Related Documentation
Made by
Kong Inc.
Incompatible with
on-prem
Minimum Version
AI Gateway - 2.0
Tags

This AI Policy allows you to append request and response data in JSON format to a log file. You can also specify streams (for example, /dev/stdout and /dev/stderr), which is especially useful when running Kong Gateway in Kubernetes.

The File Log AI Policy uses blocking I/O, which could affect performance when writing to physical files on slow (spinning) disks.

Important: Log interleaving can occur when logging to stdout. This happens because data written through a pipe must fit within the pipe buffer, which is typically 4k as defined by the Linux kernel. If the data exceeds this size, the kernel can’t guarantee the atomicity of the write() system call, leading to interleaved logs.

Log format

Every request is logged separately in a JSON object, separated by a new line \n.

Expand this block to see a sample log object
{
    "response": {
        "size": 9982,
        "headers": {
            "access-control-allow-origin": "*",
            "content-length": "9593",
            "date": "Thu, 19 Sep 2024 22:10:39 GMT",
            "content-type": "text/html; charset=utf-8",
            "via": "1.1 kong/3.8.0.0-enterprise-edition",
            "connection": "close",
            "server": "gunicorn/19.9.0",
            "access-control-allow-credentials": "true",
            "x-kong-upstream-latency": "171",
            "x-kong-proxy-latency": "1",
            "x-kong-request-id": "2f6946328ffc4946b8c9120704a4a155"
        },
        "status": 200
    },
    "route": {
        "updated_at": 1726782477,
        "tags": [],
        "response_buffering": true,
        "path_handling": "v0",
        "protocols": [
            "http",
            "https"
        ],
        "service": {
            "id": "fb4eecf8-dec2-40ef-b779-16de7e2384c7"
        },
        "https_redirect_status_code": 426,
        "regex_priority": 0,
        "name": "example_route",
        "id": "0f1a4101-3327-4274-b1e4-484a4ab0c030",
        "strip_path": true,
        "preserve_host": false,
        "created_at": 1726782477,
        "request_buffering": true,
        "ws_id": "f381e34e-5c25-4e65-b91b-3c0a86cfc393",
        "paths": [
            "/example-route"
        ]
    },
    "workspace": "f381e34e-5c25-4e65-b91b-3c0a86cfc393",
    "workspace_name": "default",
    "tries": [
        {
            "balancer_start": 1726783839539,
            "balancer_start_ns": 1.7267838395395e+18,
            "ip": "34.237.204.224",
            "balancer_latency": 0,
            "port": 80,
            "balancer_latency_ns": 27904
        }
    ],
    "client_ip": "192.168.65.1",
    "request": {
        "id": "2f6946328ffc4946b8c9120704a4a155",
        "headers": {
            "accept": "*/*",
            "user-agent": "HTTPie/3.2.3",
            "host": "localhost:8000",
            "connection": "keep-alive",
            "accept-encoding": "gzip, deflate"
        },
        "uri": "/example-route",
        "size": 139,
        "method": "GET",
        "querystring": {},
        "url": "http://localhost:8000/example-route"
    },
    "upstream_uri": "/",
    "started_at": 1726783839538,
    "source": "upstream",
    "upstream_status": "200",
    "latencies": {
        "kong": 1,
        "proxy": 171,
        "request": 173,
        "receive": 1
    },
    "service": {
        "write_timeout": 60000,
        "read_timeout": 60000,
        "updated_at": 1726782459,
        "host": "httpbin.konghq.com",
        "name": "example_service",
        "id": "fb4eecf8-dec2-40ef-b779-16de7e2384c7",
        "port": 80,
        "enabled": true,
        "created_at": 1726782459,
        "protocol": "http",
        "ws_id": "f381e34e-5c25-4e65-b91b-3c0a86cfc393",
        "connect_timeout": 60000,
        "retries": 5
    }
}

Log format definitions

The following table describes each object in the log:

Log item

Description

