服务器出问题了,先看日志。但 /var/log 下文件一大堆,messages、syslog、journal,到底哪个记什么?日志撑爆磁盘怎么办?本文讲透 Linux 日志系统的三大组件:rsyslog、journald、logrotate,以及它们的分工协作。一、Linux 日志系统总览
应用/内核 │ ├──→ /dev/log (Unix socket) │ │ │ ├──→ rsyslogd ──→ /var/log/messages, /var/log/secure... │ │ │ └──→ journald ──→ /run/log/journal (内存) 或 /var/log/journal (持久) │ └──→ 直接写文件 ──→ /var/log/nginx/access.log, /var/log/app/app.log...日志轮转:logrotate ──→ 压缩旧日志、删除过期日志、防止磁盘打满
二、rsyslog — 传统日志守护进程
1. 是什么
rsyslog 是 Linux 传统的系统日志服务,接收内核和应用日志,按规则写入不同文件。
# 检查状态systemctl status rsyslog# 主配置文件/etc/rsyslog.conf# 规则目录/etc/rsyslog.d/
2. 日志级别(severity)
| | |
|---|
emerg | | |
alert | | |
crit | | |
err | | |
warning | | |
notice | | |
info | | |
debug | | |
3. 设施(facility)
| |
|---|
kern | |
user | |
mail | |
daemon | |
auth | |
syslog | |
local0-local7 | |
4. 配置规则
# /etc/rsyslog.conf 核心格式# 设施.级别 动作*.info;mail.none;authpriv.none;cron.none /var/log/messagesauthpriv.* /var/log/securemail.* /var/log/maillogcron.* /var/log/cron*.emerg :omusrmsg:*local7.* /var/log/boot.log
规则含义:
| |
|---|
*.info | |
mail.none | |
authpriv.* | |
:omusrmsg:* | |
5. 自定义应用日志
# /etc/rsyslog.d/myapp.conf# 将 local0.info 写入 /var/log/myapp/app.loglocal0.info /var/log/myapp/app.log& stop # 不再继续匹配其他规则# 重启生效systemctl restart rsyslog
# 用 logger 测试logger -p local0.info "This is a test message"# 或 Pythonimport syslogsyslog.openlog('myapp', syslog.LOG_PID, syslog.LOG_LOCAL0)syslog.syslog(syslog.LOG_INFO, 'Application started')
6. 远程日志收集
# 服务端(日志中心):接收远程日志# /etc/rsyslog.confmodule(load="imudp")input(type="imudp" port="514")module(load="imtcp")input(type="imtcp" port="514")# 按来源 IP 分目录$template RemoteLogs,"/var/log/remote/%fromhost-ip%/%programname%.log"*.* ?RemoteLogs& stop
# 客户端:发送日志到远程# /etc/rsyslog.d/remote.conf*.* @@192.168.1.100:514 # @@ = TCP, @ = UDP
三、journald — systemd 的日志系统
1. 是什么
journald 是 systemd 自带的日志服务,用二进制格式存储,支持结构化查询。
# 查看状态systemctl status systemd-journald# 配置/etc/systemd/journald.conf# 日志存储/run/log/journal/ # 内存存储(重启丢失)/var/log/journal/ # 持久存储(需创建目录)
2. journald vs rsyslog
3. journalctl 常用命令
# 查看所有日志(从旧到新)journalctl# 反向查看(最新的在前)journalctl -r# 查看实时日志journalctl -f# 查看特定服务journalctl -u nginxjournalctl -u sshd --since "1 hour ago"# 查看特定时间范围journalctl --since "2026-07-15 10:00:00" --until "2026-07-15 12:00:00"# 查看特定优先级journalctl -p err# 查看内核日志journalctl -k# 查看特定进程journalctl _PID=1234# 查看特定用户journalctl _UID=1000# 查看启动日志journalctl -b # 当前启动journalctl -b -1 # 上一次启动# 查看日志占用的磁盘空间journalctl --disk-usage# 清理日志journalctl --vacuum-size=100M # 保留100MBjournalctl --vacuum-time=7d # 保留7天
4. 持久化配置
# 默认 journal 存在内存,重启丢失# 改为持久化sudo mkdir -p /var/log/journalsudo systemd-tmpfiles --create --prefix /var/log/journal# /etc/systemd/journald.conf[Journal]Storage=persistent # auto/persistent/volatileSystemMaxUse=500M # 最大占用SystemMaxFileSize=50M # 单个文件大小MaxRetentionSec=7day # 保留时间
5. 转发 journald 到 rsyslog
# /etc/systemd/journald.conf[Journal]ForwardToSyslog=yes# 这样 journald 和 rsyslog 双写,兼容两种查询方式
四、logrotate — 日志轮转工具
1. 是什么
logrotate 自动轮转、压缩、删除旧日志,防止 /var/log 撑爆磁盘。
# 配置文件/etc/logrotate.conf # 主配置/etc/logrotate.d/ # 应用配置目录# 定时执行(通过 cron 或 systemd timer)/etc/cron.daily/logrotate
2. 主配置
# /etc/logrotate.confweekly # 默认每周轮转rotate 4 # 保留4个旧文件create # 轮转后创建新文件dateext # 用日期作为后缀compress # 压缩旧文件include /etc/logrotate.d # 包含应用配置
3. 应用配置示例
Nginx 日志
# /etc/logrotate.d/nginx/var/log/nginx/*.log { daily # 每天轮转 missingok # 文件不存在不报错 rotate 30 # 保留30天 compress # 压缩 delaycompress # 推迟一天压缩(方便恢复) notifempty # 空文件不轮转 create 0644 nginx nginx # 创建新文件的权限和属主 sharedscripts # 所有文件轮转完再执行脚本 postrotate # 通知 Nginx 重新打开日志文件 /bin/kill -USR1 $(cat /run/nginx.pid 2>/dev/null) 2>/dev/null || true endscript}
自定义应用日志
# /etc/logrotate.d/myapp/data/myapp/logs/*.log { daily rotate 30 compress delaycompress missingok notifempty create 0644 appuser appgroup dateext # 用日期后缀:app.log-20260715.gz dateformat -%Y%m%d-%s # 自定义日期格式 size 100M # 超过100MB也轮转(不按时间) maxsize 200M # 最大200MB必须轮转 minsize 1M # 小于1MB不轮转}
4. 配置指令详解
| |
|---|
daily/weekly/monthly/yearly | |
rotate N | |
create mode owner group | |
compress | |
delaycompress | |
missingok | |
notifempty | |
sharedscripts | |
prerotate/endscript | |
postrotate/endscript | |
size | |
maxage | |
5. 手动测试配置
# 测试配置是否正确(不实际执行)sudo logrotate -d /etc/logrotate.d/nginx# 强制轮转(调试用)sudo logrotate -f /etc/logrotate.d/nginx# 查看轮转历史cat /var/lib/logrotate/logrotate.status
五、三大组件协作关系
应用写日志 │ ├──→ journald(systemd 服务默认) │ │ │ ├──→ 内存存储(/run/log/journal)──→ 重启丢失 │ │ │ ├──→ 持久存储(/var/log/journal)──→ journalctl 查询 │ │ │ └──→ ForwardToSyslog=yes ──→ rsyslog │ ├──→ rsyslog(传统服务、自定义设施) │ │ │ └──→ /var/log/messages, /var/log/secure... │ └──→ 直接写文件(Nginx、应用框架) │ └──→ logrotate ──→ 轮转、压缩、清理
六、生产环境最佳实践
1. 日志目录规划
# 系统日志/var/log/messages # 通用系统日志/var/log/secure # 认证日志/var/log/audit # SELinux 审计日志# 应用日志(独立分区或磁盘)/data/logs/nginx/ # Nginx 访问/错误日志/data/logs/app/ # 应用日志/data/logs/mysql/ # 数据库慢查询/错误日志# 日志分区单独挂载,防止撑爆根目录
2. 统一日志格式(JSON)
# 应用日志输出 JSON,便于 ELK 收集{"timestamp":"2026-07-15T10:30:00+08:00","level":"ERROR","service":"order","msg":"timeout","trace_id":"abc123"}
3. 日志监控告警
# 监控日志增长df -h /var/logdu -sh /var/log/*# 监控特定错误journalctl -p err --since "5 minutes ago" | wc -l# 或用 logwatch 生成日报sudo logwatch --detail High --mailto admin@example.com
4. 日志集中收集架构
服务器A/B/C │ ├──→ Filebeat ──→ Kafka/Redis ──→ Logstash ──→ Elasticsearch ──→ Kibana │ └──→ rsyslog ──→ 日志中心服务器
七、常见问题排查
| | |
|---|
| systemctl status rsyslog | |
| /var/log/journal | 创建目录,配置 Storage=persistent |
| du -sh /var/log/* | |
| logrotate -d | |
| df -h | |
八、总结 checklist
□ rsyslog:传统系统日志,按设施/级别分发到不同文件□ journald:systemd 结构化日志,journalctl 查询,建议配置持久化□ logrotate:自动轮转、压缩、清理,防止磁盘打满□ 应用日志:建议用 local0-local7 设施,rsyslog 统一收集□ 关键日志:配置 logrotate 保留足够天数,满足审计要求□ 磁盘监控:日志单独分区,设置告警阈值□ 集中收集:大规模环境用 ELK 或 rsyslog 转发
一句话总结
rsyslog 是分类员(按规则分发),journald 是档案馆(结构化存储),logrotate 是清洁工(定时清理)。三者配合,日志系统才能既好用又不撑爆磁盘。