Nginx使用logrotate实现日志轮转与保留策略!

 更新时间:2026年04月30日 09:26:32   作者:遇见火星  
本文介绍了使用logrotate工具实现Nginx日志按天切割的方法,解决日志文件过大导致的管理问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

使用 Nginx 作为 Web 服务器或反向代理时,访问日志(access.log)和错误日志(error.log)是非常重要的调试和分析工具。但随着运行时间的增加,access.log 文件会变得越来越大,不仅占用磁盘空间,也会影响日志的查询效率。本文将介绍如何通过日志轮转来实现 Nginx 的日志按天切割,并设置日志的保留时间,以优化日志管理。

一、问题背景

默认情况下,Nginx 将所有访问记录写入一个日志文件中(如 /var/log/nginx/access.log)。随着时间推移:

  • 文件体积过大:日志文件可能达到GB甚至TB级别,打开和查询效率极低
  • 磁盘空间占用:未经压缩的日志文件会快速消耗磁盘空间
  • 管理困难:单文件难以进行历史分析、归档和自动化处理
  • 故障排查低效:在海量日志中定位问题如同大海捞针

为了解决这个问题,我们需要对日志进行定期切割,并保留一定时间的历史日志。

二、宿主机安装方案:使用logrotate实现日志轮转

Linux 系统中广泛使用的日志轮转工具是 logrotate,它支持按天、按大小自动切割日志,并可设置保留份数。

步骤1:确认是否安装了 logrotate

大多数 Linux 发行版默认已安装。你可以执行以下命令检查:

which logrotate

如果未安装,可以使用包管理器安装:

# Ubuntu / Debian
sudo apt update && sudo apt install logrotate
# CentOS / RHEL
sudo yum install logrotate

步骤2:创建或修改 logrotate 配置文件

logrotate的配置文件一般位于/etc/logrotate.d下面,我们可以新建一个nginx的配置文件来管理日志,注意改为自己的nginx日志目录。

