Linux 日志管理与 logrotate 配置完全指南

Linux 日志管理与 logrotate 配置完全指南

Someone Lv5

日志是 Linux 系统的”黑匣子”,记录了系统运行、应用行为和错误事件的详细信息。合理的日志管理不仅能帮助你快速定位问题,还能有效控制磁盘空间,避免日志文件无限膨胀导致磁盘爆满。本文将全面介绍 Linux 日志管理的基础知识、日志系统的演化,以及 logrotate 工具的详细配置方法。

一、Linux 日志系统概述

1.1 日志存储位置

Linux 系统日志通常存储在 /var/log/ 目录下,常见的日志文件包括:

日志文件 用途
/var/log/syslog/var/log/messages 系统综合日志
/var/log/auth.log/var/log/secure 认证与安全日志
/var/log/kern.log 内核日志
/var/log/dmesg 内核环缓冲区消息
/var/log/boot.log 系统启动日志
/var/log/nginx/ Nginx 访问与错误日志
/var/log/mysql/ MySQL/MariaDB 日志
/var/log/redis/ Redis 日志

说明:Debian/Ubuntu 系列使用 syslogauth.log,而 RHEL/CentOS 系列使用 messagessecure

1.2 日志系统的演化

Linux 日志系统经历了三个阶段:

  1. syslogd:传统的系统日志守护进程,功能简单
  2. rsyslog:增强版 syslog,支持 TCP、TLS、数据库输出、模块化扩展(当前主流)
  3. systemd-journald:systemd 自带的日志系统,二进制格式,支持结构化元数据

目前大多数现代 Linux 发行版同时运行 rsyslog 和 systemd-journald,两者协同工作。

二、systemd-journald 的使用

2.1 基本查询

journalctl 是查看 systemd-journald 日志的核心命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看所有日志(默认显示在 pager 中)
journalctl

# 查看本次启动以来的日志
journalctl -b

# 查看上一次启动的日志
journalctl -b -1

# 查看特定 unit 的日志
journalctl -u nginx.service

# 查看指定时间范围的日志
journalctl --since "2026-06-08 00:00:00" --until "2026-06-08 23:59:59"

# 实时跟踪日志输出(类似 tail -f)
journalctl -f

# 查看内核日志
journalctl -k

# 查看指定优先级的日志(0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug)
journalctl -p err -b

2.2 日志持久化配置

默认情况下,systemd-journald 将日志存储在内存中(/run/log/journal),重启后丢失。如需持久化存储:

1
2
3
4
# 创建持久化存储目录
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

持久化配置文件 /etc/systemd/journald.conf 关键参数:

1
2
3
4
5
6
7
8
[Journal]
Storage=persistent # 持久化存储
Compress=yes # 启用压缩
Seal=yes # 启用日志密封(防篡改)
SystemMaxUse=1G # 日志最大占用空间
SystemMaxFileSize=100M # 单个日志文件最大大小
MaxRetentionSec=1month # 日志保留时间
ForwardToSyslog=yes # 转发到 rsyslog

三、rsyslog 配置

rsyslog 是大多数 Linux 发行版默认的日志记录守护进程。

3.1 配置文件结构

rsyslog 的配置位于 /etc/rsyslog.conf/etc/rsyslog.d/ 目录下:

1
2
3
4
5
# 查看主配置文件
cat /etc/rsyslog.conf

# 查看自定义规则
ls /etc/rsyslog.d/

3.2 配置语法

rsyslog 配置文件由选择器(selector)和动作(action)组成:

1
2
3
4
# 格式:设施.优先级    动作
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
kern.* -/var/log/kern.log
  • 设施(Facility)auth, authpriv, cron, daemon, kern, lpr, mail, news, syslog, user, uucp, local0~`local7`
  • 优先级(Priority)debug, info, notice, warning, err, crit, alert, emerg
  • 动作(Action):日志文件路径、远程服务器、数据库等

3.3 常见配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 将所有 info 及以上级别的日志记录到指定文件,排除 mail/auth/authpriv/cron
# /etc/rsyslog.d/50-default.conf
*.info;mail.none;authpriv.none;cron.none /var/log/messages

# 将特定程序日志输出到独立文件
if $programname == 'nginx' then /var/log/nginx/error.log
& stop

# 远程日志收集(服务端)
# 在 /etc/rsyslog.conf 中取消注释
module(load="imudp")
input(type="imudp" port="514")
module(load="imtcp")
input(type="imtcp" port="514")

四、logrotate 日志轮转配置

4.1 logrotate 工作原理

logrotate 是 Linux 系统自带的日志轮转工具,用于自动压缩、轮转、删除旧日志文件。它通过 cron 定时任务触发,默认每天运行一次。

