Open-Source Wikis

/

nginx

/

Systems

/

Logging

nginx/nginx

Logging

Active contributors: Maxim Dounin, Sergey Kandaurov

Purpose

NGINX has two main logs:

  • Error log (error_log) — process-wide diagnostic stream, written by every ngx_log_error call. Levels: debug < info < notice < warn < error < crit < alert < emerg.
  • Access log (access_log) — per-request log lines for HTTP and Stream, configurable via log_format.

Both can write to files, to stderr, to syslog, or to a custom destination via the audit_log shared-zone helpers used by some third-party modules.

Files

File Role
src/core/ngx_log.{c,h} Error log: ngx_log_error, ngx_log_debug*
src/core/ngx_syslog.{c,h} Syslog target (UDP)
src/http/modules/ngx_http_log_module.c HTTP access log + log_format engine
src/stream/ngx_stream_log_module.c Stream access log

Error log

ngx_log_error(level, log, errno, fmt, ...) is the universal entry point. It:

  1. Checks level against the log's configured threshold (cheap — early-out).
  2. Formats the message into a stack buffer using the custom formatter (ngx_vslprintf).
  3. Appends errno translated to a string when nonzero.
  4. Appends a stack trace marker if compiled with --with-debug and the level is debug.
  5. Writes to each target attached to the log.

ngx_log_t is a chain — multiple targets (e.g., a file plus syslog) can be attached. The cycle owns the master log (cycle->log); each connection gets its own ngx_log_t derived from it; per-request loggers carry request-specific context (the $request_id, the $server_name, etc.).

ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, "msg") (and _debug1 ... _debug8 for printf-style args) compile to no-ops unless --with-debug is configured. The NGX_LOG_DEBUG_* constants are bitmasks: NGX_LOG_DEBUG_CORE, _ALLOC, _MUTEX, _EVENT, _HTTP, _MAIL, _STREAM. The debug_connection directive lets you enable debug only for a specific client.

Format

2026/04/30 12:34:56 [error] 12345#67: *890 something happened, client: 1.2.3.4, server: example.com, request: "GET / HTTP/1.1", host: "example.com"

The pieces:

  • Timestamp (cached ngx_cached_log_time).
  • Level in brackets.
  • pid#tid of the writer.
  • *<conn_id> if a connection is in scope.
  • Message.
  • Optional connection / request context appended by helpers (r->log_handler, c->log->handler).

The connection counter *N comes from the per-cycle ngx_connection_counter atomic, useful for grepping all log lines of one connection.

Access log

access_log /var/log/nginx/access.log <format_name>; writes one line per HTTP request at the LOG phase. The format is precompiled at config time to avoid per-request parsing.

log_format directive:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

The format is compiled by ngx_http_log_compile_format into a series of ngx_http_log_op_t operations, each with an op->run function pointer. At LOG time, each op runs against the request and produces bytes into the log buffer. Variables go through ngx_http_get_indexed_variable (fast path).

A handful of operations are specialized so they don't go through the variable system:

Op What it produces
ngx_http_log_copy A constant string literal
ngx_http_log_pipe A pipe character
ngx_http_log_time Cached time
ngx_http_log_msec Cached msec time
ngx_http_log_request_time The $request_time value
ngx_http_log_status The $status value
ngx_http_log_bytes_sent The total bytes sent

Buffering and gzip

access_log path buffer=64k flush=5s; buffers writes in memory and flushes periodically. gzip=... compresses on the fly using zlib. Both keep the access log out of the hot path on busy servers.

ngx_http_log_module allocates the buffer in the worker's pool but keeps a per-target structure so multiple access_log directives in the same scope each get their own buffer.

Conditional logging

access_log /path/to/file format if=$loggable; evaluates $loggable per request and skips the line if false. Used for filtering out health checks, etc.

Syslog

error_log syslog:server=...,facility=...,severity=...,tag=... format; opens a UDP socket to the syslog server (typically localhost:514) at first write and sends RFC 3164 messages. Implementation: src/core/ngx_syslog.c. A failure to send doesn't block — syslog is best-effort.

The same syntax works for access_log syslog:....

Log rotation

SIGUSR1 to the master triggers ngx_reopen_files() (src/core/ngx_cycle.c), which closes and reopens every ngx_open_file_t in cycle->open_files. Workers receive NGX_CMD_REOPEN over the channel and do the same. The standard rotation procedure:

mv access.log access.log.old
nginx -s reopen
gzip access.log.old

Logs that target stderr or syslog don't need this.

$request_id and request tracing

$request_id is a 16-byte hex string (ngx_random()-derived) generated at request start. Useful for correlating across access log + error log + upstream X-Request-ID header when forwarding via proxy_set_header X-Request-ID $request_id;.

Integration points

  • Every module uses ngx_log_error and ngx_log_debug*. There's no second logging API.
  • Variables — access log relies on the variable system; everything that can appear in a log_format must be a registered variable.
  • Event loop / timengx_cached_log_time is updated once per loop iteration, so all log lines in one event-loop pass share a timestamp (good enough at the second granularity of error log; $msec and $request_time use the cached msec clock).
  • Cycle / process model — log rotation goes through the master/worker channel.

Entry points for modification

Adding a new log target (e.g., a structured-JSON sink) is typically a third-party module that registers its own ngx_open_file_t and log_format. Adding a new built-in log_format op goes in ngx_http_log_module.c. Changing error-log formatting touches ngx_log_error_core in src/core/ngx_log.c — be careful, every line of every log file depends on it.

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

Logging – nginx wiki | Factory