Project: Traefik (Orchestration & Management / API Gateway)
File: access-logs.md

title: "Traefik Access Logs Documentation" description: "Access logs are a key part of observability in Traefik Proxy. Read the technical documentation to learn their configurations, rotations, and time zones." Who Calls Whom? {.subtitle} By default, logs are written to stdout, in text format. To enable the access logs: ```yaml tab="File (YAML)" accessLog: {} ``` ```toml tab="File (TOML)" [accessLog] ``` ```bash tab="CLI" --accesslog=true ``` Optional, Default="false" Enables accessLogs for internal resources (e.g.: `ping@internal`). ```yaml tab="File (YAML)" accesslog: addInternals: true ``` ```toml tab="File (TOML)" [accesslog] addInternals = true ``` ```bash tab="CLI" --accesslog.addinternals ``` By default access logs are written to the standard output. To write the logs into a log file, use the `filePath` option. ```yaml tab="File (YAML)" accessLog: filePath: "/path/to/access.log" ``` ```toml tab="File (TOML)" [accessLog] filePath = "/path/to/access.log" ``` ```bash tab="CLI" --accesslog.filepath=/path/to/access.log ``` 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. !!! info "Common Log Format" ```html <remoteIPaddress> - <clientusernameifavailable> [<timestamp>] "<requestmethod> <requestpath> <requestprotocol>" <HTTPstatus> <content-length> "<requestreferrer>" "<requestuseragent>" <numberofrequestsreceivedsinceTraefikstarted> "<Traefikroutername>" "<TraefikserverURL>" <requestdurationinms>ms ``` 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. ```yaml tab="File (YAML)" accessLog: filePath: "/path/to/access.log" bufferingSize: 100 ``` ```toml tab="File (TOML)" [accessLog] filePath = "/path/to/access.log" bufferingSize = 100 ``` ```bash tab="CLI" --accesslog.filepath=/path/to/access.log --accesslog.bufferingsize=100 ``` 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 range `retryAttempts`, to keep the access logs when at least one retry has happened `minDuration`, to keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format, see ) ```yaml tab="File (YAML)" accessLog: filePath: "/path/to/access.log" format: json filters: statusCodes: "200" "300-302" retryAttempts: true minDuration: "10ms" ``` ```toml tab="File (TOML)" [accessLog] filePath = "/path/to/access.log" format = "json" [accessLog.filters] statusCodes = ["200", "300-302"] retryAttempts = true minDuration = "10ms" ``` ```bash tab="CLI" --accesslog.filepath=/path/to/access.log --accesslog.format=json --accesslog.filters.statuscodes=200,300-302 --accesslog.filters.retryattempts --accesslog.filters.minduration=10ms ``` 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 value `drop` to drop the value `redact` to replace the value with "redacted" The `defaultMode` for `fields.names` is `keep`. The `defaultMode` for `fields.headers` is `drop`. ```yaml tab="File (YAML)" 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 ``` ```toml tab="File (TOML)" [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" ``` ```bash tab="CLI" --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 ``` ??? info "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

| | `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. `TLSECDHERSAWITH3DESEDECBC_SHA`) (if connection is TLS) | | `TLSClientSubject` | The string representation of the TLS client certificate's Subject (e.g. `CN=username,O=organization`) | 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. 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 named `StartUTC` (available on the default Common Log Format (CLF) as well as JSON) Example utilizing Docker Compose: ```yaml version: "3.7" services: traefik: image: traefik:v3.0 environment: TZ=US/Alaska command: --accesslog.fields.names.StartUTC=drop --providers.docker ports: 80:80 volumes: /var/run/docker.sock:/var/run/docker.sock ```