service Properties of the internal AI Gateway Service associated with the requested Route.
route Properties of the specific Route requested.
request Properties of the request sent by the client.
request.tls.version TLS/SSL version used by the connection.
request.tls.cipher TLS/SSL cipher used by the connection.
request.tls.client_verify mTLS validation result. Contents are the same as described in $ssl_client_verify.
response Properties of the response sent to the client.
latencies Latency data.
latencies.kong The internal AI Gateway latency, in milliseconds, that it takes to process the request.
  • For requests that are proxied to an upstream service, it is equivalent to the X-Kong-Proxy-Latency response header. It describes the time, in milliseconds, that has elapsed before transmitting the request to upstream. If there are retries to the upstream, it includes the time taken by all but the last retry. The latency of each retry is recorded by balancer_latency or balancer_latency_ns.
  • For requests that generate a response within AI Gateway (typically the result of an error or a policy-generated response), it is equivalent to the X-Kong-Response-Latency response header.
latencies.request The time, in milliseconds, that has elapsed between when the first bytes were read from the client and the last byte was sent to the client. This is useful for detecting slow clients.
latencies.proxy The time, in milliseconds, that it took for the upstream service to process the request. In other words, it’s the time elapsed between transferring the request to the final Service and when AI Gateway starts receiving the response.
latencies.receive The time, in milliseconds, that it took to receive and process the response (headers and body) from the upstream service.
tries A list of iterations made by the load balancer for this request.
tries.balancer_start A Unix timestamp for when the balancer started.
tries.ip The IP address of the contacted balancer.
tries.port The port number of the contacted balancer.
tries.balancer_latency The latency of the balancer expressed in milliseconds.
client_ip The original client IP address.
upstream_uri The URI, including query parameters, for the configured upstream service.
authenticated_entity Properties of the authenticated credential. Only present if authentication is enabled.
consumer The authenticated Consumer. Only present if authentication is enabled.
started_at The Unix timestamp of when the request has started to be processed.
source Indicates whether the response is generated by kong or upstream.
upstream_status The status code received from the upstream service in the response.

Kong process errors

This logging AI Policy logs HTTP request and response data, and also supports stream data (TCP, TLS, and UDP).

The AI Gateway process error file is the Nginx error file. You can find it at the following path:

$PREFIX/logs/error.log

Configure the prefix in kong.conf.

Custom fields by Lua

The config.custom_fields_by_lua configuration lets you dynamically modify log fields using Lua code. The following example configuration removes the route field from the logs:

New fields can be added the same way:

Dot characters (.) in the field key create nested fields. Use a backslash \ to escape a dot if you want to keep it as part of a flat field name instead of nesting it. For example, [my_entry.log\.field] produces a my_entry object with a single log.field key, instead of nesting into log and field.

Targeting AI Gateway fields

AI Gateway logs the outcome of an LLM request under a nested ai object, for example ai.$POLICY_NAME.meta, ai.$POLICY_NAME.usage, and, when payload logging is enabled, ai.$POLICY_NAME.payload.request and ai.$POLICY_NAME.payload.response. Because custom_fields_by_lua keys are split into nested table accesses the same way, you can use the same unescaped, dotted-key syntax to remove or override those fields.

For example, to stop logging LLM request and response payloads:

Note: Escaping the dots (for example, ai\.file-log\.payload\.request) targets a literal flat key instead of the nested ai.file-log.payload.request field, so it won’t match. Use unescaped dots to target AI Gateway fields.

Because File Log applies custom_fields_by_lua in its own log phase, which runs after AI Gateway sets the ai.* fields on the request, it can override or remove any ai.* field. The reverse isn’t possible, since AI Gateway can’t run after a logging Policy’s log phase to override a field the Policy already set.

Policy precedence and managing fields

All logging Policies use the same table for logging. If you set config.custom_fields_by_lua in one Policy, all logging Policies that run after it also use that configuration. For example, if you configure fields in the File Log Policy, those same fields appear in the Syslog Policy too, since File Log executes first.

  • If you want all logging Policies to use the same configuration, use the Pre-function Policy to call kong.log.set_serialize_value so the function is applied predictably and is easier to manage.
  • If you don’t want all logging Policies to share the same configuration, disable the relevant field in each Policy explicitly. For example, if you configure a field in the File Log Policy that you don’t want appearing in the Syslog Policy, set that field to return nil in the File Log Policy’s custom_fields_by_lua configuration.

Limitations

Lua code runs in a restricted sandbox environment, whose behavior is governed by the untrusted_lua configuration.

As this code runs in the log phase, only PDK methods that can run in that phase can be used.

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!