Nginx 调试
约 2252 字大约 8 分钟
2025-10-31
自定义日志格式
自定义日志格式让你能够精确记录所需信息,从基础访问日志到深度调试数据,满足不同场景的监控和排查需求。
Nginx 官方默认格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';企业级扩展格式
log_format main_extended
'$remote_addr - $remote_user [$time_local] ' # 客户端信息和时间
'"$request_method $scheme://$host$request_uri ' # 完整请求URL
'$server_protocol" $status $body_bytes_sent ' # 协议和响应状态
'"$http_referer" "$http_user_agent" ' # 来源和UA
'$request_time $upstream_response_time ' # 性能时间指标
'$http_x_forwarded_for'; # 代理链信息调试专用格式
log_format debug_full
'$remote_addr - $remote_user [$time_local] ' # 基础信息
'"$request_method $scheme://$host$request_uri ' # 请求详情
'$server_protocol" $status $body_bytes_sent ' # 响应状态
'$request_id $pid $msec $request_time ' # 请求标识和时序
'$upstream_connect_time $upstream_header_time ' # 上游连接时间
'$upstream_response_time ' # 上游响应时间
'"$request_filename" $request_completion ' # 文件路径和完成状态
'rc:$connection requests:$connection_requests'; # 连接统计API 服务专用格式
log_format api_monitoring
'$remote_addr [$time_local] ' # 客户端和时间
'"$request_method $request_uri" $status ' # API端点和方法
'$body_bytes_sent $request_time ' # 数据量和耗时
'$upstream_response_time ' # 后端处理时间
'"$http_user_agent" ' # 客户端标识
'rate:$limit_conn_status ' # 限流状态
'cache:$upstream_cache_status'; # 缓存命中状态安全审计格式
log_format security_audit
'$remote_addr - $remote_user [$time_local] ' # 基础信息
'"$request_method $host$request_uri" $status ' # 请求详情
'$http_referer "$http_user_agent" ' # 来源和UA
'xff:$http_x_forwarded_for ' # 真实IP链
'country:$geoip_country_code ' # 地理位置
'args:$query_string ' # 查询参数
'post_data:"$request_body"'; # POST数据(需配置)性能监控格式
log_format performance
'time:$time_iso8601 ' # ISO标准时间
'host:$host uri:$request_uri ' # 请求标识
'status:$status bytes:$body_bytes_sent ' # 响应信息
'req_time:$request_time ' # 总请求时间
'upstream_time:$upstream_response_time ' # 后端时间
'connect_time:$upstream_connect_time ' # 连接建立时间
'header_time:$upstream_header_time ' # 首字节时间
'cache:$upstream_cache_status'; # 缓存状态完整配置示例
http {
## 定义多种日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
log_format debug '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'rt=$request_time uct=$upstream_connect_time '
'uht=$upstream_header_time urt=$upstream_response_time';
log_format json escape=json
'{"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"host":"$host",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"upstream_response_time":"$upstream_response_time",'
'"http_user_agent":"$http_user_agent"}';
## 为不同场景应用不同格式
server {
server_name example.com;
## 主访问日志
access_log /var/log/nginx/access.log main;
## 调试日志(特定位置)
location /api/ {
access_log /var/log/nginx/api_debug.log debug;
...
}
## JSON 日志(机器解析)
location /internal/ {
access_log /var/log/nginx/internal.json json;
...
}
## 关闭不必要的日志
location /static/ {
access_log off;
...
}
}
}常用变量参考
基础信息变量
$remote_addr- 客户端IP$remote_user- 认证用户$time_local- 本地时间$time_iso8601- ISO8601时间格式
请求变量
$request_method- HTTP方法$scheme- 协议 (http/https)$host- 主机名$request_uri- 完整请求URI$query_string- 查询参数$server_protocol- HTTP协议版本
响应变量
$status- HTTP状态码$body_bytes_sent- 发送字节数$request_length- 请求长度
性能变量
$request_time- 请求处理总时间$upstream_connect_time- 上游连接时间$upstream_header_time- 上游首字节时间$upstream_response_time- 上游响应时间
高级变量
$http_*- 任意HTTP头$connection- 连接序列号$connection_requests- 连接请求数$limit_conn_status- 限流状态$upstream_cache_status- 缓存状态
最佳实践
按需启用日志
## 生产环境:主日志 + 错误日志
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
## 调试环境:增加调试日志
access_log /var/log/nginx/debug.log debug;结构化日志(推荐)
## JSON格式便于ELK等系统处理
log_format json_combined escape=json
'{'
'"timestamp":"$time_iso8601",'
'"client_ip":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"response_size":$body_bytes_sent,'
'"response_time":$request_time,'
'"user_agent":"$http_user_agent"'
'}';性能考虑
## 高流量路径关闭访问日志
location /health-check {
access_log off;
return 200 "healthy";
}
## 静态资源减少日志细节
location ~* \.(js|css|png|jpg)$ {
access_log /var/log/nginx/static.log;
expires 1y;
}缓冲区优化
## 使用缓冲减少磁盘IO
access_log /var/log/nginx/access.log main buffer=64k flush=1m;log_format 语法格式
log_format <format_name> [escape=default|json|none] <format_string>;format_name (必需)
- 日志格式的名称标识符
- 用于在
access_log指令中引用 - 命名规则:字母、数字、下划线
escape (可选参数)
指定特殊字符的转义方式:
## 默认转义 (双引号和空字符)
log_format main '$remote_addr - "$request"';
## JSON 转义 (所有JSON特殊字符)
log_format json escape=json '{"ip":"$remote_addr","request":"$request"}';
## 不转义
log_format raw escape=none '$remote_addr - $request';format_string (必需)
日志格式字符串,包含:
- 普通文本
- Nginx 变量 (
$variable_name) - 转义字符
完整语法示例
## 基本格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
## 带转义参数的格式
log_format json_format escape=json
'{"time":"$time_iso8601",'
'"ip":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status}';
## 多行格式(使用续行符)
log_format detailed
'$remote_addr - $remote_user [$time_local] '
'"$request_method $scheme://$host$request_uri $server_protocol" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $request_time $upstream_response_time';转义规则详解
escape=default (默认)
log_format default_escape '$remote_addr - "$request"';
## 输出示例: 192.168.1.1 - "GET /test\"data HTTP/1.1"
## 转义: " → \" , 空字符 → \x00escape=json
log_format json_escape escape=json '{"request":"$request"}';
## 输出示例: {"request":"GET /test\"data\nHTTP/1.1"}
## 转义: " → \" , \n → \\n , 等所有JSON特殊字符escape=none
log_format no_escape escape=none '$remote_addr - $request';
## 输出示例: 192.168.1.1 - GET /test"data
## 不进行任何转义配置位置和作用域
有效配置位置
## 只能在 http 块中配置
http {
## 正确位置
log_format main '...';
server {
## 错误!不能在 server 或 location 中定义
# log_format server_format '...';
## 但可以在 server/location 中使用
access_log /var/log/nginx/access.log main;
}
}作用域规则
http {
## 全局格式 - 所有 server 可用
log_format global_format '$remote_addr - $host';
server {
server_name site1.com;
access_log /var/log/site1.log global_format;
}
server {
server_name site2.com;
access_log /var/log/site2.log global_format; ## 可复用
}
}实际应用示例
条件日志格式
http {
## 定义多个格式
log_format main '$remote_addr - "$request" $status';
log_format debug '$remote_addr - "$request" $status $request_time $upstream_response_time';
server {
## 根据条件使用不同格式
set $log_format main;
if ($arg_debug) {
set $log_format debug;
}
access_log /var/log/nginx/access.log $log_format;
}
}包含文件方式
## 在单独文件中定义格式
## /etc/nginx/log-formats.conf
log_format main '...';
log_format json '...';
log_format debug '...';
## 主配置中引入
http {
include /etc/nginx/log-formats.conf;
server {
access_log /var/log/nginx/access.log main;
}
}变量组合技巧
log_format custom
## 文本常量
'Client: $remote_addr | '
## 时间信息
'Time: $time_iso8601 | '
## 请求信息(带条件)
'Request: $request_method $request_uri | '
## 响应信息
'Status: $status | '
## 性能指标
'Timing: req_time=$request_time upstream=$upstream_response_time | '
## HTTP 头信息
'UA: "$http_user_agent" | '
'Referer: "$http_referer"';语法注意事项
正确写法
## 使用单引号包裹整个格式字符串
log_format main '$remote_addr - $remote_user [$time_local] "$request"';
## 多行使用续行符
log_format extended
'$remote_addr - $remote_user '
'[$time_local] "$request" '
'$status $body_bytes_sent';错误写法
## 错误:缺少单引号
log_format main $remote_addr - $request;
## 错误:双引号包裹
log_format main "$remote_addr - $request";
## 错误:在错误的作用域
server {
log_format server_format '...'; ## 不允许!
}使用调试模式来跟踪意外行为
Nginx 调试模式提供 多层级、多粒度的日志记录,帮助开发者深入追踪系统行为和排查复杂问题。
错误日志级别体系
## 错误日志级别(从详细到简洁)
error_log /path/to/error.log debug; ## 🐛 最详细调试信息
error_log /path/to/error.log info; ## ℹ️ 一般信息
error_log /path/to/error.log notice; ## 💡 重要通知
error_log /path/to/error.log warn; ## ⚠️ 警告信息
error_log /path/to/error.log error; ## ❌ 错误信息(生产默认)
error_log /path/to/error.log crit; ## 🚨 严重错误作用域和继承规则
## 全局配置(main上下文)
error_log /var/log/nginx/error.log warn;
http {
## HTTP块级别(继承并覆盖全局)
error_log /var/log/nginx/http-error.log info;
server {
server_name app.example.com;
## Server级别(继承并覆盖HTTP块)
error_log /var/log/nginx/app-debug.log debug;
location /api/ {
## Location级别(最细粒度)
error_log /var/log/nginx/api-debug.log debug;
## 重写模块调试(记录rewrite规则执行)
rewrite_log on;
}
location /static/ {
## 关闭调试,恢复为更高级别配置
error_log off;
}
}
server {
server_name admin.example.com;
## 另一个server使用不同配置
error_log /var/log/nginx/admin-error.log error;
}
}内存日志(高性能调试)
## 将调试日志写入内存,避免磁盘IO瓶颈
error_log memory:32m debug;
## 适用场景:
## - 高并发下的性能问题追踪
## - 临时性调试,避免磁盘写满
## - 生产环境短期问题排查IP 条件调试
events {
## 仅为特定IP范围开启调试连接
debug_connection 192.168.252.15/32; ## 单个IP
debug_connection 10.10.10.0/24; ## 整个网段
debug_connection 2001:db8::/32; ## IPv6支持
}
## 效果:只有来自这些IP的请求会产生详细连接调试日志重写规则调试
server {
server_name example.com;
## 开启重写模块调试(notice级别)
rewrite_log on;
error_log /var/log/nginx/rewrite-debug.log notice;
location / {
## 复杂的重写规则
rewrite ^/old/(.*)$ /new/$1 permanent;
rewrite ^/user/([0-9]+)$ /profile?id=$1 last;
## 调试日志将显示:
## - 每个rewrite规则的匹配过程
## - 重定向执行结果
## - 变量替换详情
}
}企业级调试架构
分层调试配置
## 全局生产配置
error_log /var/log/nginx/error.log error;
http {
## 开发/测试环境覆盖
include /etc/nginx/conf.d/debug-override.conf;
server {
server_name staging.example.com;
## 预发环境:详细日志但非debug级别
error_log /var/log/nginx/staging-error.log info;
location /debug/ {
## 调试端点:临时开启完整调试
error_log /var/log/nginx/debug-endpoint.log debug;
rewrite_log on;
## 通过特定URL触发调试模式
if ($arg_debug = "true") {
error_log /var/log/nginx/temp-debug.log debug;
}
}
}
server {
server_name production.example.com;
## 生产环境:严格控制日志级别
error_log /var/log/nginx/prod-error.log error;
## 紧急调试开关(通过配置文件管理)
include /etc/nginx/conf.d/emergency-debug.conf;
}
}实战调试场景
upstream backend {
server 10.0.1.1:8080;
server 10.0.1.2:8080;
}
location /api/ {
proxy_pass http://backend;
## 开启调试追踪代理问题
error_log /var/log/nginx/proxy-debug.log debug;
## 调试信息包括:
## - 上游服务器选择过程
## - 连接建立/重用详情
## - 请求/响应传输状态
## - 超时和错误处理
}SSL/TLS 连接调试
server {
listen 443 ssl;
server_name secure.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
## SSL握手过程调试
error_log /var/log/nginx/ssl-debug.log debug;
## 调试信息包括:
## - 证书验证过程
## - 密码套件协商
## - 会话恢复详情
## - 客户端认证过程
}核心转储
核心转储(Core Dump)是 进程崩溃时的内存快照,包含崩溃瞬间的程序状态、变量值、堆栈信息等,是诊断复杂崩溃问题的关键工具。
## 在 main 上下文中配置
worker_rlimit_core 500m; ## 🔧 每个worker进程核心文件大小限制
worker_rlimit_nofile 65535; ## 📁 每个worker进程文件描述符限制
working_directory /var/dump/nginx; ## 💾 核心转储文件存储目录