Open-Source Wikis

/

Envoy

/

Features

/

Access logging

envoyproxy/envoy

Access logging

Envoy's access log is the per-request structured emission produced after a stream completes. Loggers are configurable per HCM listener, per route, per virtual host, per cluster (upstream events), and per filter (sub-events). Implementations live under source/extensions/access_loggers/.

Shipped loggers

Logger Path Behaviour
file file/ Append to a file on disk; supports text and JSON formats.
stream stream/ Write to stderr/stdout. Mostly for embedded scenarios.
grpc grpc/ Stream to a gRPC service (TCP or HTTP variants). The proto is envoy.service.accesslog.v3.
open_telemetry open_telemetry/ Emit OpenTelemetry log records.
fluentd fluentd/ Forward to a Fluentd daemon.
stats stats/ Convert log entries into per-request stat increments.
wasm wasm/ Pass log records to a Wasm plugin.
dynamic_modules dynamic_modules/ Hand off to a dynamic module.
filters filters/ Predicates that gate logger invocation (status code range, sampler, header match).

Lifecycle

sequenceDiagram
    participant FM as FilterManager
    participant FA as AccessLog::FilterChain
    participant L as AccessLog::Instance

    FM->>FA: log() at end of stream / on connection close
    FA->>FA: evaluate filter predicates
    FA->>L: log(formatter context, stream_info) if predicate true
    L->>L: format and write

The AccessLog::Instance interface is in envoy/access_log/access_log.h. Each logger has a (possibly empty) chain of AccessLog::Filter objects that decide whether to invoke it for a given stream.

Per-route, per-virtual-host, per-listener loggers

The HCM config carries the listener-level access loggers; the route configuration can add loggers per virtual host or per route; some filters (e.g. ext_authz, ext_proc) emit their own logs. The full list runs at end-of-stream.

Periodic logging

access_log_options on the HCM lets you enable periodic logging during long streams (e.g. WebSocket sessions) — every N seconds the same entry is logged with current StreamInfo so an analyst can see liveness without waiting for stream end.

Formatters

Both file and grpc accept a format string. The default is the Envoy "default access log format" — see envoy.access_loggers.file/v3/file.proto. The format language understands command operators like:

  • %REQ(:METHOD)%, %REQ(X-FOO)%, %REQ(X-FOO?X-BAR)% — request header.
  • %RESP(...)% — response header.
  • %TRAILER(...)% — request trailer.
  • %RESPONSE_CODE%, %RESPONSE_FLAGS%, %RESPONSE_FLAGS_LONG% — outcome.
  • %DURATION%, %REQUEST_DURATION%, %RESPONSE_DURATION%, %RESPONSE_TX_DURATION%.
  • %UPSTREAM_HOST%, %UPSTREAM_CLUSTER%, %UPSTREAM_LOCAL_ADDRESS%.
  • %DOWNSTREAM_REMOTE_ADDRESS%, %DOWNSTREAM_LOCAL_ADDRESS%.
  • %FILTER_STATE(key)%, %DYNAMIC_METADATA(filter:key)%.
  • %CEL(expr)% — Common Expression Language.

The lexer/evaluator is in source/common/formatter/. Custom formatters can be added by registering a BuiltInCommandParser extension.

JSON / structured

For structured output, use JsonFormatter (set json_format instead of text_format) or the open_telemetry logger which produces an OpenTelemetry log record.

Filters

Access log filters short-circuit emission. They include:

  • status_code_filter — only log 5xx, only log 2xx, etc.
  • duration_filter — only log slow requests.
  • not_health_check_filter — drop health-check noise.
  • traceable_filter — only log when the request is sampled for tracing.
  • runtime_filter — sample by runtime fraction.
  • and_filter / or_filter — boolean composition.
  • header_filter — match on request header.
  • response_flag_filter — match on RESPONSE_FLAGS.
  • grpc_status_filter — match on grpc status.
  • metadata_filter — match on dynamic metadata.
  • log_type_filter — match downstream-start vs downstream-end vs upstream-poll.
  • extension_filter — opaque extension (Wasm/CEL).

File logger internals

The file logger (in access_loggers/file/) hands writes to a Filesystem::AsyncFileManager (source/common/filesystem/async_file_manager_impl.cc) so workers don't block on file IO. Reopening on SIGUSR1 lets log rotation proceed without restart.

gRPC logger internals

The grpc logger has a tcp variant (single connection per cluster, log entries multiplexed) and an http variant. Both batch entries to amortise gRPC overhead. The proto schema is in api/envoy/data/accesslog/v3/.

Adding a logger

  1. New directory under source/extensions/access_loggers/<name>/.
  2. Implement AccessLog::Instance and an AccessLog::AccessLogFactory.
  3. Proto under api/envoy/extensions/access_loggers/<name>/v3/.
  4. Register in extensions_build_config.bzl.

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Access logging – Envoy wiki | Factory