Ana içeriğe geç

Table Creation Commands for Apinizer Logs

Info

The DDL commands on this page use Apinizer's default table names (log_ApiProxyTraffic, log_PolicyCapture, log_AuditEvent, log_Application, log_UnsentMessage, log_TokenTraffic, log_LoginLog) and a schemaless definition.

If you prefer a custom schema or a custom table name, you can configure this under the Usage as Log Target — Table Schema section of the connection definition. You may change the table name in the DDL or add a schema prefix; however, the column names and data types must remain exactly the same — otherwise log records will fail during INSERT with a "column not found" error.

In particular, if you use case-sensitive table names in Oracle (e.g. CREATE TABLE "HR"."logtablosu"), you must enter the table name in double quotes in the connection definition.

See the Database Connection page for details.

Apinizer can store traffic and audit records in relational databases via the DB Connector. The tables below are prepared with the appropriate data types for each supported database type.

Info

Column names are identical across all database types (snake_case). Only the data types differ per database.

API Proxy Traffic Log

This is the main table where all HTTP traffic passing through the API Proxy is recorded.

Info

The CREATE TABLE command below is intended for new installations and already includes all columns — AI Gateway, MCP Gateway, A2A Gateway, routing diagnostics, outbound MCP/A2A call auditing, and policy execution time columns. You do not need to run an additional ALTER.

If you are upgrading an existing installation, do not run this command; your table already exists. Run the ALTER TABLE script of every version you pass through, in order:

