Linux日志系统
Linux 有两套并存的日志体系:传统的 rsyslog(纯文本,按 facility 分流到 /var/log)和 systemd 的 journal(二进制,结构化查询)。现代 RHEL 系发行版中两者同时工作:服务日志先进 journal,再由 rsyslog 转发落盘为文本文件。
为什么需要日志系统
程序各自写文件会导致格式混乱、无处轮转、重启丢失。统一的日志守护进程解决三件事:集中收集(内核、服务、应用都投递给它)、分类落盘(按来源和级别路由到不同文件)、生命周期管理(轮转、压缩、删除)。
rsyslog 与 /var/log
rsyslog 按「facility.priority」路由日志:facility 表示来源(auth、cron、daemon、kern、mail…),priority 表示级别(从 emerg 到 debug,共 8 级)。规则写在 /etc/rsyslog.conf 及 /etc/rsyslog.d/,如 *.info;mail.none /var/log/messages 表示"info 及以上、排除邮件"写入 messages。
| 文件 | 内容 |
|---|---|
/var/log/messages | 综合系统日志(多数服务的默认去处) |
/var/log/secure | 认证相关:SSH 登录、sudo、密码验证 |
/var/log/dmesg | 内核环缓冲区日志(开机硬件探测) |
/var/log/cron | 定时任务执行记录 |
/var/log/boot.log | 本次启动过程 |
/var/log/wtmp、btmp、lastlog | 登录成功 / 失败 / 最后登录(二进制,用 last、lastb 读) |
tail -f /var/log/secure # 实时跟踪 SSH 登录
last -n 10 # 最近 10 次成功登录
lastb -n 10 # 登录失败记录(爆破排查入口)
dmesg -T # 内核日志带人类时间戳systemd journal
journal 把日志存为二进制结构化文件(/var/log/journal/,无此目录则只存内存、重启即丢),优势是可按服务、时间、级别、启动周期精确查询,不用 grep 一堆文本。
journalctl -u nginx # 只看某服务
journalctl -b # 只看本次启动(-b -1 上次)
journalctl -p err # 只看 error 及以上
journalctl --since "1 hour ago" # 时间范围
journalctl -f # 实时跟踪
journalctl --disk-usage # 占用空间持久化
默认 /run/log/journal 在内存里,重启丢失。创建 /var/log/journal 目录并 systemd-tmpfiles --create --prefix /var/log/journal 即可持久化;空间上限在 /etc/systemd/journald.conf 的 SystemMaxUse 控制。
logrotate:防止日志写爆磁盘
日志只增不减,必须定期轮转:重命名当前文件(app.log → app.log.1)、新建空文件继续写、旧文件压缩并按策略删除。logrotate 由 cron 每日触发,规则在 /etc/logrotate.conf 与各服务的 /etc/logrotate.d/*。
/var/log/nginx/*.log {
daily # 每天轮转
rotate 7 # 保留 7 份
compress # gzip 压缩旧文件
missingok # 文件不存在不报错
notifempty # 空文件不轮转
sharedscripts
postrotate
nginx -s reopen # 轮转后通知 nginx 重开文件句柄
endscript
}轮转后必须重开句柄
进程持有旧文件的写入句柄,单纯重命名后它继续写旧文件。所以配置里要有 postrotate 通知进程重开日志(nginx 用 reopen,多数服务用 kill -USR1 或 copytruncate 方式)。