温馨提示×

CentOS Nginx日志切割技巧有哪些

小樊
33
2025-12-29 09:37:42
栏目: 智能运维

CentOS 上 Nginx 日志切割实用技巧

一 推荐做法 Logrotate 系统级方案

  • 创建或编辑配置文件:/etc/logrotate.d/nginx,适配常见安装路径(如 /var/log/nginx//usr/local/nginx/logs/)。
  • 示例配置(按天切割、保留 7 天、压缩归档、切割后通知 Nginx 重新打开日志):
/var/log/nginx/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 0640 nginx nginx
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}
  • 测试与验证:
    • 调试模式:logrotate -d /etc/logrotate.d/nginx
    • 强制执行:logrotate -vf /etc/logrotate.d/nginx
    • 查看是否生成类似 access.log-YYYYMMDD.gz 的归档,且当前 access.log 已被重新创建并可写。
  • 说明:
    • postrotate + kill -USR1 是关键,用于在不重启 Nginx 的情况下切换到新日志文件。
    • create 0640 nginx nginx 中的用户/组需与 Nginx 运行身份一致,避免写入失败。
    • 系统通常通过 /etc/cron.daily/logrotate 每日触发,无需额外定时任务。

二 备选方案 Shell 脚本 + Cron

  • 适用场景:需要高度定制、非标准路径、或容器内外统一管理日志时。
  • 示例脚本(按天切割并保留 N 天):
#!/bin/bash
LOGS_PATH="$1"
DAYS="$2"
DATE=$(date -d "yesterday" +%Y%m%d)

cd "$LOGS_PATH" || exit 1
[ -f access.log ] && mv access.log access_${DATE}.log
[ -f error.log  ] && mv error.log  error_${DATE}.log

# 通知 Nginx 重新打开日志
if [ -f /var/run/nginx.pid ]; then
    kill -USR1 $(cat /var/run/nginx.pid)
fi

# 清理 N 天前日志(按需调整)
find . -mtime +${DAYS} -name "*.log" -delete
  • 赋权与定时任务:
    • 赋权:chmod +x /opt/scripts/cut_nginx_log.sh
    • 定时:每天 00:00 执行
      • 0 0 * * * /opt/scripts/cut_nginx_log.sh /var/log/nginx 120
  • 要点:
    • 切割后必须执行 kill -USR1,否则 Nginx 会继续写入已被重命名的旧文件。
    • 脚本与日志目录权限需匹配 Nginx 运行用户。

三 Docker 与容器场景

  • 容器内常见现象:镜像通常未安装或未启用 logrotate,导致日志无限增长。
  • 两种处理方式:
    • 利用宿主机 logrotate 管理容器日志
      • 将容器内日志目录挂载到宿主机(如 -v /opt/common/nginx/logs:/var/log/nginx)。
      • 在宿主机创建 /etc/logrotate.d/nginx,对挂载目录轮转,并在 postrotate 中向容器内 Nginx 发送 USR1(可通过 docker exec 执行)。
    • 在容器内使用“按日期命名”的访问日志
      • nginx.conf 中使用 map 生成日期后缀:
map $time_iso8601 $logdate {
    default 'date-not-found';
    '~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
}
access_log /var/log/nginx/access-$logdate.log main;
- 注意:需确保日志目录对 **nginx** 用户可写,并另行清理历史日志。 

四 高级策略与实用参数

  • 按大小切割(突发流量、防止单文件过大):
/var/log/nginx/*.log {
    size 100M
    rotate 10
    compress
    missingok
    notifempty
    create 0640 nginx nginx
    sharedscripts
    postrotate
        kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}
  • 按月切割(大流量归档):
/usr/local/nginx/logs/*.log {
    monthly
    rotate 24
    compress
    missingok
    notifempty
    create 0640 nginx nginx
    sharedscripts
    postrotate
        kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)
    endscript
}
  • 按小时切割(精细分析需求):
/var/log/nginx/*.log {
    hourly
    rotate 168   # 保留 7 天
    compress
    missingok
    notifempty
    create 0640 nginx nginx
    sharedscripts
    postrotate
        kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}
  • 常用参数速查:
    • daily/weekly/monthly/hourly:切割频率
    • size N:达到 N 即切割(可与时间频率叠加)
    • rotate N:保留 N 个归档
    • compress/delaycompress:压缩旧日志(delaycompress 常用于避免压缩最新一份)
    • missingok/notifempty:容错与空文件处理
    • create perms owner:group:切割后新文件权限与属主
    • dateext:使用日期作为后缀(如 access.log-20250405.gz)
    • copytruncate:复制后截断原文件(无需 USR1,但在高并发下可能丢少量日志,优先使用 USR1)

五 验证 排错与运维建议

  • 验证与排错
    • 调试:logrotate -d /etc/logrotate.d/nginx;强制:logrotate -vf /etc/logrotate.d/nginx
    • 检查归档是否生成、当前日志是否可写、权限是否正确(如 0640 nginx nginx)。
    • 若使用脚本,确认 kill -USR1 已执行且 Nginx 进程存在(检查 /var/run/nginx.pid)。
  • 常见问题
    • 权限/属主错误:Nginx 无法写入新日志,修正 create 参数与目录权限。
    • SELinux:启用时设置正确上下文,例如 chcon -R -t httpd_log_t /var/log/nginx
    • 容器环境:容器内无 logrotate 时,使用宿主机 logrotate 或“按日期命名”方案。
    • 脚本换行符:Windows 编辑导致 ^M,可用 dos2unixvi :set ff=unix 修正。
  • 运维建议
    • 中小站点:daily + rotate 7~30 + compress 足够;大流量叠加 size 条件。
    • 合规归档:按月/年切割并长期保留,结合对象存储或集中式日志平台(如 ELK/Splunk)。
    • 监控告警:监控 /var/log 使用率,超过阈值(如 80%)及时告警与清理。

0