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 writeThe 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 onRESPONSE_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
- New directory under
source/extensions/access_loggers/<name>/. - Implement
AccessLog::Instanceand anAccessLog::AccessLogFactory. - Proto under
api/envoy/extensions/access_loggers/<name>/v3/. - Register in
extensions_build_config.bzl.
See also
- HTTP connection manager — owns the HCM-level loggers.
- Tracing — adjacent observability.
- Stats — the
statsaccess logger.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.