Access Logs¶
Who Calls Whom?
By default, logs are written to stdout, in text format.
Configuration¶
To enable the access logs:
accessLog: {}
[accessLog]
--accesslog=true
addInternals
¶
Optional, Default="false"
Enables access logs for internal resources (e.g.: ping@internal
).
accesslog:
addInternals: true
[accesslog]
addInternals = true
--accesslog.addinternals
filePath
¶
By default access logs are written to the standard output.
To write the logs into a log file, use the filePath
option.
accessLog:
filePath: "/path/to/access.log"
[accessLog]
filePath = "/path/to/access.log"
--accesslog.filepath=/path/to/access.log
format
¶
Optional, Default="common"
By default, logs are written using the Common Log Format (CLF).
To write logs in JSON, use json
in the format
option.
If the given format is unsupported, the default (CLF) is used instead.
Common Log Format
<remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <HTTP_status> <content-length> "<request_referrer>" "<request_user_agent>" <number_of_requests_received_since_Traefik_started> "<Traefik_router_name>" "<Traefik_server_URL>" <request_duration_in_ms>ms
accessLog:
format: "json"
[accessLog]
format = "json"
--accesslog.format=json
bufferingSize
¶
To write the logs in an asynchronous fashion, specify a bufferingSize
option.
This option represents the number of log lines Traefik will keep in memory before writing them to the selected output.
In some cases, this option can greatly help performances.
# Configuring a buffer of 100 lines
accessLog:
filePath: "/path/to/access.log"
bufferingSize: 100
# Configuring a buffer of 100 lines
[accessLog]
filePath = "/path/to/access.log"
bufferingSize = 100
# Configuring a buffer of 100 lines
--accesslog.filepath=/path/to/access.log
--accesslog.bufferingsize=100
Filtering¶
To filter logs, you can specify a set of filters which are logically "OR-connected". Thus, specifying multiple filters will keep more access logs than specifying only one.
The available filters are:
statusCodes
, to limit the access logs to requests with a status codes in the specified rangeretryAttempts
, to keep the access logs when at least one retry has happenedminDuration
, to keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format, see time.ParseDuration)
# Configuring Multiple Filters
accessLog:
filePath: "/path/to/access.log"
format: json
filters:
statusCodes:
- "200"
- "300-302"
retryAttempts: true
minDuration: "10ms"
# Configuring Multiple Filters
[accessLog]
filePath = "/path/to/access.log"
format = "json"
[accessLog.filters]
statusCodes = ["200", "300-302"]
retryAttempts = true
minDuration = "10ms"
# Configuring Multiple Filters
--accesslog.filepath=/path/to/access.log
--accesslog.format=json
--accesslog.filters.statuscodes=200,300-302
--accesslog.filters.retryattempts
--accesslog.filters.minduration=10ms
Limiting the Fields/Including Headers¶
You can decide to limit the logged fields/headers to a given list with the fields.names
and fields.headers
options.
Each field can be set to:
keep
to keep the valuedrop
to drop the value
Header fields may also optionally be set to redact
to replace the value with "REDACTED".
The defaultMode
for fields.names
is keep
.
The defaultMode
for fields.headers
is drop
.
# Limiting the Logs to Specific Fields
accessLog:
filePath: "/path/to/access.log"
format: json
fields:
defaultMode: keep
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
User-Agent: redact
Authorization: drop
Content-Type: keep
# Limiting the Logs to Specific Fields
[accessLog]
filePath = "/path/to/access.log"
format = "json"
[accessLog.fields]
defaultMode = "keep"
[accessLog.fields.names]
"ClientUsername" = "drop"
[accessLog.fields.headers]
defaultMode = "keep"
[accessLog.fields.headers.names]
"User-Agent" = "redact"
"Authorization" = "drop"
"Content-Type" = "keep"
# Limiting the Logs to Specific Fields
--accesslog.filepath=/path/to/access.log
--accesslog.format=json
--accesslog.fields.defaultmode=keep
--accesslog.fields.names.ClientUsername=drop
--accesslog.fields.headers.defaultmode=keep
--accesslog.fields.headers.names.User-Agent=redact
--accesslog.fields.headers.names.Authorization=drop
--accesslog.fields.headers.names.Content-Type=keep
Available Fields
Field | Description |
---|---|
StartUTC |
The time at which request processing started. |
StartLocal |
The local time at which request processing started. |
Duration |
The total time taken (in nanoseconds) by processing the response, including the origin server's time but not the log writing time. |
RouterName |
The name of the Traefik router. |
ServiceName |
The name of the Traefik backend. |
ServiceURL |
The URL of the Traefik backend. |
ServiceAddr |
The IP:port of the Traefik backend (extracted from ServiceURL ) |
ClientAddr |
The remote address in its original form (usually IP:port). |
ClientHost |
The remote IP address from which the client request was received. |
ClientPort |
The remote TCP port from which the client request was received. |
ClientUsername |
The username provided in the URL, if present. |
RequestAddr |
The HTTP Host header (usually IP:port). This is treated as not a header by the Go API. |
RequestHost |
The HTTP Host server name (not including port). |
RequestPort |
The TCP port from the HTTP Host. |
RequestMethod |
The HTTP method. |
RequestPath |
The HTTP request URI, not including the scheme, host or port. |
RequestProtocol |
The version of HTTP requested. |
RequestScheme |
The HTTP scheme requested http or https . |
RequestLine |
RequestMethod + RequestPath + RequestProtocol |
RequestContentSize |
The number of bytes in the request entity (a.k.a. body) sent by the client. |
OriginDuration |
The time taken (in nanoseconds) by the origin server ('upstream') to return its response. |
OriginContentSize |
The content length specified by the origin server, or 0 if unspecified. |
OriginStatus |
The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent (0). |
OriginStatusLine |
OriginStatus + Status code explanation |
DownstreamStatus |
The HTTP status code returned to the client. |
DownstreamStatusLine |
DownstreamStatus + Status code explanation |
DownstreamContentSize |
The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. |
RequestCount |
The number of requests received since the Traefik instance started. |
GzipRatio |
The response body compression ratio achieved. |
Overhead |
The processing time overhead (in nanoseconds) caused by Traefik. |
RetryAttempts |
The amount of attempts the request was retried. |
TLSVersion |
The TLS version used by the connection (e.g. 1.2 ) (if connection is TLS). |
TLSCipher |
The TLS cipher used by the connection (e.g. TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ) (if connection is TLS) |
TLSClientSubject |
The string representation of the TLS client certificate's Subject (e.g. CN=username,O=organization ) |
TraceId |
A consistent identifier for tracking requests across services, including upstream ones managed by Traefik, shown as a 32-hex digit string |
SpanId |
A unique identifier for Traefik’s root span (EntryPoint) within a request trace, formatted as a 16-hex digit string. |
Log Rotation¶
Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal.
This allows the logs to be rotated and processed by an external program, such as logrotate
.
Warning
This does not work on Windows due to the lack of USR signals.
Time Zones¶
Traefik will timestamp each log line in UTC time by default.
It is possible to configure the Traefik to timestamp in a specific timezone by ensuring the following configuration has been made in your environment:
- Provide time zone data to
/etc/localtime
or/usr/share/zoneinfo
(based on your distribution) or set the environment variable TZ to the desired timezone - Specify the field
StartLocal
by dropping the field namedStartUTC
(available on the default Common Log Format (CLF) as well as JSON)
Example utilizing Docker Compose:
version: "3.7"
services:
traefik:
image: traefik:v3.3
environment:
- TZ=US/Alaska
command:
- --accesslog.fields.names.StartUTC=drop
- --providers.docker
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
OpenTelemetry¶
Experimental Feature
The OpenTelemetry access logs feature is currently experimental and must be explicitly enabled in the experimental section prior to use.
experimental:
otlpLogs: true
[experimental.otlpLogs]
--experimental.otlpLogs=true
To enable the OpenTelemetry Logger for access logs:
accesslog:
otlp: {}
[accesslog.otlp]
--accesslog.otlp=true
Default protocol
The OpenTelemetry Logger exporter will export access logs to the collector using HTTPS by default to https://localhost:4318/v1/logs, see the gRPC Section to use gRPC.
HTTP configuration¶
Optional
This instructs the exporter to send access logs to the OpenTelemetry Collector using HTTP.
accesslog:
otlp:
http: {}
[accesslog.otlp.http]
--accesslog.otlp.http=true
endpoint
¶
Optional, Default="https://localhost:4318/v1/logs
", Format="<scheme>://<host>:<port><path>
"
URL of the OpenTelemetry Collector to send access logs to.
Insecure mode
To disable TLS, use http://
instead of https://
in the endpoint
configuration.
accesslog:
otlp:
http:
endpoint: https://collector:4318/v1/logs
[accesslog.otlp.http]
endpoint = "https://collector:4318/v1/logs"
--accesslog.otlp.http.endpoint=https://collector:4318/v1/logs
headers
¶
Optional, Default={}
Additional headers sent with access logs by the exporter to the OpenTelemetry Collector.
accesslog:
otlp:
http:
headers:
foo: bar
baz: buz
[accesslog.otlp.http.headers]
foo = "bar"
baz = "buz"
--accesslog.otlp.http.headers.foo=bar --accesslog.otlp.http.headers.baz=buz
tls
¶
Optional
Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector.
ca
¶
Optional
ca
is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
accesslog:
otlp:
http:
tls:
ca: path/to/ca.crt
[accesslog.otlp.http.tls]
ca = "path/to/ca.crt"
--accesslog.otlp.http.tls.ca=path/to/ca.crt
cert
¶
Optional
cert
is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the key
option is required.
accesslog:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
[accesslog.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
--accesslog.otlp.http.tls.cert=path/to/foo.cert
--accesslog.otlp.http.tls.key=path/to/foo.key
key
¶
Optional
key
is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the cert
option is required.
accesslog:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
[accesslog.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
--accesslog.otlp.http.tls.cert=path/to/foo.cert
--accesslog.otlp.http.tls.key=path/to/foo.key
insecureSkipVerify
¶
Optional, Default=false
If insecureSkipVerify
is true
,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
accesslog:
otlp:
http:
tls:
insecureSkipVerify: true
[accesslog.otlp.http.tls]
insecureSkipVerify = true
--accesslog.otlp.http.tls.insecureSkipVerify=true
gRPC configuration¶
Optional
This instructs the exporter to send access logs to the OpenTelemetry Collector using gRPC.
accesslog:
otlp:
grpc: {}
[accesslog.otlp.grpc]
--accesslog.otlp.grpc=true
endpoint
¶
Required, Default="localhost:4317", Format="<host>:<port>
"
Address of the OpenTelemetry Collector to send access logs to.
accesslog:
otlp:
grpc:
endpoint: localhost:4317
[accesslog.otlp.grpc]
endpoint = "localhost:4317"
--accesslog.otlp.grpc.endpoint=localhost:4317
insecure
¶
Optional, Default=false
Allows exporter to send access logs to the OpenTelemetry Collector without using a secured protocol.
accesslog:
otlp:
grpc:
insecure: true
[accesslog.otlp.grpc]
insecure = true
--accesslog.otlp.grpc.insecure=true
headers
¶
Optional, Default={}
Additional headers sent with access logs by the exporter to the OpenTelemetry Collector.
accesslog:
otlp:
grpc:
headers:
foo: bar
baz: buz
[accesslog.otlp.grpc.headers]
foo = "bar"
baz = "buz"
--accesslog.otlp.grpc.headers.foo=bar --accesslog.otlp.grpc.headers.baz=buz
tls
¶
Optional
Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector.
ca
¶
Optional
ca
is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
accesslog:
otlp:
grpc:
tls:
ca: path/to/ca.crt
[accesslog.otlp.grpc.tls]
ca = "path/to/ca.crt"
--accesslog.otlp.grpc.tls.ca=path/to/ca.crt
cert
¶
Optional
cert
is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the key
option is required.
accesslog:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
[accesslog.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
--accesslog.otlp.grpc.tls.cert=path/to/foo.cert
--accesslog.otlp.grpc.tls.key=path/to/foo.key
key
¶
Optional
key
is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the cert
option is required.
accesslog:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
[accesslog.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
--accesslog.otlp.grpc.tls.cert=path/to/foo.cert
--accesslog.otlp.grpc.tls.key=path/to/foo.key
insecureSkipVerify
¶
Optional, Default=false
If insecureSkipVerify
is true
,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
accesslog:
otlp:
grpc:
tls:
insecureSkipVerify: true
[accesslog.otlp.grpc.tls]
insecureSkipVerify = true
--accesslog.otlp.grpc.tls.insecureSkipVerify=true
Using Traefik OSS in Production?
If you are using Traefik at work, consider adding enterprise-grade API gateway capabilities or commercial support for Traefik OSS.
Adding API Gateway capabilities to Traefik OSS is fast and seamless. There's no rip and replace and all configurations remain intact. See it in action via this short video.