13 10 月 2026

服务器出故障时,日志是唯一的线索。但日志散落在几十个文件里,/var/log 翻半天找不到重点;或者反过来,日志涨了几个 G 把磁盘塞满。

这篇讲 Linux 日志体系:systemd-journald(二进制日志)+ rsyslog(传统文本日志)+ logrotate(轮转) 三件套的配置与管理。

需要云服务器可以看看财富云计算:NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,一键开服面板,主流游戏快速部署。

一、Linux 日志体系概览

现代 Linux(systemd)有两套日志并存:

体系工具日志位置特点
journaldsystemd-journald/var/log/journal/(二进制)或 /run/log/journal/结构化、带元数据、查询强大,重启默认清(除非持久化)
rsyslogrsyslogd/var/log/syslog、/var/log/messages(文本)传统方式,通用格式,工具链成熟
应用日志各程序自己/var/log/nginx/、/var/log/mysql/程序自管

关系:应用把日志写给 syslog 或直接写文件;journald 收系统服务的日志。两者互补,不是替代。

二、journald:最好用的日志查询工具

常用查询(比 grep 文件高效得多)

# 看所有日志(实时,类似 tail -f)
journalctl

# 看某个服务的日志
journalctl -u nginx
journalctl -u nginx -f          # 实时跟踪

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

# 看上次启动的日志(排查重启原因神器)
journalctl -b -1

# 看内核日志
journalctl -k

# 按时间
journalctl --since "2026-10-13 20:00"
journalctl --since "1 hour ago"
journalctl --since today --until "now"

# 按优先级(err 及以上)
journalctl -p err
# 优先级: emerg(0) alert(1) crit(2) err(3) warning(4) notice(5) info(6) debug(7)

# 组合查询:某个服务今天的错误
journalctl -u nginx --since today -p err

# 看指定 PID
journalctl _PID=1234

# 看可执行文件
journalctl /usr/bin/sshd

日志持久化(重要)

默认情况下 journald 日志存在 /run/log/journal/,重启就没了。要持久化:

# 创建持久化目录
mkdir -p /var/log/journal

# 配置
vim /etc/systemd/journald.conf
[Journal]
# 持久化存储
Storage=persistent

# 日志总量上限(防止塞满磁盘,默认等于磁盘的 10%)
SystemMaxUse=2G

# 单文件大小
SystemMaxFileSize=200M

# 保留策略(按时间)
MaxRetentionSec=1month

# 自动压缩
Compress=yes
systemctl restart systemd-journald
journalctl --disk-usage    # 看占用

清理日志

# 看占用
journalctl --disk-usage

# 按时间清理(只保留最近 7 天)
journalctl --vacuum-time=7d

# 按大小清理(压到 500M 以内)
journalctl --vacuum-size=500M

