Access Logs
This example builds on the previous HTTP Example and configures Envoy access logs for Gateways managed by Cilium Gateway API.
Access logging is managed via the spec.telemetry.accessLogs field within a
CiliumGatewayClassConfig resource. Since this configuration is referenced by
GatewayClass resource via spec.parametersRef, any settings you define here will automatically
apply to all Gateways using that specific Gateway Class.
Cilium configures Envoy to write access logs to stdout.
Configuration Options
When configuring access logs, the format field is required. You can
customize the log output using the following parameters:
format(Required): Defines the log output type. Supported values areTextorJSON.text(Optional): A custom Envoy text format string. If you selectformat: Textbut leave this field empty, Cilium falls back to the default Envoy text format.json(Optional): A key-value map linking your custom JSON field names to Envoy format operators. If you selectformat: JSONbut leave this field empty, Cilium applies a pre-configured JSON template that mirrors the information from the default Envoy text format.Note
This default JSON mapping is provided by Cilium, not by Envoy’s built-in defaults.
targets(Optional): Specifies the traffic type to log. Supported values areHTTPandTCP(which includes TLS passthrough). If omitted, Cilium defaults to loggingHTTPtraffic only.
Custom Cilium formatters
In addition to standard Envoy operators, Cilium provides two Gateway-specific formatters to help you identify the source of the traffic:
%CILIUM_GATEWAY_NAMESPACE%resolves to the namespace of the Gateway.%CILIUM_GATEWAY_NAME%resolves to the name of the Gateway.
For a complete list of all other available format operators, please refer to the official Envoy access log substitution formatter documentation.
Deploy a Gateway with access logs
Create a CiliumGatewayClassConfig that enables JSON access logs for HTTP
traffic:
apiVersion: cilium.io/v2alpha1
kind: CiliumGatewayClassConfig
metadata:
name: cilium
namespace: default
spec:
telemetry:
accessLogs:
- format: JSON
json:
gateway: "%CILIUM_GATEWAY_NAMESPACE%/%CILIUM_GATEWAY_NAME%"
start_time: "%START_TIME%"
method: "%REQUEST_HEADER(:METHOD)%"
path: "%REQUEST_HEADER(X-ENVOY-ORIGINAL-PATH?:PATH)%"
protocol: "%PROTOCOL%"
response_code: "%RESPONSE_CODE%"
response_flags: "%RESPONSE_FLAGS%"
bytes_received: "%BYTES_RECEIVED%"
bytes_sent: "%BYTES_SENT%"
duration: "%DURATION%"
authority: "%REQUEST_HEADER(:AUTHORITY)%"
upstream_host: "%UPSTREAM_HOST%"
Update the GatewayClass to reference the CiliumGatewayClassConfig resource:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: cilium
spec:
controllerName: io.cilium/gateway-controller
parametersRef:
group: cilium.io
kind: CiliumGatewayClassConfig
name: cilium
namespace: default
Verify that the GatewayClass configuration is accepted:
$ kubectl get ciliumgatewayclassconfig cilium
NAME ACCEPTED AGE
cilium True 33s
Send a request through the Gateway:
$ GATEWAY=$(kubectl get gateway my-gateway -o jsonpath='{.status.addresses[0].value}')
$ curl --fail -s http://"$GATEWAY"/details/1 | jq
Verify access logs
Check the Envoy stdout logs for an access log entry that contains the Gateway namespace and name.
$ kubectl -n kube-system logs -l app.kubernetes.io/name=cilium-envoy,app.kubernetes.io/part-of=cilium | grep default/my-gateway
{"authority":"172.18.255.193","bytes_received":0,"bytes_sent":178,"duration":8,"gateway":"default/my-gateway","method":"GET","path":"/details/1","protocol":"HTTP/1.1","response_code":200,"response_flags":"-","start_time":"2026-07-06T10:10:13.622Z","upstream_host":"10.244.0.221:9080"}
Log HTTP and TCP traffic
To emit access logs for both HTTP and TCP proxy traffic, set both targets:
spec:
telemetry:
accessLogs:
- format: Text
text: '[%START_TIME%] %CILIUM_GATEWAY_NAMESPACE%/%CILIUM_GATEWAY_NAME% "%REQUEST_HEADER(:METHOD)% %REQUEST_HEADER(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %DURATION%'
targets:
- HTTP
- TCP
Multiple access log entries may use the same target. Envoy emits one log entry for each matching configuration, so duplicate configurations will produce duplicate log lines.