CREATE TABLE log_ApiProxyTraffic (
id VARCHAR2(255) PRIMARY KEY,
log_timestamp TIMESTAMP,
correlation_id VARCHAR2(255),
environment_id VARCHAR2(255),
project_id VARCHAR2(255),
application_id VARCHAR2(255),
application_name VARCHAR2(255),
api_proxy_id VARCHAR2(255),
api_proxy_name VARCHAR2(255),
enum_api_type VARCHAR2(255),
proxy_relative_path VARCHAR2(255),
proxy_method_id VARCHAR2(255),
proxy_method_name VARCHAR2(255),
x_forwarded_for VARCHAR2(255),
username_or_key VARCHAR2(255),
req_context_path VARCHAR2(255),
req_remote_addr VARCHAR2(255),
req_http_method VARCHAR2(255),
req_content_type VARCHAR2(255),
req_path_info VARCHAR2(255),
req_query_string VARCHAR2(255),
req_remote_user VARCHAR2(255),
req_session_id VARCHAR2(255),
req_request_uri VARCHAR2(255),
req_char_encoding VARCHAR2(255),
req_content_length NUMBER(10),
req_protocol VARCHAR2(255),
req_scheme VARCHAR2(255),
req_server_name VARCHAR2(255),
req_server_port NUMBER(10),
req_remote_host VARCHAR2(255),
req_remote_port NUMBER(10),
req_local_name VARCHAR2(255),
req_local_addr VARCHAR2(255),
req_local_port NUMBER(10),
from_client_ro_param CLOB,
from_client_ro_header CLOB,
from_client_ro_body CLOB,
to_backend_param CLOB,
to_backend_header CLOB,
to_backend_body CLOB,
routing_address VARCHAR2(255),
routing_retry_count NUMBER(10),
routing_failover_cnt NUMBER(10),
from_backend_ro_header CLOB,
from_backend_ro_body CLOB,
to_client_header CLOB,
to_client_body CLOB,
time_req_pipeline NUMBER(10),
time_resp_pipeline NUMBER(10),
time_routing_total NUMBER(10),
time_api_proxy_total NUMBER(10),
size_request_total NUMBER(10),
size_response_total NUMBER(10),
cache_hit NUMBER(1),
status_code NUMBER(10),
error_type VARCHAR2(255),
parent_error_type VARCHAR2(255),
result_type VARCHAR2(255),
location_lat NUMBER,
location_lon NUMBER,
is_canary_request NUMBER(1),
canary_routing_status VARCHAR2(255),
mirror_count NUMBER(10),
mirror_success_count NUMBER(10),
mirror_failure_count NUMBER(10),
mirror_total_duration NUMBER(19),
mirror_addresses CLOB,
ai_provider VARCHAR2(64),
ai_model VARCHAR2(128),
ai_token_input NUMBER(19),
ai_token_output NUMBER(19),
ai_token_cached NUMBER(19),
ai_cost_micro NUMBER(19),
ai_first_token_ms NUMBER(19),
ai_tpot_ms NUMBER(19),
ai_total_latency_ms NUMBER(19),
ai_semantic_cache_hit NUMBER(1),
ai_guardrail_hit VARCHAR2(64),
ai_pii_detected NUMBER(1),
ai_finish_reason VARCHAR2(64),
ai_streaming NUMBER(1),
ai_tenant_credential_id VARCHAR2(64),
ai_trace_id VARCHAR2(64),
ai_failover_from VARCHAR2(64),
ai_cost_input_micro NUMBER(19),
ai_cost_output_micro NUMBER(19),
ai_cost_cached_micro NUMBER(19),
mcp_tool_name VARCHAR2(128),
mcp_jsonrpc_id VARCHAR2(64),
ai_deployment_type VARCHAR2(32),
ai_guardrail_total_ms NUMBER(19),
ai_inference_ms NUMBER(19),
ai_overhead_ms NUMBER(19),
routing_failure_reason VARCHAR2(64),
routing_confidence VARCHAR2(16),
routing_exception_class VARCHAR2(255),
routing_exception_detail VARCHAR2(256),
rd_selection_ns NUMBER(19),
rd_dns_ns NUMBER(19),
rd_tcp_connect_ns NUMBER(19),
rd_tls_handshake_ns NUMBER(19),
rd_ttfb_ns NUMBER(19),
rd_body_read_ns NUMBER(19),
rd_pool_wait_ns NUMBER(19),
upstream_status_code NUMBER(5),
upstream_ip_port VARCHAR2(64),
connection_reused NUMBER(1),
ttfb_reached NUMBER(1),
gateway_worker VARCHAR2(128),
pool_leased NUMBER(5),
pool_pending NUMBER(5),
pool_available NUMBER(5),
pool_max NUMBER(5),
cfg_connect_timeout NUMBER(10),
cfg_read_timeout NUMBER(10),
cfg_conn_req_timeout NUMBER(10),
client_write_ms NUMBER(10),
a2a_task_id VARCHAR2(64),
a2a_context_id VARCHAR2(128),
a2a_task_state VARCHAR2(32),
ai_quota_soft_cap_hit NUMBER(10),
ai_quota_alert_hit NUMBER(1),
ai_guardrail_category VARCHAR2(64),
ai_guardrail_verdict VARCHAR2(32),
mcp_tool_names_out VARCHAR2(256),
mcp_tool_call_count_out NUMBER(10),
a2a_skill_names_out VARCHAR2(256),
a2a_agent_call_count_out NUMBER(10),
policy_exec_times VARCHAR2(4000),
api_client_key VARCHAR2(255),
client_owner_type VARCHAR2(16),
client_owner_id VARCHAR2(64),
client_organization_id VARCHAR2(64)
);
SQL Server: row size warning

When creating this table, SQL Server issues the following warning: "the table has been created, but its maximum row size exceeds the allowed maximum of 8060 bytes". This is expected and is not an error.

The total declared width of the variable-length NVARCHAR columns in the table exceeds the 8060-byte in-row limit per row; since SQL Server 2005 these columns are automatically moved to ROW_OVERFLOW_DATA pages when needed, leaving a 24-byte pointer in the row. Because the total of the fixed-length columns (~287 bytes) is well below the limit, INSERT operations do not fail. The only effect is the additional page read/write cost on rows where many long text fields are populated at the same time.

