在 Linux VPS 上配置 logrotate 管理日志文件

运行 Web 服务器、数据库和应用程序的 VPS 会持续积累日志文件。当磁盘填满时,您的网站会崩溃,数据库停止写入新数据,整个服务器可能无法响应请求。Logrotate 是 Linux 系统上的标准日志管理工具,可以按计划自动轮换、压缩和删除旧日志,是每台 VPS 服务器的必配基础工具。

许多系统管理员忽视了日志管理,直到磁盘空间耗尽才追悔莫及。Nginx、MySQL、应用程序错误日志在高流量服务器上每天可产生数 GB 数据。没有轮换策略,这些文件会无限增长,最终在最不合时宜的时刻让整台服务器停摆。本指南帮助您为所有主要服务配置 Logrotate,并介绍如何管理 systemd 日志,确保磁盘空间始终处于可控状态。

Logrotate 是什么?为什么需要它?

Logrotate 是一个自动化的日志管理工具,可以定期重命名旧日志文件、创建新日志文件、对旧日志进行 gzip 或 bzip2 压缩、最后删除超过保留期限的文件。这一切都通过 cron 任务完全自动化进行,无需手动干预。

想象一个场景:您的 Nginx 服务器每天产生 1GB 的访问日志和 500MB 的错误日志。不经过处理,一个月就会产生 45GB 的日志数据。如果您的 VPS 只有 100GB 存储,不到 2 个月就会填满。Logrotate 会自动:

通过 Logrotate,同样的 45GB 月度日志数据可以被压缩到只需 8-10GB 存储空间,并且可以根据您的需要自动删除 30 天前的日志。

Logrotate 的关键配置文件和位置

Logrotate 的配置存储在几个关键位置:

/etc/logrotate.conf          # 全局默认配置
/etc/logrotate.d/            # 按服务分类的配置目录
/var/lib/logrotate/status    # 轮换历史和状态文件

主配置文件 /etc/logrotate.conf 定义了所有日志的全局默认值,而 /etc/logrotate.d/ 目录中的文件允许为特定服务(如 Nginx、MySQL)定义自定义规则。当您创建新的轮换规则时,通常会在 /etc/logrotate.d/ 中创建一个新文件。

您可以查看当前配置:

cat /etc/logrotate.conf
# 查看 Nginx 的特定配置
cat /etc/logrotate.d/nginx

Logrotate 常见选项详解

了解各个配置选项的含义是正确设置 Logrotate 的关键:

Nginx 日志轮换配置

Nginx 通常已经在 Ubuntu/Debian 系统中预配置了 Logrotate。查看现有配置:

cat /etc/logrotate.d/nginx

标准的 Nginx 配置通常看起来像这样:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

这个配置的含义:

这种配置对高流量网站至关重要。USR1 信号允许在不中断服务的情况下进行日志切换,避免请求丢失。

MySQL 和 MariaDB 日志轮换

MySQL 的慢查询日志和错误日志往往会占用大量磁盘空间。为 MySQL 创建自定义轮换规则:

sudo nano /etc/logrotate.d/mysql

添加以下内容:

/var/log/mysql/mysql-slow.log
/var/log/mysql/error.log {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    notifempty
    create 640 mysql adm
    postrotate
        mysqladmin -u root -p'YOUR_ROOT_PASSWORD' flush-logs 2>/dev/null
    endscript
}

配置说明:

确保将 YOUR_ROOT_PASSWORD 替换为实际的 MySQL root 密码。为了更安全,您也可以将凭据放在 ~/.my.cnf 文件中。

自定义应用程序日志轮换

对于您开发或运行的自定义应用程序,可能需要创建特定的轮换规则:

sudo nano /etc/logrotate.d/myapp

示例配置:

/var/www/myapp/logs/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    su www-data www-data
}

这个配置:

copytruncate 选项适合那些不支持优雅日志重新加载的应用程序。它会复制日志文件的内容到存档,然后清空原文件,应用程序继续向空文件写入。这种方式在复制过程中可能丢失少量日志,但对大多数应用来说可以接受。

基于文件大小的日志轮换

有时候按日期轮换不适合所有场景。对于产生日志非常快的应用,可以改用基于大小的轮换:

/var/log/myapp/access.log {
    size 100M
    rotate 5
    compress
    missingok
    copytruncate
}

