- Add Go module initialization (go 1.26) - Add comprehensive NGINX documentation covering: - Overview, installation, HTTP core module - Proxy/load balancing, SSL/TLS, URL rewrite - Compression/caching, logging/monitoring - Security, TCP/UDP stream, mail proxy - Performance tuning, Git commit guide - Add standard Go .gitignore Co-Authored-By: Claude <noreply@anthropic.com>
9.8 KiB
9.8 KiB
NGINX 日志与监控指南
1. 访问日志配置
基础配置
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
}
日志格式定义
log_format name [escape=default|json|none] string ...;
转义选项:
default:转义"、\、控制字符为\xXXjson:按 JSON 标准转义none:禁用转义
预定义格式
combined(默认):
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
自定义格式
# JSON 格式
log_format json_combined escape=json
'{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
# 详细性能日志
log_format performance
'$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 cache '$remote_addr - $remote_user [$time_local] '
'"$request" $status $upstream_cache_status';
2. access_log 指令
语法
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
配置示例
http {
# 基础配置
access_log /var/log/nginx/access.log main;
# 带缓冲
access_log /var/log/nginx/access.log main buffer=32k;
# 带压缩
access_log /var/log/nginx/access.log.gz main gzip=6 buffer=32k flush=5m;
# 条件日志
map $status $loggable {
~^[23] 0;
default 1;
}
access_log /var/log/nginx/access.log main if=$loggable;
# 多日志输出
access_log /var/log/nginx/access.log main;
access_log /var/log/nginx/access_json.log json_combined;
# Syslog
access_log syslog:server=192.168.1.1:514,facility=local7,tag=nginx main;
# 禁用日志
location /health {
access_log off;
}
}
变量路径
server {
root /var/www/$host;
access_log /var/log/nginx/$host/access.log;
# 缓存变量路径的日志文件描述符
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
}
3. 错误日志配置
语法
error_log file [level];
error_log syslog:server=address [level];
日志级别
| 级别 | 说明 | 使用场景 |
|---|---|---|
debug |
调试信息 | 开发调试 |
info |
信息 | 一般信息 |
notice |
通知 | 重要事件 |
warn |
警告 | 潜在问题 |
error |
错误 | 操作错误 |
crit |
严重 | 严重错误 |
alert |
警报 | 需立即处理 |
emerg |
紧急 | 系统不可用 |
配置示例
error_log /var/log/nginx/error.log warn;
# Server 级别覆盖
server {
error_log /var/log/nginx/example.com/error.log notice;
}
# 仅记录特定客户端的调试日志
events {
debug_connection 192.168.1.1;
debug_connection 192.168.10.0/24;
}
4. 调试日志
启用调试
编译时:
./configure --with-debug
运行时:
error_log /var/log/nginx/debug.log debug;
验证调试支持
nginx -V | grep -- --with-debug
内存缓冲调试
error_log memory:32m debug;
提取日志:
# GDB
gdb -p $(cat /var/run/nginx.pid)
set $log = ngx_cycle->log
while $log->writer != ngx_log_memory_writer
set $log = $log->next
end
set $buf = (ngx_log_memory_buf_t *) $log->wdata
dump binary memory debug.log $buf->start $buf->end
# LLDB
lldb -p $(cat /var/run/nginx.pid)
expr ngx_log_t *$log = ngx_cycle->log
expr while ($log->writer != ngx_log_memory_writer) { $log = $log->next; }
expr ngx_log_memory_buf_t *$buf = (ngx_log_memory_buf_t *) $log->wdata
memory read --force --outfile debug.log --binary $buf->start $buf->end
5. 条件日志
基于状态码
map $status $loggable {
~^[23] 0; # 2xx, 3xx 不记录
default 1;
}
access_log /var/log/nginx/access.log main if=$loggable;
基于请求路径
map $uri $loggable {
/health 0;
/favicon.ico 0;
~^/static/ 0;
default 1;
}
access_log /var/log/nginx/access.log main if=$loggable;
基于响应时间
map $request_time $slow_request {
default 0;
"~^[0-9]+\.[5-9]" 1; # 大于 0.5 秒
}
access_log /var/log/nginx/slow.log main if=$slow_request;
6. 日志轮转
logrotate 配置
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 nginx adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
手动轮转
# 重命名日志文件
mv /var/log/nginx/access.log /var/log/nginx/access.log.1
# 重新打开日志文件
nginx -s reopen
# 或
kill -USR1 $(cat /var/run/nginx.pid)
# 压缩旧日志
gzip /var/log/nginx/access.log.1
7. 内置变量
请求相关
| 变量 | 说明 |
|---|---|
$request |
完整原始请求行 |
$request_method |
请求方法 |
$request_uri |
完整请求 URI(含参数) |
$uri |
规范化后的 URI |
$args |
查询参数 |
$arg_name |
指定参数值 |
$request_body |
请求体内容 |
$request_length |
请求长度(含行、头、体) |
$request_time |
请求处理时间(秒,毫秒精度) |
客户端相关
| 变量 | 说明 |
|---|---|
$remote_addr |
客户端 IP |
$remote_port |
客户端端口 |
$remote_user |
认证用户名 |
$http_user_agent |
User-Agent |
$http_referer |
Referer |
响应相关
| 变量 | 说明 |
|---|---|
$status |
响应状态码 |
$body_bytes_sent |
发送的字节数(不含头) |
$bytes_sent |
发送的总字节数 |
$sent_http_name |
响应头字段 |
上游相关
| 变量 | 说明 |
|---|---|
$upstream_addr |
上游服务器地址 |
$upstream_response_time |
上游响应时间 |
$upstream_connect_time |
连接上游时间 |
$upstream_header_time |
接收响应头时间 |
$upstream_cache_status |
缓存状态 |
时间相关
| 变量 | 说明 |
|---|---|
$time_local |
本地时间 |
$time_iso8601 |
ISO 8601 格式时间 |
$msec |
当前时间(秒,毫秒精度) |
8. 状态监控
stub_status
location /nginx_status {
stub_status;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
输出示例:
Active connections: 10
server accepts handled requests
100 100 200
Reading: 0 Writing: 1 Waiting: 9
指标说明:
Active connections:当前活跃连接数accepts:接受的连接总数handled:处理的连接总数requests:请求总数Reading:正在读取请求的连接数Writing:正在写入响应的连接数Waiting:等待下一个请求的连接数(keepalive)
9. 监控集成
Prometheus Exporter
使用 nginx-prometheus-exporter:
# docker-compose.yml
version: '3'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
nginx-exporter:
image: nginx/nginx-prometheus-exporter:latest
ports:
- "9113:9113"
command:
- -nginx.scrape-uri=http://nginx/nginx_status
ELK 集成
log_format json_log escape=json
'{'
'"@timestamp":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"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"'
'}';
access_log /var/log/nginx/access.log json_log;
10. 日志分析
常用分析命令
# 请求数统计
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 状态码统计
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 响应时间分析
awk '{print $NF}' /var/log/nginx/access.log | awk '{sum+=$1; count++} END {print "avg:", sum/count, "total:", count}'
# 慢请求
awk '$NF > 1 {print}' /var/log/nginx/access.log
# 404 请求
awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 每小时请求量
awk '{print substr($4, 14, 2)}' /var/log/nginx/access.log | sort | uniq -c
GoAccess 实时分析
# 安装
apt install goaccess
# 实时分析
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --real-time-html --log-format=COMBINED
11. 日志最佳实践
日志级别建议
| 环境 | 错误日志级别 | 访问日志 |
|---|---|---|
| 开发 | debug | 详细 |
| 测试 | notice | 标准 |
| 生产 | warn | 条件记录 |
性能考虑
# 高流量场景
location / {
access_log off; # 禁用访问日志
# 或使用缓冲
access_log /var/log/nginx/access.log main buffer=64k flush=5m;
}
# 静态资源不记录
location ~* \.(css|js|png|jpg|gif|ico)$ {
access_log off;
}
# 健康检查不记录
location /health {
access_log off;
return 200 "OK";
}