Narrowing the column widths enough to silence this warning (all text columns to 64 characters) was not preferred, as it would cause data loss in fields such as req_request_uri, req_query_string and application_name.

ColumnDescription
idRecord identifier
log_timestampTime the log record was created
correlation_idRequest-specific correlation identifier; links records belonging to the same request chain
environment_idIdentifier of the environment in which the request was processed
project_idIdentifier of the project the API belongs to
application_idIdentifier of the application making the request
application_nameName of the application making the request
api_proxy_idIdentifier of the API Proxy used for the request
api_proxy_nameName of the API Proxy used for the request
enum_api_typeAPI type (REST, SOAP, etc.)
proxy_relative_pathAPI Proxy relative path
proxy_method_idIdentifier of the matched method
proxy_method_nameName of the matched method
x_forwarded_forThe client's real IP address (proxy/load balancer chain)
username_or_keyUsername or API key used in authentication
req_context_pathRequest context path
req_remote_addrRemote address
req_http_methodHTTP method (GET, POST, PUT, etc.)
req_content_typeContent type of the request
req_path_infoRequest path info
req_query_stringRequest query string
req_remote_userRemote user
req_session_idSession identifier
req_request_uriRequest URI
req_char_encodingRequest character encoding
req_content_lengthRequest content length (bytes)
req_protocolProtocol
req_schemeScheme (http/https)
req_server_nameServer name
req_server_portServer port
req_remote_hostRemote host
req_remote_portRemote port
req_local_nameLocal name
req_local_addrLocal address
req_local_portLocal port
from_client_ro_paramQuery parameters received from the client (JSON)
from_client_ro_headerHeaders received from the client (JSON)
from_client_ro_bodyRequest body received from the client
to_backend_paramQuery parameters sent to the backend (JSON)
to_backend_headerHeaders sent to the backend (JSON)
to_backend_bodyRequest body sent to the backend
routing_addressBackend address the request was routed to
routing_retry_countNumber of retries
routing_failover_cntNumber of failovers
from_backend_ro_headerResponse headers received from the backend (JSON)
from_backend_ro_bodyResponse body received from the backend
to_client_headerResponse headers sent to the client (JSON)
to_client_bodyResponse body sent to the client
time_req_pipelineRequest pipeline duration (ms)
time_resp_pipelineResponse pipeline duration (ms)
time_routing_totalTotal routing duration (ms)
time_api_proxy_totalTotal API Proxy processing time (ms)
size_request_totalRequest size (bytes)
size_response_totalResponse size (bytes)
cache_hitWhether the response was served from cache
status_codeHTTP response code
error_typeError type
parent_error_typeParent error type
result_typeOperation result
location_latGeographic location — latitude
location_lonGeographic location — longitude
is_canary_requestWhether this is a canary routing request
canary_routing_statusCanary routing status
mirror_countNumber of mirrors
mirror_success_countNumber of successful mirrors
mirror_failure_countNumber of failed mirrors
mirror_total_durationTotal mirroring duration (ms)
mirror_addressesMirror addresses (JSON)
mcp_tool_names_outDistinct MCP tool names called in outbound requests (CSV, limited to 256 characters)
mcp_tool_call_count_outTotal number of outbound MCP tool calls (raw, unlimited)
a2a_skill_names_outDistinct A2A skill/agent names called in outbound requests (CSV, limited to 256 characters)
a2a_agent_call_count_outTotal number of outbound A2A agent calls (raw, unlimited)
policy_exec_timesPolicy execution times — order:type:duration CSV; written only when the setting is enabled on the log target
api_client_keyAPI Client key that authenticated the request (empty when the identity was authenticated without an API Client)
client_owner_typeKind of subject the API Client belongs to — CONSUMER or APPLICATION
client_owner_idId of the owning Consumer (Credential) or Portal Application
client_organization_idOrganization id of the authenticated identity

This is the highest-volume log table. The indexes below cover the most frequently used query patterns (end-to-end tracing, time range scans, proxy/project-based filtering, error analysis).