# 看日志文件
ls -la /var/log/journal/*/

三、rsyslog:传统文本日志

journald 查起来爽,但有些场景需要文本格式(日志分析工具、合规要求、外发到日志服务器)。

基础配置

# /etc/rsyslog.conf
# 加载模块
module(load="imuxsock")      # 本地系统日志输入
module(load="imklog")        # 内核日志

# 全局设置
$WorkDirectory /var/spool/rsyslog
$ActionFileEnableSync off

# 默认规则:所有日志进 /var/log/syslog
*.info;mail.none;authpriv.none;cron.none    /var/log/syslog

# 认证日志单独放
authpriv.*    /var/log/secure

# 邮件日志
mail.*    -/var/log/maillog

# cron 日志
cron.*    /var/log/cron

# 所有设施的全部级别
*.*    /var/log/all.log

自定义规则:按程序分文件

# /etc/rsyslog.d/10-nginx.conf
# Nginx 的 syslog 日志单独存
if $programname == 'nginx' then /var/log/nginx/syslog.log
& stop

# /etc/rsyslog.d/10-myapp.conf
# 自己的应用
if $programname startswith 'myapp' then /var/log/myapp.log
& stop

改完 systemctl restart rsyslog。

外发日志到集中服务器

多台机器的日志汇到一台,排查问题时不用逐台登录:

# 客户端:/etc/rsyslog.d/90-remote.conf
# UDP 转发(快但可能丢)
*.* @日志服务器IP:514

# TCP 转发(可靠)
*.* @@日志服务器IP:514

# 服务器端:/etc/rsyslog.conf
# 开启 TCP 接收
module(load="imtcp")
input(type="imtcp" port="514")

# 按来源 IP 分文件
$template RemoteStore,"/var/log/remote/%FROMHOST-IP%/%$YEAR%/%$MONTH%/%$DAY%/messages"
*.* ?RemoteStore

日志服务器安全:514 端口别暴露公网,内网专用;开启 TLS 传输敏感日志。

四、logrotate:日志轮转

日志不轮转,磁盘必满。logrotate 是标配,大部分软件的日志配置都装好了,但自己的日志要手动配。

配置示例

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily                # 每天轮转
    rotate 14            # 保留 14 份
    missingok           # 文件不存在不报错
    notifempty          # 空文件不轮转
    compress            # 压缩旧日志
    delaycompress       # 最近一份不压(程序可能还在写)
    dateext             # 用日期做后缀
    sharedscripts       # 多文件共享 pre/post 脚本
    postrotate
        # 轮转后通知 nginx 重新打开文件(关键!)
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

游戏服日志配置

# /etc/logrotate.d/gameservers
/opt/games/*/server/Logs/*.log {
    weekly
    rotate 8
    compress
    delaycompress
    missingok
    notifempty
    copytruncate        # 游戏服不支持 USR1 信号时用这个
}

copytruncate vs postrotate + USR1:

方式原理适用
postrotate + kill -USR1告诉程序重新打开日志文件支持信号的程序(nginx、PHP-FPM)
copytruncate先复制再清空原文件不支持信号的程序(多数游戏服)

copytruncate 有极小概率丢轮转瞬间的几行日志,游戏服日志不敏感,可以接受。

测试与手动执行

# 测试配置语法(不会真的执行)
logrotate -d /etc/logrotate.d/nginx

# 强制执行一次轮转
logrotate -f /etc/logrotate.d/nginx

# 跑全部配置
logrotate /etc/logrotate.conf

# 看日志轮转状态
cat /var/lib/logrotate/status

全局配置

# /etc/logrotate.conf
# 每周轮转系统日志
weekly
rotate 4
create
compress
include /etc/logrotate.d

五、实战:日志暴涨的排查与处理

场景:磁盘突然满了,df -h 看到 / 100%。

# 1. 找大文件
du -h /var/log --max-depth=2 | sort -rh | head -20

# 2. 常见元凶
# - nginx access.log 被刷(CC 攻击或爬虫)
# - journald 没设上限
# - 应用 debug 日志忘关
# - 某个 cron 脚本疯狂输出

# 3. 看谁在写(实时)
lsof +D /var/log 2>/dev/null | head -20

# 4. 看增长最快的文件
watch -n 2 'du -sh /var/log/* | sort -rh | head -5'

# 5. 处理
# a. 先止血:清空暴涨的日志(不是删文件,是清空)
truncate -s 0 /var/log/nginx/access.log

# b. journald 超限就 vacuum
journalctl --vacuum-size=500M

# c. 根因处理:CC 攻击配限流(见 Nginx 限速防护)
# d. 确认 logrotate 配置覆盖了这个文件

清空日志的正确方式:

# 对:清空内容,保留文件句柄
truncate -s 0 /var/log/xxx.log
> /var/log/xxx.log

# 错:直接删文件(进程还持有着句柄,空间不释放,且可能写丢)
rm /var/log/xxx.log    # ❌

六、日志分析:快速提取信息

# Nginx 访问日志 TOP IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

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

# 请求最多的 URL(找 CC 目标)
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

# 日志里的错误汇总
grep -iE "error|fail|denied" /var/log/nginx/error.log | tail -50

# journald 看服务重启记录(查为什么老重启)
journalctl -u myapp | grep -iE "start|stop|fail|kill" | tail -30

# 系统 OOM 记录
journalctl -k | grep -i "killed process"

更复杂的分析(Web 日志安全分析)见Web 日志分析实战。

七、常见问题

Q:journalctl 输出是二进制乱码?
用 journalctl 看,不要 cat /var/log/journal/xxx.journal。想转文本:journalctl -o export > backup.journal.txt。

Q:日志时间和其他机器对不上?
时区问题,timedatectl set-timezone Asia/Shanghai,重启服务。详见云服务器时区与 NTP 同步。

Q:日志轮转后程序不写新文件了?
程序 hold 着旧文件的句柄。支持信号的用 postrotate + USR1,不支持的用 copytruncate。

Q:journald 占了几个 G?
没配上限。/etc/systemd/journald.conf 里设 SystemMaxUse=2G,然后 journalctl --vacuum-size=2G。

Q:多台机器日志想统一看?
小规模用 rsyslog 外发到一台日志服务器;规模大了上 Loki + Grafana 或 ELK。本文的 rsyslog 外发方案是零成本起步。

小结

日志管理三件套:journald 持久化 + 设上限(查询爽、不炸盘)、rsyslog 规则分类(该分的分开存)、logrotate 全覆盖(包括自己的应用日志)。配一次,之后所有故障排查都有据可查,磁盘也不会被日志偷袭。

更多运维教程见财富云计算知识库:Linux 命令速查、crontab、systemd 服务、监控体系全系列。需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:rsync 同步与定时备份实战:增量备份 + 硬链接方案
  2. 下一篇:内核参数优化:sysctl 实战调优(游戏服与高并发两套参数)
发表评论 3