sudo bash -c 'cat > /etc/logrotate.d/nginx << EOF
/var/log/nginx/*.log 
{
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    sharedscripts
    postrotate
        [ -f /run/nginx.pid ] && kill -USR1 \$(cat /run/nginx.pid)
    endscript
}
EOF'

参数说明:

参数说明
daily

每天轮换一次

missingok

如果日志文件不存在,不报错

rotate 30

保留最近 30 天的日志

compress

压缩旧日志文件(生成 .gz 文件)

delaycompress

推迟压缩到下一轮,避免刚轮换就压缩

notifempty

如果日志为空,不进行轮换

sharedscripts

所有日志共用 postrotate 脚本

postrotate ... endscript

切割完成后向Nginx主进程发送USR1信号使其重新打开日志文件

步骤3:测试 logrotate 配置

为了避免配置错误导致服务异常,测试配置,其中 -d 表示 debug 模式,只输出日志不会真正执行操作:

sudo logrotate -d /etc/logrotate.d/nginx

如果你想强制执行一次日志轮换,可以去掉 -d:

sudo logrotate -f /etc/logrotate.d/nginx

三、Docker环境方案:容器化Nginx日志轮转

如果我们使用了docker安装的 Nginx,上面这段脚本可能 不会生效,原因如下:

  • /run/nginx.pid 这个文件在容器中可能存在,也可能不存在;
  • 即使存在,你在宿主机上运行 kill -USR1 是无效的,因为目标进程在容器内部;
  • 所以你不能直接在宿主机上使用 kill 向容器内的进程发送信号。

正确做法(Docker 环境下)

你可以改用 docker exec 命令向容器内发送信号。

postrotate
    docker exec <nginx_container_name> kill -USR1 1
endscript

但是上面的脚本可能会执行失败: exec: "kill": executable file not found in $PATH,虽然docker exec your_container kill -USR1 1这是标准的向容器发送信号的方式,但容器内可能是一个极简镜像(比如基于 alpine 或 scratch),它不包含 kill 命令。

正确解决方案:改用 sh -c 直接发送信号

你可以通过在容器内运行一个 shell 命令来发送信号,而不是依赖 kill 命令本身。例如:

docker exec your_container sh -c 'kill -USR1 1'

修改后的完整的宿主机logrotate配置,注意修改日志路径:

sudo bash -c 'cat > /etc/logrotate.d/nginx << EOF
/opt/nginx/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    sharedscripts
    postrotate
        docker exec nginx sh -c "kill -USR1 1"
    endscript
}
EOF'

四、日志轮转效果验证

执行完日志轮换后,你可以在日志目录看到类似下面的文件:

/var/log/nginx/
├── access.log          # 当前活动日志
├── access.log.1        # 昨日日志(未压缩)
├── access.log.2.gz     # 前日日志(已压缩)
├── error.log
├── error.log.1
└── error.log.2.gz

压缩效果对比

  • 原始日志:2.4GB
  • 压缩后:720MB(节省70%空间)
  • 30天保留策略可节省数十GB磁盘空间

五、高级配置技巧

自定义日志路径

如果你希望将日志按项目或域名分类存储,可以在 Nginx 配置中指定不同的日志路径:

server {
    listen 80;
    server_name example.com;
    access_log /var/log/nginx/example.com-access.log;
    error_log /var/log/nginx/example.com-error.log;
}
server {
    listen 80;
    server_name api.example.com;
    access_log /var/log/nginx/api-access.log;
    error_log /var/log/nginx/api-error.log;
}

按日期命名的日志文件

/var/log/nginx/*.log {
    daily
    dateext                   # 使用日期后缀
    dateformat -%Y%m%d        # 日期格式
    rotate 90
    ...
}

生成文件名示例:access.log-20240623.gz

日志分析与监控集成

postrotate
    # 发送通知到监控系统
    curl -X POST https://monitor.example.com/logrotate -d 'server=web01'
    
    # 触发日志分析任务
    /opt/scripts/log-analysis.sh &amp;
endscript

六、常见问题

日志切割后,Nginx 是否需要重启?

不需要。只需发送 USR1 信号给 Nginx 进程,使其重新打开日志文件即可。

kill -USR1 $(cat /run/nginx.pid)

报错unknown user 'www-data'

/etc/logrotate.d/nginx 配置文件使用了一个系统中 不存在的用户:www-data,通常是这一行引起的错误:

create 0640 www-data adm
  • create 表示在日志轮换后自动创建新的日志文件。
  • www-data 是通常用于 Nginx 进程运行的用户,在 Ubuntu/Debian 系统上存在。

解决方法

将 www-data 替换为你的系统中存在的用户和组,比如 nginx(常见于 CentOS/RHEL):

create 0640 nginx adm

或者如果你不确定用哪个用户,可以先注释掉这一行,让系统使用默认权限创建日志文件:

# create 0640 www-data adm

postrotate脚本的作用

 postrotate
      [ -f /run/nginx.pid ] &amp;&amp; kill -USR1 \$(cat /run/nginx.pid)
  endscript
  • postrotate ... endscript:是一个脚本块,在 logrotate 完成日志切割之后自动运行。通常用于通知服务重新加载配置或重新打开日志文件。
  • [ -f /run/nginx.pid ]:如果 /run/nginx.pid 文件存在,就继续执行后面的命令
  • kill -USR1 $(cat /run/nginx.pid):获取 Nginx 主进程的 PID(进程号),向 Nginx 发送一个 USR1 信号

Nginx 收到 USR1 信号后的行为是:重新打开日志文件(包括 access.log 和 error.log)。这样做的目的是为了让 Nginx 开始写入新的日志文件(比如切割后的 access.log),而不是继续写入旧的被重命名的日志文件(如 access.log.1)。

总结

通过logrotate实现Nginx日志轮转:

宿主机方案:标准配置+USR1信号通知

Docker方案:docker exec穿透容器执行命令

核心价值

  • 节省70%磁盘空间
  • 保留30天历史日志便于审计
  • 避免单文件过大导致的性能问题

最佳实践:生产环境建议启用dateext按日期归档,并集成日志分析系统实时监控异常。

到此这篇关于Nginx使用logrotate实现日志轮转与保留策略!的文章就介绍到这了,更多相关Nginx logrotate日志轮转与保留内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Nginx配置SSL和WSS步骤介绍

    Nginx配置SSL和WSS步骤介绍

    大家好,本篇文章主要讲的是Nginx配置SSL和WSS步骤介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • Nginx session丢失问题处理解决方法

    Nginx session丢失问题处理解决方法

    这篇文章主要介绍了Nginx session丢失问题处理解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • Ubuntu 22.04.1 LTS 编译安装 nginx-1.22.1的配置过程

    Ubuntu 22.04.1 LTS 编译安装 nginx-1.22.1的配置过程

    Ubuntu安装Nginx有两种方式,一种是通过命令的方式,这种方式安装的Nginx版本低,之前漏扫扫出来Nginx版本低,需要升级所以现在用编译的方式安装版本高点的,本文介绍Ubuntu22.04.1 LTS编译安装nginx1.22.1的配置过程,本文给大家介绍的非常详细,需要的朋友参考下吧
    2024-01-01
  • Nginx用户认证配置方法详解(域名/目录)

    Nginx用户认证配置方法详解(域名/目录)

    Nginx超级强大它可以单独为一个域名设置用户认证,方法也很简单我们只要生成用户认证的用户名和密码,然后再Nginx添加auth认证配置即可
    2013-08-08
  • nginx 匹配规则小总结(推荐)

    nginx 匹配规则小总结(推荐)

    这篇文章主要介绍了nginx 匹配规则小总结及nginx配置proxy_pass路径带/问题,需要的朋友可以参考下
    2018-07-07
  • nginx 访问限制与访问控制的实现

    nginx 访问限制与访问控制的实现

    访问控制要做的事情是控制客户端的资源访问权限,本文主要介绍了nginx 访问限制与访问控制的实现,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • Nginx中server_name指令的参数详解

    Nginx中server_name指令的参数详解

    这篇文章主要介绍了Nginx中server_name指令的参数详解,Nginx中的server_name指令主要用于配置基于名称的虚拟主机,server_name指令一项很实用的功能便是可以在使用正则表达式的捕获功能,这样可以尽量精简配置文件,需要的朋友可以参考下
    2023-08-08
  • 讨论nginx location 顺序问题

    讨论nginx location 顺序问题

    在有一次配置时发现,请求 uri 明明是符合了前缀匹配 ^~ 规则,但 nginx 却没有使用,这让我对上述结论产生了疑惑。后续通过调研、实践后发现,上述结论可以说对,但也不对,是不是更疑惑了?没关系,看完这篇文章你就知道我为什么会这样说了
    2022-05-05
  • 实例详解SpringBoot+nginx实现资源上传功能

    实例详解SpringBoot+nginx实现资源上传功能

    这篇文章主要介绍了SpringBoot+nginx实现资源上传功能,由于小编最近在使用nginx放置静态资源问题,遇到很多干货,特此分享到脚本之家平台,供大家参考,需要的朋友可以参考下
    2019-10-10
  • nginx中的健康检查方案

    nginx中的健康检查方案

    这篇文章主要介绍了nginx中的健康检查方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01

最新评论