CREATE INDEX idx_apitraffic_correlation ON log_ApiProxyTraffic(correlation_id);
CREATE INDEX idx_apitraffic_timestamp ON log_ApiProxyTraffic(log_timestamp);
CREATE INDEX idx_apitraffic_proxy ON log_ApiProxyTraffic(api_proxy_id);
CREATE INDEX idx_apitraffic_project ON log_ApiProxyTraffic(project_id);
CREATE INDEX idx_apitraffic_status ON log_ApiProxyTraffic(status_code);
CREATE INDEX idx_apitraffic_result ON log_ApiProxyTraffic(result_type);

Partitioning

This table grows very quickly under live traffic. Applying daily partitioning on log_timestamp is strongly recommended. This way the retention policy can be applied with DROP PARTITION, and time range queries scan only the relevant partitions. For database-specific examples, see the Partition Syntax section.

Token Traffic Log

This is the table where OAuth/JWT token operations are recorded.

CREATE TABLE log_TokenTraffic (
id VARCHAR2(255) PRIMARY KEY,
log_timestamp TIMESTAMP,
correlation_id VARCHAR2(255),
environment_id VARCHAR2(255),
project_id VARCHAR2(255),
application_id VARCHAR2(255),
application_name VARCHAR2(255),
api_proxy_id VARCHAR2(255),
api_proxy_name VARCHAR2(255),
x_forwarded_for VARCHAR2(255),
req_remote_addr VARCHAR2(255),
req_http_method VARCHAR2(255),
req_content_type VARCHAR2(255),
username_or_key VARCHAR2(255),
time_total NUMBER(10),
status_code NUMBER(10),
error_type VARCHAR2(255),
parent_error_type VARCHAR2(255),
result_type VARCHAR2(255),
to_client_header CLOB,
to_client_body CLOB,
auth_token_type VARCHAR2(255),
audience VARCHAR2(255),
client_info VARCHAR2(255),
token_never_expires NUMBER(1),
issued_at TIMESTAMP,
expires_at TIMESTAMP,
expires_in NUMBER(10),
scope VARCHAR2(255),
refresh_token_allowed NUMBER(1),
refresh_token_issued_at TIMESTAMP,
refresh_token_expires_at TIMESTAMP,
refresh_token_expires_in NUMBER(10),
refresh_count NUMBER(10),
max_refresh_count NUMBER(10),
api_client_key VARCHAR2(255),
client_organization_id VARCHAR2(64)
);
ColumnDescription
idRecord identifier
log_timestampTime the log record was created
correlation_idCorrelation identifier
environment_idEnvironment identifier
project_idProject identifier
application_idApplication identifier
application_nameApplication name
api_proxy_idAPI Proxy identifier
api_proxy_nameAPI Proxy name
x_forwarded_forThe client's real IP address
req_remote_addrRemote address
req_http_methodHTTP method
req_content_typeContent type of the request
username_or_keyUsername or API key
time_totalTotal processing time (ms)
status_codeHTTP response code
error_typeError type
parent_error_typeParent error type
result_typeOperation result
to_client_headerHeaders sent to the client (JSON)
to_client_bodyResponse body sent to the client
auth_token_typeToken type (Bearer, Basic, etc.)
audienceIntended audience of the token
client_infoClient information
token_never_expiresWhether the token ever expires
issued_atTime the token was issued
expires_atToken expiry time
expires_inToken validity period (seconds)
scopeScope information of the token
refresh_token_allowedWhether a refresh token is allowed
refresh_token_issued_atTime the refresh token was issued
refresh_token_expires_atRefresh token expiry time
refresh_token_expires_inRefresh token validity period (seconds)
refresh_countNumber of refreshes
max_refresh_countMaximum number of refreshes allowed
api_client_keyAPI Client key the token was issued to
client_organization_idOrganization id of the identity the token was issued to

Token operations are frequently examined by user/application and time range. When tracing an end-to-end call, joining with the API traffic table on correlation_id is also common.

