2019-02-26 13:50:07 +00:00
# Access Logs
Who Calls Whom?
{.subtitle}
By default, logs are written to stdout, in text format.
2021-06-18 22:08:08 +00:00
## Configuration
2019-02-26 13:50:07 +00:00
2019-06-27 14:04:03 +00:00
To enable the access logs:
2019-02-26 13:50:07 +00:00
2019-07-22 07:58:04 +00:00
```yaml tab="File (YAML)"
accessLog: {}
```
2021-06-18 22:08:08 +00:00
```toml tab="File (TOML)"
[accessLog]
```
2019-06-27 14:04:03 +00:00
```bash tab="CLI"
2019-07-22 07:58:04 +00:00
--accesslog=true
2019-06-27 14:04:03 +00:00
```
2019-02-26 13:50:07 +00:00
2019-06-27 14:04:03 +00:00
### `filePath`
2019-02-26 13:50:07 +00:00
By default access logs are written to the standard output.
To write the logs into a log file, use the `filePath` option.
2020-12-14 11:34:05 +00:00
```yaml tab="File (YAML)"
accessLog:
filePath: "/path/to/access.log"
```
2021-06-18 22:08:08 +00:00
```toml tab="File (TOML)"
[accessLog]
filePath = "/path/to/access.log"
```
2020-12-14 11:34:05 +00:00
```bash tab="CLI"
--accesslog.filepath=/path/to/access.log
```
2019-06-27 14:04:03 +00:00
### `format`
2021-06-18 22:08:08 +00:00
2019-02-26 13:50:07 +00:00
By default, logs are written using the Common Log Format (CLF).
To write logs in JSON, use `json` in the `format` option.
2019-09-09 07:24:03 +00:00
If the given format is unsupported, the default (CLF) is used instead.
2019-02-26 13:50:07 +00:00
2019-09-23 12:32:04 +00:00
!!! info "Common Log Format"
2021-06-18 22:08:08 +00:00
2019-02-26 13:50:07 +00:00
```html
2020-03-17 11:36:04 +00:00
< remote_IP_address > - < client_user_name_if_available > [< timestamp > ] "< request_method > < request_path > < request_protocol > " < origin_server_HTTP_status > < origin_server_content_size > "< request_referrer > " "< request_user_agent > " < number_of_requests_received_since_Traefik_started > "< Traefik_router_name > " "< Traefik_server_URL > " < request_duration_in_ms > ms
2019-02-26 13:50:07 +00:00
```
2019-06-27 14:04:03 +00:00
### `bufferingSize`
2019-02-26 13:50:07 +00:00
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.
2019-07-22 07:58:04 +00:00
```yaml tab="File (YAML)"
# Configuring a buffer of 100 lines
accessLog:
filePath: "/path/to/access.log"
bufferingSize: 100
```
2021-06-18 22:08:08 +00:00
```toml tab="File (TOML)"
# Configuring a buffer of 100 lines
[accessLog]
filePath = "/path/to/access.log"
bufferingSize = 100
```
2019-06-27 14:04:03 +00:00
```bash tab="CLI"
# Configuring a buffer of 100 lines
2019-11-19 09:18:05 +00:00
--accesslog.filepath=/path/to/access.log
2019-06-27 14:04:03 +00:00
--accesslog.bufferingsize=100
```
2019-02-26 13:50:07 +00:00
2019-06-27 14:04:03 +00:00
### Filtering
2019-02-26 13:50:07 +00:00
2021-06-18 22:08:08 +00:00
To filter logs, you can specify a set of filters which are logically "OR-connected".
2019-02-26 13:50:07 +00:00
Thus, specifying multiple filters will keep more access logs than specifying only one.
2021-06-18 22:08:08 +00:00
The available filters are:
2019-02-26 13:50:07 +00:00
- `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
2020-10-22 09:36:03 +00:00
- `minDuration` , to keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format, see [time.ParseDuration ](https://golang.org/pkg/time/#ParseDuration ))
2019-02-26 13:50:07 +00:00
2019-07-22 07:58:04 +00:00
```yaml tab="File (YAML)"
# Configuring Multiple Filters
accessLog:
filePath: "/path/to/access.log"
format: json
2021-06-18 22:08:08 +00:00
filters:
2019-07-22 07:58:04 +00:00
statusCodes:
2019-09-23 15:00:06 +00:00
- "200"
- "300-302"
2019-07-22 07:58:04 +00:00
retryAttempts: true
minDuration: "10ms"
```
2021-06-18 22:08:08 +00:00
```toml tab="File (TOML)"
# Configuring Multiple Filters
[accessLog]
filePath = "/path/to/access.log"
format = "json"
[accessLog.filters]
statusCodes = ["200", "300-302"]
retryAttempts = true
minDuration = "10ms"
```
2019-06-27 14:04:03 +00:00
```bash tab="CLI"
# Configuring Multiple Filters
2019-11-19 09:18:05 +00:00
--accesslog.filepath=/path/to/access.log
--accesslog.format=json
--accesslog.filters.statuscodes=200,300-302
2019-06-27 14:04:03 +00:00
--accesslog.filters.retryattempts
2019-11-19 09:18:05 +00:00
--accesslog.filters.minduration=10ms
2019-06-27 14:04:03 +00:00
```
2020-05-26 14:56:04 +00:00
### Limiting the Fields/Including Headers
2019-02-26 13:50:07 +00:00
2020-05-26 14:56:04 +00:00
You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.headers` options.
2019-02-26 13:50:07 +00:00
Each field can be set to:
- `keep` to keep the value
- `drop` to drop the value
- `redact` to replace the value with "redacted"
2020-05-26 14:56:04 +00:00
The `defaultMode` for `fields.headers` is `drop` .
2019-06-27 14:04:03 +00:00
[accessLog.fields]
defaultMode = "keep"
2019-07-22 07:58:04 +00:00
```yaml tab="File (YAML)"
# Limiting the Logs to Specific Fields
accessLog:
filePath: "/path/to/access.log"
format: json
fields:
defaultMode: keep
2019-09-05 08:48:04 +00:00
names:
ClientUsername: drop
headers:
defaultMode: keep
2019-07-22 07:58:04 +00:00
names:
2019-09-05 11:42:04 +00:00
User-Agent: redact
Authorization: drop
Content-Type: keep
2019-07-22 07:58:04 +00:00
```
2021-06-18 22:08:08 +00:00
```toml tab="File (TOML)"
# Limiting the Logs to Specific Fields
[accessLog]
filePath = "/path/to/access.log"
format = "json"
[accessLog.fields.names]
"ClientUsername" = "drop"
[accessLog.fields.headers]
defaultMode = "keep"
[accessLog.fields.headers.names]
"User-Agent" = "redact"
"Authorization" = "drop"
"Content-Type" = "keep"
```
2019-06-27 14:04:03 +00:00
```bash tab="CLI"
# Limiting the Logs to Specific Fields
2019-11-19 09:18:05 +00:00
--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
2019-06-27 14:04:03 +00:00
```
2019-02-26 13:50:07 +00:00
2019-09-23 12:32:04 +00:00
??? info "Available Fields"
2019-02-26 13:50:07 +00:00
2019-05-21 15:02:11 +00:00
| Field | Description |
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `StartUTC` | The time at which request processing started. |
| `StartLocal` | The local time at which request processing started. |
2019-10-16 08:34:04 +00:00
| `Duration` | The total time taken (in nanoseconds) by processing the response, including the origin server's time but not the log writing time. |
2020-07-01 10:14:04 +00:00
| `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` ) |
2019-05-21 15:02:11 +00:00
| `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. |
2020-03-17 11:36:04 +00:00
| `RequestScheme` | The HTTP scheme requested `http` or `https` . |
2019-05-21 15:02:11 +00:00
| `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` |
| `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. |
2020-10-22 09:36:03 +00:00
| `OriginDuration` | The time taken (in nanoseconds) by the origin server ('upstream') to return its response. |
2019-05-21 15:02:11 +00:00
| `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. |
| `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. |
2020-10-22 09:36:03 +00:00
| `Overhead` | The processing time overhead (in nanoseconds) caused by Traefik. |
2019-05-21 15:02:11 +00:00
| `RetryAttempts` | The amount of attempts the request was retried. |
2019-02-26 13:50:07 +00:00
## 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` .
2019-09-23 12:32:04 +00:00
!!! warning
2019-02-26 13:50:07 +00:00
This does not work on Windows due to the lack of USR signals.
2020-08-25 12:38:04 +00:00
## 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:
1. 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
2. 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:v2.2
environment:
- TZ=US/Alaska
command:
- --accesslog.fields.names.StartUTC=drop
- --providers.docker
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```