服务器出故障时,日志是唯一的线索。但日志散落在几十个文件里,/var/log 翻半天找不到重点;或者反过来,日志涨了几个 G 把磁盘塞满。
这篇讲 Linux 日志体系:systemd-journald(二进制日志)+ rsyslog(传统文本日志)+ logrotate(轮转) 三件套的配置与管理。
需要云服务器可以看看财富云计算:NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,一键开服面板,主流游戏快速部署。
一、Linux 日志体系概览
现代 Linux(systemd)有两套日志并存:
| 体系 | 工具 | 日志位置 | 特点 |
|---|---|---|---|
| journald | systemd-journald | /var/log/journal/(二进制)或 /run/log/journal/ | 结构化、带元数据、查询强大,重启默认清(除非持久化) |
| rsyslog | rsyslogd | /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=yessystemctl 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 机型省一半以上。
延伸阅读
- 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
- 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
- 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
- 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
- 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
- RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
- 短链接服务搭建:Shlink 自托管,链接数据自己掌握
- 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道

[...]du -sh ~/palworld/Pal/Saved/Logs/* # 日志目录多大修复:配 logrotate(日志集中管理有配置),或直接 crontab 每周清日志。四、存档类报错(最吓人的一类)4.1 存档损坏 / Level load failed先止血:停服,别再启动,防止覆盖损坏文件。systemctl stop palworld # 或 pkill恢复:从备份恢复(这[...]
2026-10-14 回复
[...]5. 泄露响应顺序:改密码 → 重启 → 查日志 → 对备份特别提醒群管理场景:把 RCON 密码发给协管时,用「私聊 + 密码管理器分享」而不是「发群里 @他」。群记录是会截图的,密码是会忘的,泄露是会发生的。六、常见疑问Q:RCON 端口开着但不设密码行吗?不行。「不设密码」在很多服务端等于空密码直接进,比弱密码还危险。Q:用 SSH 隧道麻烦吗?一次配置永久受益,而且比公网暴露 RCON 安[...]
2026-10-18 回复
[...]netsh advfirewall firewall add rule name="GameRange" dir=in action=allow protocol=UDP localport=26901-26903完整的 Windows 环境准备(远程桌面连接、运行库安装、SteamCMD 用法、开机自启、8 个常见坑)见:《Windows 云服务器开服通用前置教程》→ htt[...]
2026-10-18 回复