CREATE INDEX idx_tokentraffic_correlation ON log_TokenTraffic(correlation_id);
CREATE INDEX idx_tokentraffic_timestamp ON log_TokenTraffic(log_timestamp);
CREATE INDEX idx_tokentraffic_proxy ON log_TokenTraffic(api_proxy_id);
CREATE INDEX idx_tokentraffic_user ON log_TokenTraffic(username_or_key);
CREATE INDEX idx_tokentraffic_result ON log_TokenTraffic(result_type);

Partitioning

Token volume generally grows in proportion to API traffic volume. Daily partitioning on log_timestamp is recommended. See Partition Syntax.

Log Policy

This is the table that stores the message snapshot captured each time the Log Policy is triggered.

CREATE TABLE log_PolicyCapture (
id VARCHAR2(255) PRIMARY KEY,
log_timestamp TIMESTAMP,
correlation_id VARCHAR2(255),
environment_id VARCHAR2(255),
api_proxy_id VARCHAR2(255),
api_proxy_name VARCHAR2(255),
proxy_method_id VARCHAR2(255),
proxy_method_name VARCHAR2(255),
username_or_key VARCHAR2(255),
status_code NUMBER(10),
result_type VARCHAR2(255),
error_type VARCHAR2(255),
from_client_ro_header CLOB,
from_client_ro_param CLOB,
from_client_ro_body CLOB,
capture_region VARCHAR2(50),
capture_location VARCHAR2(50)
);
ColumnDescription
idRecord identifier
log_timestampTime the log record was created
correlation_idCorrelation identifier
environment_idEnvironment identifier
api_proxy_idAPI Proxy identifier
api_proxy_nameAPI Proxy name
proxy_method_idMethod identifier
proxy_method_nameMethod name
username_or_keyUsername or API key
status_codeHTTP response code
result_typeOperation result
error_typeError type
from_client_ro_headerHeaders received from the client (JSON)
from_client_ro_paramQuery parameters received from the client (JSON)
from_client_ro_bodyRequest body received from the client
capture_regionPipeline stage in which the policy ran: FROM_CLIENT, TO_BACKEND, FROM_BACKEND, TO_CLIENT
capture_locationLevel at which the policy is defined: API_PROXY_GROUP (Group), API_PROXY (Proxy), API_PROXY_METHOD (Method)

When the logging policy is placed at more than one point in the pipeline (for example FROM_CLIENT and TO_CLIENT), the request and response records share the same correlation_id. For this reason the correlation_id index is critical for joining request and response end to end.

CREATE INDEX idx_policycapture_correlation ON log_PolicyCapture(correlation_id);
CREATE INDEX idx_policycapture_timestamp ON log_PolicyCapture(log_timestamp);
CREATE INDEX idx_policycapture_proxy ON log_PolicyCapture(api_proxy_id);
CREATE INDEX idx_policycapture_region ON log_PolicyCapture(capture_region);

Partitioning

Volume depends on the number of logging policies attached to the flows and how often they are triggered. For policies attached at proxy/method level on high-traffic APIs, daily partitioning on log_timestamp is recommended. See Partition Syntax.

Elasticsearch Integration

If you use an Elasticsearch connector, a separate index template must be created for log policy data. This template differs from the standard API traffic log template and contains only the fields sent by the log policy.

Warning

The Elasticsearch index template and ILM policy for log policy data are not automatically created from the Apinizer UI. You need to manually apply the following steps on Elasticsearch.

Step 1: Create ILM Policy

Create an ILM policy for index lifecycle management. The following example creates a policy that rolls over at 30 GB or 1 day and deletes after 30 days. Adjust the values according to your needs.

PUT _ilm/policy/apinizer-log-policy-capture-ilm
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "30gb",
"max_age": "1d"
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}

Step 2: Create Index Template

Run the following command using Elasticsearch Kibana Dev Tools or curl. The template includes data stream support.

