access_log与error_log详解、日志切割、日志分析
日志管理是Nginx运维中的重要环节,合理的日志配置可以帮助我们监控服务状态、排查问题、分析性能。本课程将深入讲解Nginx的日志系统,包括访问日志、错误日志的配置、格式定制、日志切割和分析等实用技能。
Nginx主要有两种类型的日志:
客户端请求 → Nginx处理 → 记录访问日志
↓
处理过程中 → 记录错误日志(如有错误)
# 基本语法
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
# 关闭访问日志
access_log off;
# 示例:默认配置
access_log /var/log/nginx/access.log;
Nginx支持自定义日志格式,使用log_format指令:
# 定义日志格式
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;
| 变量 | 说明 | 示例 |
|---|---|---|
$remote_addr |
客户端IP地址 | 192.168.1.100 |
$remote_user |
客户端用户名(HTTP认证) | admin |
$time_local |
访问时间 | 25/Dec/2023:10:30:22 +0800 |
$request |
请求行 | GET /index.html HTTP/1.1 |
$status |
响应状态码 | 200 |
$body_bytes_sent |
发送给客户端的字节数 | 1024 |
$http_referer |
来源页面 | http://example.com |
$http_user_agent |
用户代理 | Mozilla/5.0... |
$http_x_forwarded_for |
代理服务器IP | 192.168.1.1 |
# 条件日志记录
map $status $loggable {
~^[23] 0; # 2xx和3xx状态码不记录
default 1; # 其他状态码记录
}
access_log /var/log/nginx/access.log main if=$loggable;
# 缓冲日志写入(提升性能)
access_log /var/log/nginx/access.log main buffer=32k flush=5m;
# 压缩日志
access_log /var/log/nginx/access.log main gzip=1 buffer=32k;
# 基本语法
error_log file [level];
# 示例:不同级别的错误日志
error_log /var/log/nginx/error.log warn; # 记录警告及以上级别
error_log /var/log/nginx/error.log error; # 记录错误及以上级别
error_log /var/log/nginx/error.log info; # 记录信息及以上级别
| 级别 | 说明 | 记录内容 |
|---|---|---|
debug |
调试信息 | 详细的调试信息 |
info |
一般信息 | 一般运行信息 |
notice |
通知信息 | 重要通知 |
warn |
警告信息 | 警告信息(默认) |
error |
错误信息 | 错误信息 |
crit |
严重错误 | 严重错误 |
alert |
警报信息 | 需要立即处理的问题 |
emerg |
紧急信息 | 系统不可用 |
创建logrotate配置文件:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily # 每天轮转
missingok # 如果日志文件丢失,继续处理下一个
rotate 52 # 保留52个备份文件
compress # 压缩旧日志
delaycompress # 延迟压缩(下一个轮转时压缩)
notifempty # 如果日志为空,不轮转
create 0640 www-data adm # 创建新文件时的权限和所有者
sharedscripts # 在所有日志处理完后执行脚本
postrotate
# 向Nginx发送USR1信号,重新打开日志文件
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
# 重命名当前日志文件
mv /var/log/nginx/access.log /var/log/nginx/access.log.$(date +%Y%m%d)
mv /var/log/nginx/error.log /var/log/nginx/error.log.$(date +%Y%m%d)
# 重新打开日志文件
nginx -s reopen
# 或者发送USR1信号
kill -USR1 $(cat /var/run/nginx.pid)
# 查看实时访问日志
tail -f /var/log/nginx/access.log
# 统计访问量最多的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
# 统计最常访问的URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 查看特定时间段的日志
grep "25/Dec/2023:10" /var/log/nginx/access.log
# 统计带宽使用
awk '{sum += $10} END {print sum/1024/1024 " MB"}' /var/log/nginx/access.log
# 安装GoAccess
sudo apt install goaccess
# 实时分析访问日志
goaccess /var/log/nginx/access.log -c
# 生成HTML报告
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED
# 实时监控模式
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --real-time-html --daemonize
# 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" '
'"$request_time" "$upstream_response_time"';
log_format json '{"@timestamp":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"request_time":"$request_time",'
'"upstream_response_time":"$upstream_response_time"}';
# 访问日志配置
access_log /var/log/nginx/access.log main buffer=64k flush=5m;
access_log /var/log/nginx/access.json json;
# 错误日志配置
error_log /var/log/nginx/error.log warn;
server {
listen 80;
server_name example.com;
# 为特定location关闭访问日志
location /health {
access_log off;
return 200 "healthy\n";
}
location / {
root /var/www/html;
index index.html;
}
}
}
通过本课的学习,你应该已经掌握了:
任务1:配置自定义日志格式,包含请求时间和上游响应时间
任务2:设置logrotate实现自动日志切割
任务3:使用GoAccess生成可视化访问报告
任务4:分析日志文件,找出访问量最大的IP和URL