一、日志是运维的第一手证据
服务器出问题,第一件事永远是看日志。但日志文件无限增长会撑爆磁盘,排障时又要在海量日志里捞关键行。本文讲清楚 Linux 下两套日志体系:systemd 的 journald 和传统 rsyslog + logrotate。
二、journalctl 高效查日志
systemd 时代所有服务的标准输出和错误都进 journal,journalctl 是核心查询工具:
# 查看某服务全部日志journalctl -u nginx# 只看最近 30 分钟journalctl --since "30 min ago"journalctl --since "2026-08-08 08:00" --until "2026-08-08 09:00"# 跟踪实时输出(排障利器)journalctl -u nginx -f# 按优先级过滤:0 emerg 到 7 debug,err 表示 0-3journalctl -p err -b# 只看本次开机以来的日志journalctl -b# 查看上次启动的日志(系统崩溃后排查)journalctl -b -1# 配合 grep 定位关键词journalctl -u php-fpm --since today | grep -i error
常用组合:-u 按服务过滤,-p 按级别过滤,-b 按启动轮次过滤,--since/--until 按时间过滤,四个维度交叉基本能定位绝大多数问题。
三、journald 持久化与容量控制
journald 默认把日志存在内存 /run/log/journal,重启即丢。要持久化:
mkdir -p /var/log/journalsystemd-tmpfiles --create --prefix /var/log/journalsystemctl restart systemd-journald
同时限制日志体积,防止 /var 被撑爆。编辑 /etc/systemd/journald.conf:
[Journal]# 日志占满磁盘的百分比上限,超出会清理旧日志SystemMaxUse=500M# 单条日志大小上限MaxFileSize=64M# 保留时间MaxRetentionSec=2weekCompress=yes
改完 systemctl restart systemd-journald 生效。想立刻瘦身:journalctl --vacuum-size=200M 或 journalctl --vacuum-time=7d。
四、logrotate 管理传统日志文件
Nginx、MySQL 等应用日志仍由 rsyslog 或应用自身写文件,靠 logrotate 轮转。配置在 /etc/logrotate.d/ 下,以 nginx 为例:
/var/log/nginx/*.log { daily # 每天轮转一次 rotate 14 # 保留 14 份 missingok # 文件不存在不报错 notifempty # 空文件不轮转 compress # 轮转后 gzip 压缩 delaycompress # 延迟一份再压缩,方便当天查 dateext # 文件名带日期 sharedscripts postrotate # 通知 nginx 重新打开日志文件 [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript}手动测试配置是否正确(会真的执行一次轮转,先加 -d 试运行):
logrotate -d /etc/logrotate.conf # 试运行,只打印不执行logrotate -f /etc/logrotate.conf # 强制轮转logrotate -v /etc/logrotate.conf # 查看执行详情
logrotate 由 cron.daily 驱动,若机器长时间关机或 cron 异常,日志会堆积,巡检时可用 logrotate -v 确认最近有执行记录。
五、日志集中收集
单机排障靠 journalctl 和 logrotate 够用,但服务器一多就要集中收集。轻量方案用 rsyslog 的 imjournal 模块把 journal 转发到中央日志机:
# 在 /etc/rsyslog.conf 增加module(load="imjournal" StateFile="imjournal.state")*.* @10.0.0.10:514 # 转发到中央日志服务器 UDP 514
规模化方案上 ELK 或 Loki + Promtail,配合 Grafana 做可视化检索。收集前务必在每台机器上做好时区统一和时间同步,否则日志时间轴是乱的。
六、排障实战套路
- 先看时间窗口:
journalctl --since "10 min ago" -p err缩小范围。 - 再定位服务:
journalctl -u 服务名 -f实时观察复现。 - 查应用自身日志:/var/log/ 下对应文件,配合 logrotate 的 .gz 历史文件看问题是否反复出现。
- 最后对照系统日志 /var/log/messages 或 journal 的 kernel 段,排除硬件和内核层问题。
养成"问题来了先看日志、看完日志再动手"的习惯,比任何监控工具都管用。
评论