Nginx 1.7.1+ 可原生通过 syslog: 协议直连远程 Syslog 服务器,需关闭本地日志、禁用 buffer/flush、正确配置 server/facility/tag/severity 等参数,并推荐生产环境使用 TCP 协议提升可靠性。

直接用 syslog: 协议就行,Nginx 1.7.1+ 原生支持,不用装模块、不走文件中转,但必须关掉本地日志、选对协议、配准远端接收规则,否则日志会静默丢失。
确认 Nginx 版本并禁用本地日志
低于 1.7.1 的 Nginx 不支持 syslog: 协议,nginx -v 必须看到 ≥1.7.1。旧版本强行配置只会忽略或报错。
- 注释或删除所有形如
access_log /var/log/nginx/access.log的行 - 显式关闭:写
access_log off;和error_log /dev/null error;(1.11.6+ 才稳定支持error_log syslog:,低版本建议先关掉) - 别留空的
access_log指令——Nginx 会回退到默认路径,导致双写
配置 syslog: 目标地址与关键参数
syslog: 地址不是 URL,是带逗号分隔参数的字符串,任意拼写错误(比如少个 = 或多空格)都会让整个指令失效,且 nginx -t 不报错。
- UDP 示例:
access_log syslog:server=192.168.10.50:514,facility=local7,tag=nginx_access,severity=info main; - TCP 更可靠,必须加
tcp://前缀:access_log syslog:server=tcp://192.168.10.50:601,facility=local7,tag=nginx_access,severity=info main; -
facility要和远端 rsyslog 配置一致(比如local7.* /var/log/nginx.log),否则日志被丢弃 -
tag会变成 syslog 报文里的PROGRAMNAME字段,Logstash 过滤时靠它识别来源,不能含空格或特殊字符
定义兼容 syslog 的 log_format
默认 combined 格式含双引号嵌套、空格不规整,rsyslog 或 Logstash 解析时容易截断或字段错位。
- 在
http块里定义精简格式:log_format syslog_fmt '$remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent "$http_referer" "$http_user_agent"'; - 避免变量返回空值导致 JSON 不合法(比如
$upstream_response_time在直连场景下为空) - 如果下游是 ELK,推荐用 JSON 格式:
log_format json_log '{"@timestamp":"$time_iso8601","clientip":"$remote_addr","status":$status,"uri":"$request_uri"}';,注意数值字段不加引号
验证链路是否真正通了
配置 reload 后没日志,90% 是卡在三处:本机没发出、网络不通、远端没监听。不要只看 Nginx error_log。
- 本机发没发出:
tcpdump -i any port 514 or port 601 -c 5,看到包飞出去才算生效 - 网络通不通:
nc -zv 192.168.10.50 601(TCP)或echo "test" | nc -u -w1 192.168.10.50 514(UDP) - 远端收不收:
ss -tuln | grep ':601'看有没有0.0.0.0:601;若只有127.0.0.1:601,说明只监听本地,收不到外网日志 - rsyslog 必须加载对应模块:
$ModLoad imtcp+$InputTCPServerRun 601,缺一不可
最容易被忽略的是:UDP 默认无重传、无连接确认,防火墙或中间设备丢包时完全无声;TCP 虽稳,但远端没开 imtcp 模块时,Nginx worker 会卡住写日志,拖慢请求响应。


