logrotate 的工作流程:

  1. 根据配置文件判断是否需要轮转
  2. 将当前日志文件重命名(如 syslogsyslog.1
  3. 通知进程重新创建日志文件(通过 postrotate 脚本)
  4. 压缩旧日志(可选)
  5. 删除超过保留期限的日志

4.2 主配置文件

1
2
/etc/logrotate.conf          # 主配置文件
/etc/logrotate.d/ # 应用级配置目录

查看默认配置:

1
cat /etc/logrotate.conf

典型输出:

1
2
3
4
5
6
weekly           # 每周轮转一次
rotate 4 # 保留 4 份历史日志
create # 轮转后创建新日志文件
dateext # 使用日期作为后缀
compress # 压缩历史日志
include /etc/logrotate.d # 包含应用配置

4.3 配置指令详解

指令 说明 示例
daily / weekly / monthly 轮转周期 daily
rotate N 保留 N 份旧日志 rotate 30
size SIZE 日志达到指定大小触发轮转 size 100M
compress / nocompress 是否压缩旧日志 compress
delaycompress 延迟压缩一次(保留一个未压缩版本) delaycompress
dateext 使用日期作为后缀 dateext
dateformat -%Y%m%d 日期格式 dateformat -%Y%m%d
create [权限] [用户] [组] 轮转后创建新日志 create 640 syslog adm
missingok 日志文件不存在时不报错 missingok
notifempty 日志为空时不轮转 notifempty
sharedscripts 多个日志文件共享一个 postrotate 脚本 sharedscripts
postrotate / endscript 轮转后执行的脚本 见下方示例
prerotate / endscript 轮转前执行的脚本 见下方示例
maxage N 删除超过 N 天的日志 maxage 30
maxsize SIZE 日志超过此大小立即轮转(即使不到周期) maxsize 200M
minsize SIZE 日志超过此大小且到达周期才轮转 minsize 100M
olddir DIR 将旧日志移动到指定目录 olddir /var/log/archive

4.4 常用配置示例

Nginx 日志轮转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 $(cat /var/run/nginx.pid)
fi
endscript
}

MariaDB/MySQL 慢查询日志

1
2
3
4
5
6
7
8
9
10
11
12
13
# /etc/logrotate.d/mariadb-slow
/var/log/mysql/mariadb-slow.log {
daily
rotate 30
compress
missingok
notifempty
create 640 mysql mysql
size 500M
postrotate
mysqladmin flush-logs -u root -p$(cat /etc/mysql/debian.cnf | grep password | head -1 | awk '{print $3}') 2>/dev/null || true
endscript
}

systemd-journald 配合 logrotate

