<返回目录     Powered by claud/xia兄

第10课: Nginx日志管理

access_log与error_log详解、日志切割、日志分析

课程简介

日志管理是Nginx运维中的重要环节,合理的日志配置可以帮助我们监控服务状态、排查问题、分析性能。本课程将深入讲解Nginx的日志系统,包括访问日志、错误日志的配置、格式定制、日志切割和分析等实用技能。

Nginx日志类型

Nginx主要有两种类型的日志:

日志处理流程

客户端请求 → Nginx处理 → 记录访问日志
                    ↓
                处理过程中 → 记录错误日志(如有错误)
            

访问日志(access_log)配置

基本配置语法

# 基本语法
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)配置

基本配置语法

# 基本语法
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(推荐)

创建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进行可视化分析

# 安装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