Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/v3/configuration/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ Options:
Log the X-Forwarded-For header for remote IP information [env: SERVER_LOG_FORWARDED_FOR=] [default: false] [possible values: true, false]
--trusted-proxies <TRUSTED_PROXIES>
List of IPs to use X-Forwarded-For from. The default is to trust all [env: SERVER_TRUSTED_PROXIES=]
--log-trace-context [<LOG_TRACE_CONTEXT>]
Add the `trace_id`, `span_id` and `trace_flags` fields of a valid W3C `traceparent` request header to the log lines emitted by the request handler. Requires `--log-format json` [env: SERVER_LOG_TRACE_CONTEXT=] [default: false] [possible values: true, false]
--redirect-trailing-slash [<REDIRECT_TRAILING_SLASH>]
Check for a trailing slash in the requested directory URI and redirect permanently (308) to the same path with a trailing slash suffix if it is missing [env: SERVER_REDIRECT_TRAILING_SLASH=] [default: true] [possible values: true, false]
--include-hidden [<INCLUDE_HIDDEN>]
Expand Down
4 changes: 4 additions & 0 deletions src/v3/configuration/env.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ Log the `X-Forwarded-For` header for remote IP information. Default `false`.

List of IPs to use `X-Forwarded-For` from. The default is to trust all. Default `""`.

## SERVER_LOG_TRACE_CONTEXT

Add the trace context of a valid W3C `traceparent` request header to the JSON log lines of the request handler. See [Logging Trace Context](../features/logging#logging-trace-context). Default `false`.

## SERVER_REDIRECT_TRAILING_SLASH

Check for a trailing slash in the requested directory URI and redirect permanently (308) to the same path with a trailing slash suffix if it is missing. Default `true` (enabled).
Expand Down
3 changes: 3 additions & 0 deletions src/v3/configuration/file.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ log-forwarded-for = false
#### IPs to accept the X-Forwarded-For header from. Empty means all
trusted-proxies = []

#### Log the W3C trace context of the `traceparent` header (JSON log format only)
log-trace-context = false

#### Redirect to trailing slash in the requested directory uri
redirect-trailing-slash = true

Expand Down
32 changes: 31 additions & 1 deletion src/v3/features/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ When the level is `info` or lower, SWS logs each request with the `incoming requ
}
```

The `remote_addr`, `x_real_ip` and `real_remote_ip` fields are added when the corresponding logging options are enabled and a value is available. Fields without a value are omitted.
The `remote_addr`, `x_real_ip` and `real_remote_ip` fields are added when the corresponding logging options are enabled and a value is available, and the `trace_id`, `span_id` and `trace_flags` fields when [trace context logging](#logging-trace-context) is enabled. Fields without a value are omitted.

## Log Remote Addresses

Expand Down Expand Up @@ -230,6 +230,36 @@ curl "http://[::1]:8080" --header "X-Forwarded-For: <iframe src=//malware.attack
}
```

## Logging Trace Context

When SWS runs behind a proxy or load balancer that starts or continues a [W3C Trace Context](https://www.w3.org/TR/trace-context/) trace, the proxy forwards a `traceparent` request header. SWS can add the trace context of that header to its log lines, so a log backend can link them to the trace and to the logs of other services.

This feature is disabled by default. Enable it with the boolean `--log-trace-context` option, the equivalent [SERVER_LOG_TRACE_CONTEXT](./../configuration/env#server_log_trace_context) env or the `log-trace-context` key of the config file. It requires the `json` [log format](#log-format).

When enabled and the request has a valid `traceparent` header, the log lines emitted by the request handler get three top-level fields, as recommended by the OpenTelemetry [Trace Context in Non-OTLP Log Formats](https://opentelemetry.io/docs/specs/otel/compatibility/logging_trace_context/) specification:

- `trace_id`: the `trace-id` of the header (32 lowercase hex characters).
- `span_id`: the `parent-id` of the header (16 lowercase hex characters), which is the span of the caller. SWS does not create spans of its own.
- `trace_flags`: the `trace-flags` of the header (2 lowercase hex characters).

```sh
static-web-server -p 8787 -d ./public/ -g info --log-trace-context
```

```sh
curl "http://localhost:8787/missing.css" \
--header "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
```

```json
{"timestamp":"2026-09-28T10:39:57.103529+02:00","level":"INFO","message":"incoming request","method":"GET","uri":"/missing.css","target":"static_web_server::log_addr","span_id":"00f067aa0ba902b7","trace_flags":"01","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736"}
{"timestamp":"2026-09-28T10:39:57.103712+02:00","level":"WARN","method":"GET","uri":"/missing.css","status":404,"error":"Not Found","target":"static_web_server::error_page","span_id":"00f067aa0ba902b7","trace_flags":"01","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736"}
```

The fields are added at every log level, e.g. to the `404` warning when the level is `warn`.

SWS only reads the header. It does not generate trace IDs, export spans or change the headers of the request or the response. Missing, invalid or repeated `traceparent` headers are ignored; see the specification's [versioning rules](https://www.w3.org/TR/trace-context/#versioning-of-traceparent).

## File Logging

By default **SWS** writes log records to standard error. The `--log-file` option additionally streams every record to a file on disk, in **addition** to `stderr`. This is useful for production deployments where `stderr` is captured by a service manager but a durable on-disk copy is also required.
Expand Down