2. syslog与rsyslog:日志系统的核心枢纽
说实话,车载Linux的日志系统,我最早接触时也觉得不就是个打印信息嘛。直到有一次,一台路测车在高速上偶发黑屏,日志却什么都没留下——嗯,从那以后我才真正重视起日志系统的设计。
这一章,我们来聊聊syslog和rsyslog。说白了,它们就是车载系统的「黑匣子」。你想想看,没有它们,故障就像幽灵一样,来了又走,你根本抓不住。
2.1 syslog协议基础:别小看这个老家伙
syslog协议,RFC 5424定义的,其实很老了。但老不代表没用。我在车载项目里见过太多人,上来就搞高大上的日志方案,结果发现syslog才是最稳的。
syslog的核心就三个东西:设施(Facility)、级别(Severity)、消息(Message)。就这么简单。
Facility:标识日志来自哪个子系统。比如:
LOG_KERN(0) — 内核消息LOG_USER(8) — 用户级消息LOG_LOCAL0~LOG_LOCAL7(16~23) — 留给自定义用的
我个人的习惯是,车载应用统统用 LOG_LOCAL0 到 LOG_LOCAL3,这样方便和系统日志分开。
Severity:从紧急到调试,一共8级。记住这个表:
| 级别 | 数值 | 含义 | 车载场景举例 |
|---|---|---|---|
| EMERG | 0 | 系统不可用 | 安全气囊控制器崩溃 |
| ALERT | 1 | 必须立即处理 | 刹车系统通信超时 |
| CRIT | 2 | 严重错误 | CAN总线持续丢帧 |
| ERR | 3 | 一般错误 | 传感器初始化失败 |
| WARNING | 4 | 警告 | GPS信号弱 |
| NOTICE | 5 | 正常但重要 | 系统启动完成 |
| INFO | 6 | 一般信息 | 蓝牙连接成功 |
| DEBUG | 7 | 调试信息 | 传感器数据帧内容 |
为什么强调这个?因为车载环境里,日志量太大了。我曾经见过一个项目,DEBUG日志全开着,结果一天就写满了eMMC。所以,生产环境只开ERR及以上,这是铁律。
2.2 rsyslog配置实战:从入门到真香
syslogd太老了,现在车载Linux基本都用rsyslog。它比syslogd强在哪?说白了就是:更灵活、更可靠、能转发。
先看一个最基本的配置,我一般放在 /etc/rsyslog.conf:
# 加载模块
module(load="imuxsock") # 本地socket输入
module(load="imklog") # 内核日志输入
# 定义模板 - 这个很重要
template(name="CarLogFormat" type="string"
string="%TIMESTAMP% %HOSTNAME% %syslogtag% %msg%\n")
# 规则:所有日志按模板写入文件
*.* /var/log/syslog;CarLogFormat
# 车载专用:CAN总线日志单独存放
local0.* /var/log/canbus.log;CarLogFormat
# 车载专用:ADAS系统日志
local1.* /var/log/adas.log;CarLogFormat
我的经验:模板一定要自定义。默认格式里时间戳是字符串,解析起来很麻烦。我习惯用 %TIMESTAMP% 加 %syslogtag% 的组合,这样grep起来一目了然。
再来看一个更实战的配置——日志轮转。车载存储空间有限,不轮转就是找死:
# /etc/logrotate.d/car_logs
/var/log/canbus.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}
这里要注意:rotate 7 保留7天,车载一般7~30天。我建议根据eMMC容量来算,留出20%的余量。
2.3 车载环境下的日志转发策略
车载系统和普通服务器最大的区别是什么?网络不稳定。车在隧道里、地库里,网络说断就断。所以日志转发不能简单粗暴。
我遇到过最坑的事:一台车在山区路测,日志转发到云端,结果网络断了,rsyslog默认行为是丢弃消息。等车回来一看,关键故障日志全没了。嗯,从那以后我改用了可靠转发模式。
来看一个带缓冲的转发配置:
# 使用 RELP 协议(可靠事件日志协议)
module(load="omrelp")
# 定义转发规则 - 带磁盘缓冲
action(type="omrelp"
target="192.168.1.100"
port="2514"
queue.type="linkedlist"
queue.filename="relp_queue"
queue.maxdiskspace="100m"
queue.saveonshutdown="on"
action.resumeRetryCount="-1")
# 本地也保留一份,双重保险
*.* /var/log/syslog;CarLogFormat
重要提醒:queue.type="linkedlist" 表示用内存队列,queue.filename 指定磁盘缓冲文件。当网络断了,日志先写到磁盘,网络恢复后再补发。但要注意,queue.maxdiskspace 别设太大,100MB足够了,否则eMMC扛不住。
车载日志转发,我总结了几条策略:
- 本地优先:所有日志先写本地,再考虑转发。本地是根,云端是叶。
- 分级转发:ERR及以上实时转发,INFO/WARNING攒批发送(比如每5分钟一次)。
- 带宽控制:车载4G/5G流量有限,我一般限制转发速率不超过 100KB/s。
- 断线重连:用 RELP 或 TCP,别用 UDP。UDP丢包你哭都来不及。
最后,分享一个我常用的车载日志过滤规则。有些日志太吵了,比如GPS每秒一次的定位信息,转发到云端就是浪费流量:
# 过滤掉GPS频繁日志
if $programname == 'gpsd' and $syslogseverity-text == 'INFO' then {
/var/log/gps_local.log
stop
}
# 其他日志正常转发
*.* action(type="omrelp" target="cloud.xxx.com" port="2514")
你看,stop 关键字就是「到此为止,不再往下处理」。这个技巧在车载里非常实用。
一句话总结:syslog是基础,rsyslog是工具,转发策略是灵魂。车载日志系统,说白了就是「本地存得住、云端传得稳、关键时刻查得到」。我做了这么多年,这三条从来没变过。