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:
curl -X POST https://{region}.api.konghq.com/v1/ai-gateways/{AIGatewayId}/policies \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $KONNECT_TOKEN" \
--data '
{
"display_name": "File Log - Remove Field",
"name": "file-log",
"type": "file-log",
"config": {
"path": "/tmp/file.log",
"custom_fields_by_lua": {
"route": "return nil"
}
}
}
'
ai_gateway_policies:
- ref: file-log
ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
display_name: File Log - Remove Field
name: file-log
type: file-log
config:
path: "/tmp/file.log"
custom_fields_by_lua:
route: return nil
Make sure to replace the following placeholders with your own values:
-
AI_GATEWAY_ID: The id of your AI Gateway.
New fields can be added the same way:
curl -X POST https://{region}.api.konghq.com/v1/ai-gateways/{AIGatewayId}/policies \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $KONNECT_TOKEN" \
--data '
{
"display_name": "File Log - Add Field",
"name": "file-log",
"type": "file-log",
"config": {
"path": "/tmp/file.log",
"custom_fields_by_lua": {
"header": "return kong.request.get_header('h1')"
}
}
}
'
ai_gateway_policies:
- ref: file-log
ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
display_name: File Log - Add Field
name: file-log
type: file-log
config:
path: "/tmp/file.log"
custom_fields_by_lua:
header: return kong.request.get_header('h1')
Make sure to replace the following placeholders with your own values:
-
AI_GATEWAY_ID: The id of your AI Gateway.
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.
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:
curl -X POST https://{region}.api.konghq.com/v1/ai-gateways/{AIGatewayId}/policies \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $KONNECT_TOKEN" \
--data '
{
"display_name": "File Log - Disable Payload Logging",
"name": "file-log",
"type": "file-log",
"config": {
"path": "/tmp/file.log",
"custom_fields_by_lua": {
"ai.file-log.payload.request": "return nil"
}
}
}
'
ai_gateway_policies:
- ref: file-log
ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
display_name: File Log - Disable Payload Logging
name: file-log
type: file-log
config:
path: "/tmp/file.log"
custom_fields_by_lua:
ai.file-log.payload.request: return nil
Make sure to replace the following placeholders with your own values:
-
AI_GATEWAY_ID: The id of your AI Gateway.
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.
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.
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.