2. Linux日志系统:rsyslog配置、日志轮转、journalctl使用与采集策略

日志这东西,平时没人搭理它。一旦线上出故障,它就是唯一的救命稻草。我做了这么多年运维,最怕的就是登录服务器一看——日志文件是空的,或者被撑爆了。嗯,今天咱们就把Linux日志系统这块彻底捋清楚。

2.1 rsyslog:日志界的瑞士军刀

rsyslog是Linux上最主流的日志收集守护进程。说白了,它就是个智能快递员——把系统里各种程序产生的日志消息,按照你定的规则,送到该去的地方。

它的配置文件在 /etc/rsyslog.conf/etc/rsyslog.d/ 目录下。我个人习惯把自定义规则写在 /etc/rsyslog.d/ 里,这样升级主配置时不会被覆盖。

2.1.1 配置语法速览

rsyslog的规则格式其实很简单:

设施.级别    动作

举个例子:

# 把所有内核日志写到 /var/log/kern.log
kern.*    /var/log/kern.log

# 把mail相关的所有级别日志写到单独文件
mail.*    /var/log/mail.log

# 把紧急级别的日志发送到所有登录用户的终端
*.emerg   :omusrmsg:*

这里有个坑——设施级别的对应关系。设施包括 authcrondaemonkernmailsysloguser 等。级别从低到高是 debuginfonoticewarningerrcritalertemerg

小技巧:*.=info 表示只匹配info级别,用 *.info 表示匹配info及以上所有级别。这个等号很关键,我在项目中见过有人搞混,结果日志量翻了好几倍。

2.1.2 远程日志收集

生产环境里,我强烈建议把日志集中到一台服务器上。这样排查问题时不用挨个登录机器。

服务端配置(接收日志):

# 在 /etc/rsyslog.conf 中取消注释
$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$TCPServerRun 514

# 接收到的日志按来源IP分类存储
$template RemoteLogs,"/var/log/remote/%fromhost-ip%/%programname%.log"
*.* ?RemoteLogs

客户端配置(发送日志):

# 在 /etc/rsyslog.d/remote.conf 中
*.* @192.168.1.100:514   # UDP发送
*.* @@192.168.1.100:514  # TCP发送
注意: 我曾经在生产环境直接用UDP收日志,结果网络抖动丢了不少关键日志。后来全部改成TCP了。虽然性能差一点,但可靠性更重要。另外,防火墙记得放行514端口。

2.2 日志轮转:别让日志撑爆磁盘

日志如果不轮转,一个月就能把磁盘塞满。我见过最夸张的一次,某台机器上 /var/log/messages 达到了80GB,系统直接卡死。

Linux下日志轮转靠的是 logrotate。它的配置文件在 /etc/logrotate.conf/etc/logrotate.d/ 目录下。

2.2.1 核心配置项

配置项 说明 示例
daily/weekly/monthly 轮转周期 daily
rotate N 保留N个历史文件 rotate 7
compress 压缩旧日志 compress
maxsize SIZE 日志超过SIZE就轮转 maxsize 100M
missingok 日志文件不存在不报错 missingok
notifempty 空文件不轮转 notifempty
postrotate/endscript 轮转后执行的脚本 重启服务

来看一个实际例子:

/var/log/nginx/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    maxsize 200M
    sharedscripts
    postrotate
        /bin/kill -USR1 `cat /var/run/nginx.pid 2>/dev/null` 2>/dev/null || true
    endscript
}

这里有个细节——delaycompress。它的意思是这次轮转不立即压缩,等下次轮转再压缩。为什么?因为有些程序还在往旧文件里写数据,立即压缩可能导致数据丢失。嗯,这个坑我踩过。

2.2.2 手动测试轮转

配置写好了,别直接等cron执行。先手动跑一下看看效果:

# 强制轮转,但不实际执行
logrotate -d /etc/logrotate.d/nginx

# 强制轮转,实际执行
logrotate -f /etc/logrotate.d/nginx
核心原则: 日志轮转一定要配合 postrotate 通知应用程序重新打开文件句柄。否则应用程序会继续往已重命名的旧文件里写日志,轮转就白做了。

