TOC

Nginx 日志配置

零、自定义格式

Nginx 默认日志格式(定义在 /etc/nginx/nginx.conf http 段配置中):

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

输出结果如下:

/ # tail -f /var/log/nginx/markjour.com_access.log
172.18.0.1 - - [10/Mar/2024:09:59:24 +0000] "GET /webhook/api/events?endpoint_name=asc&limit=10&last_id=914&desc=False HTTP/1.1" 200 3 "-" "python-requests/2.33.1" "-"
172.18.0.1 - - [10/Mar/2024:09:59:29 +0000] "GET /webhook/api/events?endpoint_name=asc&limit=10&last_id=914&desc=False HTTP/1.1" 200 3 "-" "python-requests/2.33.1" "-"
172.18.0.1 - - [10/Mar/2024:09:59:34 +0000] "GET /webhook/api/events?endpoint_name=asc&limit=10&last_id=914&desc=False HTTP/1.1" 200 3 "-" "python-requests/2.33.1" "-"

我觉得这个数据量有点太少了,排查问题的时候不够,上游处理时间都没有,调试时改成这样:

log_format woodylog
    'time="$time_iso8601" '
    'remote_addr="$remote_addr" '
    'remote_user="$remote_user" '
    'xff="$http_x_forwarded_for" '
    'host="$host" '
    'method="$request_method" '
    'uri="$uri" '
    'args="$args" '
    'status=$status '
    'body_bytes=$body_bytes_sent '
    'request_length=$request_length '
    'request_time=$request_time '
    'upstream="$upstream_addr" '
    'upstream_status="$upstream_status" '
    'upstream_connect_time="$upstream_connect_time" '
    'upstream_header_time="$upstream_header_time" '
    'upstream_response_time="$upstream_response_time" '
    'referer="$http_referer" '
    'ua="$http_user_agent" '
    'request_id="$request_id"';
time="2024-03-10T10:00:29+00:00" remote_addr="117.152.221.178" remote_user="-" xff="-" host="markjour.com" method="GET" uri="/testcases/runs/1466daf3" args="result=failed" status=200 body_bytes=61411 request_length=3152 request_time=2.190 upstream="172.17.0.1:9999" upstream_status="200" upstream_connect_time="0.000" upstream_header_time="2.188" upstream_response_time="2.190" referer="-" ua="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0" request_id="f9319ae69738a1e1d33701a095b0c790"

Nginx 日志变量主要来自以下几个模块:

  • Core(核心变量)
  • HTTP(请求相关)
  • Stream(TCP/UDP)
  • SSL
  • GeoIP
  • Upstream
  • HTTP Header
  • 自定义变量(map、set、js、lua 等)

HTTP 场景(access_log)常用变量如下。

一、请求信息

变量 含义
$request 完整请求行,例如 GET /index.html HTTP/1.1
$request_method GET、POST
$request_uri 原始 URI,包含 QueryString
$uri 当前 URI(可能 rewrite 后)
$document_uri $uri 相同
$args QueryString
$is_args 有参数为 ?,否则为空
$query_string $args
$scheme http / https
$protocol HTTP/1.0、HTTP/1.1、HTTP/2.0
$request_length 请求总大小(Header+Body)
$content_length 请求 Body 长度
$content_type Content-Type

二、客户端信息

变量 含义
$remote_addr 客户端 IP
$remote_port 客户端端口
$binary_remote_addr 二进制 IP
$realip_remote_addr RealIP 模块解析后的 IP
$realip_remote_port RealIP 后端端口
$proxy_protocol_addr Proxy Protocol IP
$proxy_protocol_port Proxy Protocol Port

三、Host

变量 含义
$host Host Header 或 Server Name
$http_host 原始 Host Header
$server_name 命中的 server_name
$hostname 当前机器 Hostname
$server_addr 本机 IP
$server_port 本机端口

四、响应信息

变量 含义
$status HTTP 状态码
$body_bytes_sent Response Body 大小
$bytes_sent Header+Body 大小
$sent_http_content_type 返回 Content-Type
$sent_http_location 返回 Location
$sent_http_cache_control 返回 Cache-Control

凡是响应 Header,都可以:

$sent_http_x_request_id
$sent_http_etag
$sent_http_server

五、时间

变量 含义
$time_local Apache 风格时间
$time_iso8601 ISO8601
$msec Unix 秒(毫秒精度)
$request_time 请求耗时
$connection_time TCP 连接建立到当前时间

六、连接信息

变量 含义
$connection Connection ID
$connection_requests 当前连接已处理请求数
$pipe 是否 Pipeline
$http2 是否 HTTP/2
$http3 是否 HTTP/3(新版)

七、SSL

变量 含义
$ssl_protocol TLS1.2 / TLS1.3
$ssl_cipher 加密套件
$ssl_curve ECDHE 曲线
$ssl_session_id Session ID
$ssl_server_name SNI
$ssl_client_verify 客户端证书验证结果

八、Upstream(反向代理最常用)

变量 含义
$upstream_addr 后端地址
$upstream_status 后端状态码
$upstream_response_time 后端耗时
$upstream_connect_time 建连耗时
$upstream_header_time Header 返回耗时
$upstream_bytes_received 收到字节数
$upstream_bytes_sent 发送字节数
$upstream_cache_status HIT、MISS、BYPASS 等

九、请求 Header

任何请求 Header 都可以写:

$http_user_agent
$http_referer
$http_cookie
$http_origin
$http_authorization
$http_accept
$http_accept_language
$http_x_forwarded_for
$http_x_real_ip

规则:

Header: X-Request-Id

↓

$http_x_request_id

即:

  • 全部小写
  • -_
  • 前缀 $http_

十、Cookie

Cookie 同样可以直接获取:

$cookie_sessionid
$cookie_token
$cookie_uid

例如

Cookie:
sessionid=abc
uid=100

对应

$cookie_sessionid
$cookie_uid

十一、变量组合

变量 含义
$request_id 请求唯一 ID(较新版本内置)
$pid Worker PID
$nginx_version Nginx 版本
$server_protocol HTTP/1.1
$limit_rate 当前限速
$gzip_ratio gzip 压缩率

十二、自定义变量

可以通过 setmap 等创建变量:

map $http_user_agent $device {
    default desktop;
    "~Mobile" mobile;
}

log_format json escape=json
'{"device":"$device"}';

或者:

set $cluster "prod";

log_format main
'$cluster';

十三、查看所有可用变量

官方没有提供运行时命令列出所有变量,但可以参考官方文档:

  • ngx_http_core_module 中的 Embedded Variables(核心嵌入变量)
  • 各模块文档(如 ngx_http_ssl_modulengx_http_upstream_module)中的变量说明

实际可用变量取决于你的 Nginx 编译模块(例如是否启用了 SSL、RealIP、GeoIP 等)。

如果你的目标是设计一套生产环境 JSON 日志,通常会记录以下字段:

time
request_id
remote_addr
xff
host
method
uri
args
status
request_length
body_bytes_sent
request_time
upstream_addr
upstream_status
upstream_connect_time
upstream_header_time
upstream_response_time
referer
user_agent

这套字段基本覆盖了访问分析、性能分析、故障排查和链路追踪等常见场景。

如果你有魔法,你可以看到一个评论框~