1
2
3
4
5
6
7
8
9
10
11
12
# /etc/logrotate.d/journald
/var/log/journal/*/system.journal {
weekly
rotate 4
compress
missingok
notifempty
size 500M
postrotate
journalctl --rotate 2>/dev/null || true
endscript
}

4.5 手动测试与调试

1
2
3
4
5
6
7
8
9
10
11
# 强制轮转特定日志(调试模式)
sudo logrotate -vf /etc/logrotate.d/nginx

# 查看轮转状态文件
cat /var/lib/logrotate/status

# 查看 logrotate 版本
logrotate --version

# 只显示将要执行的操作,不实际执行
sudo logrotate -d /etc/logrotate.d/nginx

4.6 logrotate 状态文件

logrotate 的状态记录在 /var/lib/logrotate/status/var/lib/logrotate/logrotate.status 中。

1
2
# 查看各日志最后轮转时间
cat /var/lib/logrotate/status | head -20

如果某条日志轮转未如期执行,可以检查状态文件确认上次轮转时间。

五、日志查看与分析工具

5.1 基础命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看日志尾部(实时跟踪)
tail -f /var/log/nginx/access.log

# 查看日志头部
head -n 50 /var/log/syslog

# 统计 IP 访问次数
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# 查看指定时间段日志
sed -n '/2026-06-09 10:00/,/2026-06-09 11:00/p' /var/log/syslog

# 搜索错误关键词
grep -i "error\|failed\|timeout" /var/log/syslog | tail -50

5.2 日志分析实战

场景:分析 Nginx 访问日志,找出访问量最高的 IP

1
2
3
4
5
6
7
8
# 统计访问量 TOP 10 的 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# 统计每分钟请求数
awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1-2 | uniq -c | tail -20

场景:分析系统错误日志

1
2
3
4
5
# 统计各类错误出现次数
journalctl -p err --since "1 hour ago" --output=json | grep -o '"MESSAGE": "[^"]*"' | sort | uniq -c | sort -rn | head -20

# 检查磁盘相关错误
journalctl -k | grep -i "ata\|disk\|i/o error\|smart"

六、日志安全最佳实践

6.1 权限配置

1
2
3
4
5
6
# 确保日志目录权限安全
sudo chmod 750 /var/log
sudo chown root:adm /var/log

# 限制日志文件权限
sudo find /var/log -type f -exec chmod 640 {} \;

6.2 集中式日志管理

生产环境中建议使用集中式日志管理方案:

方案 特点 适用场景
ELK/EFK Stack Elasticsearch + Logstash/Fluentd + Kibana 大规模集群,需要可视化分析
Loki + Promtail + Grafana 轻量级,与 Prometheus 集成 Kubernetes 环境
Graylog 开源的集中日志管理平台 企业级日志管理
Rsyslog 远程转发 简单,无需额外组件 小型集群

6.3 Rsyslog 远程日志转发配置

客户端配置(发送日志):

1
2
3
# /etc/rsyslog.d/remote.conf
*.* @192.168.1.100:514 # UDP 发送
*.* @@192.168.1.100:514 # TCP 发送(更可靠)

服务端配置(接收日志):

1
2
3
4
5
6
7
8
9
10
# /etc/rsyslog.conf
module(load="imudp")
input(type="imudp" port="514")
module(load="imtcp")
input(type="imtcp" port="514")

# 按主机名存储日志
$template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteLogs
& stop

6.4 日志监控告警

结合 Prometheus + Alertmanager 实现日志监控告警:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 使用 mtail 提取日志指标
# 安装 mtail
wget https://github.com/google/mtail/releases/download/v3.0.0-rc53/mtail_3.0.0-rc53_linux_amd64.deb
sudo dpkg -i mtail_3.0.0-rc53_linux_amd64.deb

# 编写日志分析规则
cat > /etc/mtail/nginx.mtail << 'EOF'
# 统计 5xx 错误数
counter nginx_http_errors
/HTTP\/1\.[01]" 5\d{2}/ {
nginx_http_errors++
}
EOF

sudo systemctl restart mtail

七、常见问题排查

问题原因解决方案
日志文件过大导致磁盘占满logrotate 未配置或配置不当检查 /etc/logrotate.d/ 中各应用配置,添加 size 限制
logrotate 未按时执行cron 服务未运行或配置错误sudo systemctl status cron,检查 /etc/cron.daily/logrotate
日志轮转后应用不写新日志未正确配置 postrotate 信号添加正确的信号发送:kill -USR1 $(cat /var/run/nginx.pid)
journalctl 日志占用过大SystemMaxUse 未设置或过大配置 SystemMaxUse=500M 并执行 journalctl --vacuum-size=500M
轮转后的日志权限不正确create 参数缺失或错误添加 create 640 syslog adm 到 logrotate 配置
Nginx 日志轮转后空白页面USR1 信号未成功发送确保 nginx.pid 文件存在,使用 sharedscripts 避免重复发送

八、一键清理脚本

以下是一个实用的一键脚本,用于快速清理和配置日志管理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
# 日志管理一键脚本 - log-management.sh

usage() {
echo "用法: $0 [check|clean|vacuum|status]"
echo " check - 检查日志空间占用"
echo " clean - 清理超过 30 天的日志(保留最新 5 份)"
echo " vacuum - 清理 journald 日志至 500M"
echo " status - 显示各应用日志状态"
}

case "${1:-check}" in
check)
echo "=== 日志空间占用 ==="
du -sh /var/log/* 2>/dev/null | sort -rh | head -20
echo ""
echo "=== journald 使用 ==="
journalctl --disk-usage
;;
clean)
echo "=== 清理旧日志 ==="
sudo find /var/log -name "*.gz" -mtime +30 -delete
sudo find /var/log -name "*.1" -mtime +30 -delete
sudo find /var/log -name "*.old" -mtime +30 -delete
echo "清理完成"
;;
vacuum)
echo "=== 清理 journald 日志至 500M ==="
sudo journalctl --vacuum-size=500M
echo "清理完成"
;;
status)
echo "=== 各应用日志空间 ==="
du -sh /var/log/nginx /var/log/mysql /var/log/redis 2>/dev/null
echo ""
echo "=== 最后轮转状态 ==="
cat /var/lib/logrotate/status 2>/dev/null | tail -20 || echo "状态文件不存在"
;;
*)
usage
exit 1
;;
esac

保存为 /usr/local/bin/log-management.sh 并赋予执行权限:

1
2
sudo chmod +x /usr/local/bin/log-management.sh
sudo /usr/local/bin/log-management.sh check

九、总结

合理的日志管理是服务器运维的基础工作,核心要点如下:

  1. 理解日志体系:rsyslog 负责日志记录,logrotate 负责日志轮转,systemd-journald 提供结构化日志查询
  2. 配置 logrotate:为各应用配置合理的轮转策略(周期、保留份数、压缩、权限)
  3. 定期监控:使用 journalctltail/grep/awk 定期检查日志,及时发现异常
  4. 集中管理:多服务器环境建议使用集中式日志管理方案
  5. 安全加固:控制日志权限,避免敏感信息泄露

每次配置修改后,务必用 logrotate -vf 测试,确认轮转行为符合预期。

本文由AI辅助生成,内容仅供参考

  • 标题: Linux 日志管理与 logrotate 配置完全指南
  • 作者: Someone
  • 创建于 : 2026-06-09 11:03:00
  • 更新于 : 2026-06-18 08:39:57
  • 链接: https://demo-blog.qusite.cn/2026-06-09-linux-log-management-guide/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。