Appearance
日志管理
系统排障主要依赖三类日志来源:systemd journald(服务日志)、rsyslog(传统系统日志)、应用自身写的文件日志。
一、日志目录和文件
大多数系统和服务的日志集中在 /var/log 下。
| 文件 | 对应发行版 | 内容 |
|---|---|---|
/var/log/messages | RHEL 系 | 通用系统日志 |
/var/log/syslog | Debian/Ubuntu | 通用系统日志 |
/var/log/secure | RHEL 系 | 认证和安全相关日志(SSH 登录、sudo 等) |
/var/log/auth.log | Debian/Ubuntu | 认证和安全相关日志 |
/var/log/dmesg | 通用 | 内核启动日志的快照 |
/var/log/cron | 部分发行版 | cron 执行日志 |
不同的发行版日志文件名不完全相同,排查时先确认目标发行版的命名习惯。遇到登录相关问题看 secure 或 auth.log,内核和硬件问题看 dmesg。
二、journald 和 journalctl
systemd 的日志系统叫 journald。它收拢了 systemd 管理服务的 stdout/stderr、内核日志和部分系统日志,存放在二进制格式的日志文件中(而不是纯文本),查询时使用 journalctl。
bash
journalctl # 查看全部日志(可能非常多)
journalctl -u nginx # 只看指定 unit 的日志
journalctl -u nginx -f # 持续跟踪,类似 tail -f
journalctl -u nginx --since "1 hour ago"
journalctl -p err # 只看 error 级别及以上的日志常用参数:
| 参数 | 作用 |
|---|---|
-u | 过滤指定 systemd unit |
-f | 持续输出新日志(follow) |
--since | 起始时间(支持 "today"、"1 hour ago"、"2026-05-21") |
--until | 结束时间 |
-p | 按日志级别过滤(emerg、alert、crit、err、warning、notice、info、debug) |
-n | 显示最近 N 行 |
--no-pager | 不使用分页直接输出,方便脚本处理 |
服务启动失败的标准排查:
bash
systemctl status app --no-pager # 看状态和最后几行日志
journalctl -u app -n 100 --no-pager # 看最近 100 行从最近日志开始看,再按时间逐渐扩大范围。一上来就翻全量日志效率很低。
journald 的持久化行为与 /var/log/journal 目录是否存在有关。如果该目录不存在,journald 默认只在 /run/log/journal(tmpfs,内存中)存储日志,重启后日志丢失。需要持久化时:
bash
mkdir -p /var/log/journal
systemctl restart systemd-journald三、rsyslog
rsyslog 是传统的系统日志服务,负责按规则将不同来源的日志写到对应的文本文件中。journald 和 rsyslog 可以同时存在——journald 收集,再通过转发交给 rsyslog 归档。
主配置和附加配置:
bash
cat /etc/rsyslog.conf
ls /etc/rsyslog.d/重启 rsyslog:
bash
systemctl restart rsyslogrsyslog 的规则格式是 facility.level 目标:
conf
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
cron.* /var/log/cronfacility 表示日志来源类别(authpriv=认证、cron=定时任务、mail=邮件、daemon=守护进程),level 表示记录的最低等级。authpriv.* 表示认证相关的所有级别的日志都写入 /var/log/secure。
一般的应用服务不直接修改 rsyslog 配置。只有当需要做集中日志收集、自定义日志路径或调整系统日志行为时才会动它。
四、dmesg 内核日志
dmesg 查看内核环形缓冲区中的消息,包含硬件探测、驱动加载、OOM killer、网络接口状态等信息。
bash
dmesg
dmesg -T # 显示可读时间戳
dmesg -T | tail -n 50过滤异常信息:
bash
dmesg -T | grep -i -E "error|fail|oom|reset"磁盘 I/O 错误、网卡 link down、OOM 被杀进程、USB 设备异常等都可以在 dmesg 里找到痕迹。需要注意 dmesg -T 显示的时间在某些系统上可能不准——内核的时间戳和系统时间不一定同步,关键事故还是要结合 journald 和其他日志交叉验证。
五、logrotate 日志轮转
logrotate 解决的是日志文件无限增长的问题。它不减少日志量,只是定期把旧日志改名、压缩、删除。
bash
cat /etc/logrotate.conf # 全局配置
ls /etc/logrotate.d/ # 各服务的独立配置一个典型的轮转配置:
logrotate
/var/log/myapp/*.log {
daily # 每天轮转一次
rotate 7 # 保留最近 7 份
missingok # 文件不存在不报错
notifempty # 空文件不轮转
compress # 压缩旧日志
delaycompress # 延迟压缩(保留最近一份不压缩,方便仍在查)
copytruncate # 拷贝后清空原文件
}copytruncate 的方式:先把日志内容复制到轮转文件,再清空原日志文件。优点是不需要服务支持重新打开日志文件,缺点是复制和清空之间产生的少量日志可能丢失。
对于支持 reload 信号的服务(如 nginx),更可靠的方式是 postrotate:
logrotate
/var/log/nginx/*.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
postrotate
systemctl reload nginx >/dev/null 2>&1 || true
endscript
}轮转完成后发 reload 信号给服务,让服务重新打开日志文件。这比 copytruncate 更可靠,不会丢日志。
测试配置:
bash
logrotate -d /etc/logrotate.conf # -d 是 debug 模式,只模拟不执行
logrotate -f /etc/logrotate.conf # -f 强制执行一次正式强制轮转前先用 -d 模拟跑一遍,特别是带 postrotate 和 --delete 的配置。
六、日志排查的基本方法
按时间范围定位:
bash
journalctl --since "2026-05-21 10:00:00" --until "2026-05-21 11:00:00"按关键字过滤:
bash
grep -i "error" app.log
grep -i -E "error|exception|failed|timeout" app.log关注日志增长速度:
bash
ls -lh app.log # 单个文件大小
du -sh /var/log/* # 各日志目录占用
tail -f app.log # 观察写入速度日志目录单独挂载是一个简单的防护措施。应用程序异常狂写日志时,不至于把根分区打满进而影响整个系统。