2.3 journalctl:systemd时代的日志神器

从CentOS 7/RHEL 7开始,systemd接管了系统初始化,同时也带来了 journald 日志系统。它的日志存在 /var/log/journal/ 目录下,是二进制格式,不能直接用cat看。得用 journalctl 来查。

2.3.1 常用查询技巧

# 查看所有日志
journalctl

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

# 查看上次启动的日志
journalctl -b -1

# 查看某个服务的日志
journalctl -u nginx.service

# 查看最近5分钟的日志
journalctl --since "5 min ago"

# 按优先级过滤(0=emerg, 1=alert, 2=crit, 3=err, 4=warning...)
journalctl -p err -b

# 实时跟踪日志(类似tail -f)
journalctl -f -u nginx.service

我个人最常用的组合是:

# 查看某个服务最近一小时的错误日志
journalctl -u nginx.service --since "1 hour ago" -p err --no-pager

2.3.2 日志持久化

默认情况下,journald的日志存在内存里,重启就没了。想持久化?很简单:

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

# 重启服务
systemctl restart systemd-journald

然后编辑 /etc/systemd/journald.conf

[Journal]
Storage=persistent
Compress=yes
MaxRetentionSec=1month
MaxFileSec=1week
SystemMaxUse=1G
建议: 我一般把 SystemMaxUse 设为1GB或2GB,防止journald把磁盘撑爆。另外,MaxRetentionSec 设成1个月,太老的日志该删就删。

2.4 日志采集策略:从源头到平台

讲完了工具,咱们聊聊策略。日志采集不是把日志文件扔给采集器就完事了。你得想清楚几个问题。

2.4.1 采集什么

不是所有日志都要采。我见过有人把 /var/log/debug 也采到ELK里,结果一天几个TB,查询还巨慢。我的建议是:

  • 必采: 系统日志(messages、secure)、应用访问日志、错误日志
  • 按需采: 慢查询日志、审计日志、性能日志
  • 不采: debug日志、重复的轮转旧文件

2.4.2 采集方式

目前主流的采集方式有三种:

方式 工具 适用场景 优缺点
Agent采集 Filebeat、Logstash 通用场景 灵活、资源占用可控
Syslog转发 rsyslog、syslog-ng 网络设备、旧系统 配置简单、但功能有限
API采集 自定义脚本 云服务、特殊格式 定制化强、但维护成本高

我个人推荐用Filebeat + rsyslog的组合。Filebeat负责采集文件,rsyslog负责接收syslog。这样既覆盖了文件日志,也覆盖了系统日志。

2.4.3 避坑指南

我曾经踩过的坑:
  • 采集器权限不够,读不到日志文件——记得给Filebeat加 adm
  • 日志轮转时采集器还在读旧文件——用 close_inactive 参数控制
  • 多行日志被拆成多条——比如Java异常栈,用 multiline 配置合并
  • 采集器把磁盘IO打满——限制 harvester_buffer_sizemax_bytes

2.5 知识体系总览

下面这张图,把本章的核心逻辑串起来了。你想想看,日志从产生到最终被分析,经历了哪些环节:

Linux日志系统知识体系 日志产生源 系统/应用/服务 本地日志收集 rsyslog / journald 日志存储 /var/log/*.log 日志轮转管理 logrotate 远程日志采集 Filebeat / rsyslog转发 集中分析平台 ELK / Loki / 自建 日志查询工具 journalctl / grep / awk 从日志产生 → 本地收集 → 存储轮转 → 远程采集 → 集中分析

说白了,整个流程就是:日志从应用产生,经过rsyslog或journald收集到本地文件,logrotate负责管理文件大小和数量,然后通过Filebeat或rsyslog转发到远程平台做集中分析。每一步都有坑,每一步也都有优化空间。

我的建议: 刚开始做日志系统时,别追求大而全。先把 /var/log/messages/var/log/secure 和应用的关键日志采好,跑通整个链路。等稳定了,再逐步加其他日志。一口吃不成胖子,日志系统也是。

好了,这一章的内容就到这儿。日志系统是运维的基石,花时间把它搞扎实了,后面排查问题会轻松很多。


公众号:蓝海资料掘金营,微信deep3321