这个配置在以下情况下很有用:

当日志文件达到 100MB 时,无论当前日期如何,都会立即进行轮换。这种方式允许更灵活的日志管理。

测试和调试 Logrotate 配置

在部署新配置之前,始终要先进行测试:

# 干运行 - 显示将要执行的操作,不实际修改文件
sudo logrotate -d /etc/logrotate.conf

# 强制执行轮换(用于测试)
sudo logrotate -f /etc/logrotate.d/nginx

# 详细输出模式
sudo logrotate -v /etc/logrotate.conf

# 查看轮换历史记录
sudo cat /var/lib/logrotate/status

特别是 -d(干运行)选项非常重要。它会显示 Logrotate 如何解释您的配置规则以及会执行哪些操作,但不会实际修改任何文件。这样您可以在应用到生产系统之前验证配置的正确性。

/var/lib/logrotate/status 文件记录了每个日志文件上次轮换的时间戳。如果您想强制立即进行轮换(即使不满足时间条件),可以编辑此文件中的时间戳或使用 -f 标志。

最佳实践提示:每次创建或修改 Logrotate 配置时,始终先运行 sudo logrotate -d /etc/logrotate.d/yourconfig 进行验证。这可以在出现问题前发现 99% 的配置错误。

管理 systemd 日志和 Journal 日志

现代 Linux 系统使用 systemd 的 Journal 日志系统,它可以占用大量磁盘空间。特别是在运行许多服务或有大量日志输出的系统上,Journal 日志可以快速填满磁盘。

检查 Journal 日志占用的磁盘空间:

journalctl --disk-usage

清理 Journal 日志的方法:

# 删除 30 天以前的日志
sudo journalctl --vacuum-time=30d

# 限制日志总大小为 500MB
sudo journalctl --vacuum-size=500M

# 删除所有日志(谨慎使用)
sudo journalctl --flush --vacuum-size=1K

为了设置永久的日志保留策略,编辑 Journal 配置文件:

sudo nano /etc/systemd/journald.conf

添加或修改以下参数:

SystemMaxUse=500M
MaxRetentionSec=30day
MaxFileSec=1week

然后重启 Journal 服务:

sudo systemctl restart systemd-journald

这些参数的含义:

诊断磁盘空间问题

当磁盘接近满容时,您需要快速诊断是哪些文件或目录占用了大量空间:

# 查看磁盘使用总情况
df -h

# 查看 /var/log 中各目录的大小(按降序排列)
du -sh /var/log/* | sort -rh | head -20

# 查看 /var/log 中所有超过 100MB 的文件
find /var/log -type f -size +100M -exec ls -lh {} \;

# 查看整个文件系统中哪些目录占用最多空间
du -sh /* | sort -rh | head -10

这些命令可以帮助您快速定位问题。例如,如果您发现 /var/log/mysql 占用 80GB,那么立即配置 MySQL 的日志轮换就很重要。

Logrotate 常见问题和解决方案

日志文件仍在增长,轮换未执行

可能的原因和解决方案:

轮换后应用程序停止写入日志

这通常是因为应用程序没有重新打开日志文件:

轮换脚本权限错误

如果出现权限拒绝错误:

完整配置示例:生产环境最佳实践

这是一个针对典型 LAMP/LEMP 堆栈的完整配置示例:

# /etc/logrotate.d/webserver-complete
/var/log/nginx/*.log
/var/log/apache2/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 640 www-data adm
    sharedscripts
    postrotate
        systemctl reload nginx > /dev/null 2>&1 || true
        systemctl reload apache2 > /dev/null 2>&1 || true
    endscript
}

/var/log/mysql/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 640 mysql adm
    postrotate
        mysqladmin flush-logs > /dev/null 2>&1 || true
    endscript
}

/var/www/*/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    copytruncate
    su www-data www-data
}

这个配置为您的整个 VPS 提供了全面的日志管理。根据您的具体情况调整参数:

需要具有完全控制的 Linux VPS?

AsiaGB VPS 运行 Ubuntu/Debian,具有 root 访问权限 — 完全按照您的需要管理日志、cron 和服务。我们的 VPS 配有 99% 的正常运行时间 SLA 和 SSD 存储,起价仅 500 泰铢/月。

查看VPS套餐

查看泰国VPS主机全部套餐 →