Warning

The field types in the template must exactly match the JSON structure sent by the log policy. Do not change field types.

PUT _index_template/apinizer-log-policy-capture-template
{
"index_patterns": ["apinizer-log-policy-capture*"],
"data_stream": {},
"template": {
"settings": {
"index": {
"lifecycle": {
"name": "apinizer-log-policy-capture-ilm"
},
"number_of_shards": 1,
"number_of_replicas": 0,
"refresh_interval": "5s"
}
},
"mappings": {
"properties": {
"@timestamp": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ss.S'Z'||yyyy-MM-dd'T'HH:mm:ss.SS'Z'||yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
},
"aci": {
"type": "keyword"
},
"ei": {
"type": "keyword"
},
"api": {
"type": "keyword"
},
"apn": {
"type": "keyword"
},
"apmi": {
"type": "keyword"
},
"apmn": {
"type": "keyword"
},
"uok": {
"type": "keyword",
"ignore_above": 50
},
"sc": {
"type": "short"
},
"rt": {
"type": "keyword",
"ignore_above": 7
},
"et": {
"type": "keyword",
"ignore_above": 75
},
"fcrh": {
"type": "nested",
"properties": {
"k": {
"type": "keyword"
},
"v": {
"type": "keyword"
}
}
},
"fcrp": {
"type": "nested",
"properties": {
"k": {
"type": "keyword"
},
"v": {
"type": "keyword"
}
}
},
"fcrb": {
"type": "text"
},
"cr": {
"type": "keyword"
},
"cl": {
"type": "keyword"
}
}
}
}
}

Step 3: Create Data Stream

After the template is created, the data stream is created automatically when the first data arrives. To create it manually:

PUT _data_stream/apinizer-log-policy-capture

Enter apinizer-log-policy-capture in the Elasticsearch connector's Index Name field. This name must match the index_patterns in the template. If you want to use a different index name, update the index_patterns field in the template accordingly.

Application Log

This is the table that stores Apinizer platform-level application logs.

CREATE TABLE log_Application (
id VARCHAR2(255) PRIMARY KEY,
env_name VARCHAR2(255),
api_proxy_id VARCHAR2(255),
api_proxy_name VARCHAR2(255),
correlation_id VARCHAR2(255),
log_timestamp TIMESTAMP,
log_level VARCHAR2(255),
message CLOB,
stack_trace CLOB,
host_name VARCHAR2(255),
enum_application_log VARCHAR2(255),
total_duration NUMBER(10)
);
ColumnDescription
idRecord identifier
env_nameEnvironment name
api_proxy_idAPI Proxy identifier
api_proxy_nameAPI Proxy name
correlation_idCorrelation identifier
log_timestampTime the log record was created
log_levelLog level (INFO, WARN, ERROR, etc.)
messageLog message
stack_traceError stack trace
host_nameName of the server where the log originated
enum_application_logApplication log source type
total_durationTotal processing time (ms)

Application logs are mostly filtered by time range and log level (for troubleshooting); they are also joined with traffic logs on correlation_id to reconstruct the platform-level events of a single request.

CREATE INDEX idx_application_correlation ON log_Application(correlation_id);
CREATE INDEX idx_application_timestamp ON log_Application(log_timestamp);
CREATE INDEX idx_application_level ON log_Application(log_level);
CREATE INDEX idx_application_proxy ON log_Application(api_proxy_id);

Partitioning

Application logs accumulate steadily. On live systems, daily partitioning on log_timestamp is recommended. See Partition Syntax.

Audit Event

This is the table that stores the audit trail of user operations.

Info

The CREATE TABLE command below is intended for new installations and already includes the request-context columns (event type, outcome, client IP, user agent, correlation id, source).

If you are upgrading an existing installation, do not run this command; your table already exists. Run the 2026.09.2 — Audit and Login Table ALTER Scripts script once — unlike the traffic-log ALTER scripts above, this one is not optional to defer: the insert statement is unconditional, so until the script is run, every Audit Event row bound for this table fails to write.

CREATE TABLE log_AuditEvent (
id VARCHAR2(255) PRIMARY KEY,
audit_event_date TIMESTAMP,
principal VARCHAR2(255),
state VARCHAR2(255),
object_id VARCHAR2(255),
object_name VARCHAR2(255),
ref_object_json CLOB,
project_id VARCHAR2(255),
class_name VARCHAR2(255),
event_type VARCHAR2(32),
outcome VARCHAR2(16),
client_ip VARCHAR2(64),
user_agent VARCHAR2(512),
correlation_id VARCHAR2(255),
source VARCHAR2(32)
);
ColumnDescription
idRecord identifier
audit_event_dateTime the audit event occurred
principalUser who performed the operation
stateState of the operation (CREATE, UPDATE, DELETE, etc.)
object_idIdentifier of the object operated on
object_nameName of the object operated on
ref_object_jsonJSON representation of the object operated on
project_idProject identifier
class_nameType of the object
event_typeWhich of the Audit Records event types this row is
outcomeResult of the operation — SUCCESS, FAILURE, or DENIED
client_ipThe client's real IP address (read from X-Forwarded-For when present)
user_agentThe User-Agent header sent by the client
correlation_idTies this record to the request's other log entries
sourceThe front door the request came from — Management Console, APIops, API Portal, or System

Audit queries are most often filtered by date range, user (principal), affected object type, or project. Note that here the partition key is audit_event_date, not log_timestamp.

CREATE INDEX idx_auditevent_date ON log_AuditEvent(audit_event_date);
CREATE INDEX idx_auditevent_principal ON log_AuditEvent(principal);
CREATE INDEX idx_auditevent_project ON log_AuditEvent(project_id);
CREATE INDEX idx_auditevent_class ON log_AuditEvent(class_name);
CREATE INDEX idx_auditevent_state ON log_AuditEvent(state);
CREATE INDEX idx_auditevent_correlation ON log_AuditEvent(correlation_id);
CREATE INDEX idx_auditevent_source ON log_AuditEvent(source);

Partitioning

Audit events are produced by user operations (far fewer than traffic records) and are usually retained longer for compliance reasons. Monthly partitioning on audit_event_date is generally sufficient. In the Partition Syntax section, you can use MONTH instead of DAY.

Login Log

The table that records login attempts (both success and failure events) to the API Manager and API Portal.

Info

The CREATE TABLE command below is intended for new installations and already includes the request-context columns (user agent, reason, target project).

If you are upgrading an existing installation, do not run this command; your table already exists. Run the 2026.09.2 — Audit and Login Table ALTER Scripts script once — the insert statement is unconditional, so until the script is run, every Login Log row bound for this table fails to write, and — unlike Audit Event above — that row is not retried through a failover connector; it is simply lost.

CREATE TABLE log_LoginLog (
id VARCHAR2(255) PRIMARY KEY,
log_timestamp TIMESTAMP,
source VARCHAR2(50),
principal VARCHAR2(255),
email VARCHAR2(255),
display_name VARCHAR2(255),
event_type VARCHAR2(50),
remote_address VARCHAR2(255),
message CLOB,
error_type VARCHAR2(255),
portal_id VARCHAR2(255),
account_id VARCHAR2(255),
user_agent VARCHAR2(512),
reason_code VARCHAR2(64),
target_project_id VARCHAR2(255)
);
ColumnDescription
idRecord identifier
log_timestampTime the login event occurred
sourceLogin source (API_MANAGER, API_PORTAL)
principalUser principal (API Manager login)
emailUser email (API Portal login)
display_nameUser display name
event_typeEvent type (LOGIN_SUCCESS, LOGIN_FAILURE)
remote_addressClient remote IP address
messageResult message or failure reason
error_typeError class (for failed logins)
portal_idPortal identifier (for portal logins)
account_idAccount identifier (for portal logins)
user_agentThe User-Agent header sent by the client
reason_codeThe machine-readable reason behind a failure, lock, or password event
target_project_idThe project the session moved to, for a project-switch (token refresh) event

Login logs are queried by time range, user (email/principal), login source, and event type (for security auditing and locked-account investigation).

CREATE INDEX idx_loginlog_timestamp ON log_LoginLog(log_timestamp);
CREATE INDEX idx_loginlog_email ON log_LoginLog(email);
CREATE INDEX idx_loginlog_principal ON log_LoginLog(principal);
CREATE INDEX idx_loginlog_source ON log_LoginLog(source);
CREATE INDEX idx_loginlog_event ON log_LoginLog(event_type);

Partitioning

Login log volume is typically low compared to traffic logs. For the long retention periods often required for security auditing, monthly partitioning on log_timestamp is sufficient. See the Partition Syntax section for examples, and use MONTH instead of DAY for the interval.

Unsent Message

This is the table that temporarily stores log records that could not be delivered due to a connection failure.

CREATE TABLE log_UnsentMessage (
id VARCHAR2(255) PRIMARY KEY,
log_timestamp TIMESTAMP,
connector_id VARCHAR2(50),
content CLOB
);
ColumnDescription
idRecord identifier
log_timestampTime the record was created
connector_idIdentifier of the connector the data was attempted to be sent to
contentContent of the undelivered log record (JSON)

Records in this table are transient: they are inserted when a connector is unreachable and deleted once delivery succeeds. A small number of indexes is enough for retry lookups and cleanup.

CREATE INDEX idx_unsent_timestamp ON log_UnsentMessage(log_timestamp);
CREATE INDEX idx_unsent_connector ON log_UnsentMessage(connector_id);

Partitioning

This table holds transient records that are consumed within a short time window. Partitioning is not required. If the table grows unexpectedly (long outages), operational cleanup is a more appropriate solution than partitioning. Partitioning is possible and does not affect Apinizer's INSERT behavior, but for this temporary queue table operational cleanup is usually sufficient.

Partition Syntax

The examples below use daily partitioning on log_timestamp. Change the table name and the initial boundary date to suit your environment. For the log_AuditEvent table, use the audit_event_date column instead of log_timestamp, and prefer a monthly interval instead of a daily one.

-- Apply during CREATE TABLE (after the column list):
)
PARTITION BY RANGE (log_timestamp)
INTERVAL (NUMTODSINTERVAL(1, 'DAY'))
(
PARTITION p_initial VALUES LESS THAN (TIMESTAMP '2026-01-01 00:00:00')
);

-- Monthly variant (for example, for log_AuditEvent):
-- INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
Warning

In SQL Server, if the table uses a partition scheme keyed on log_timestamp or audit_event_date, you cannot define a clustered PRIMARY KEY on id (Msg 1908). The clustered index must be on the partition column; use a NONCLUSTERED PK for id. Yearly filegroups or quarterly partitions are valid operational choices and do not change Apinizer's INSERT behavior.

Warning

New daily partitions must be created in advance (for example with a scheduled job). If the target partition does not exist when a record arrives, the insert fails on SQL Server and MySQL; on Oracle it is created automatically only when INTERVAL partitioning is used.

Data Type Mapping Table

The table below shows the data type mappings across the different databases.

UsageOracleMySQL/MariaDBPostgreSQLSQL Server
Short textVARCHAR2(255)VARCHAR(255)VARCHAR(255)NVARCHAR(255)
Long textCLOBTEXT / LONGTEXTTEXTNVARCHAR(MAX)
IntegerNUMBER(10)INTINTEGERINT
Big integerNUMBER(19)BIGINTBIGINTBIGINT
Decimal numberNUMBERDOUBLEDOUBLE PRECISIONFLOAT
BooleanNUMBER(1)TINYINT(1)BOOLEANBIT
Date/TimeTIMESTAMPTIMESTAMP NULLTIMESTAMPDATETIME2