
工控日志系统rsyslog 持久化日志、日志分割、崩溃信息留存工控设备跑着跑着突然死了重启后啥日志都没有——这比设备本身出故障还让人崩溃。日志系统配不好出了问题就是两眼一抹黑。一、Linux 日志体系总览Linux 的日志不是一锅端而是分层管理的日志类型来源查看方式特点内核日志内核驱动、硬件事件dmesg环形缓冲区重启后丢失系统日志rsyslog 收集所有系统进程日志/var/log/messages或journalctl持久化可配置应用日志应用程序自行输出自定义文件/printf各自为政格式不统一工控系统的日志目标是内核日志不丢、系统日志有序、应用日志规范。二、rsyslog 配置详解2.1 rsyslog 是什么rsyslog是 Linux 上最广泛使用的日志收集服务它接收来自内核、系统服务和应用程序的日志按照规则过滤后写到不同文件。2.2 配置文件结构主配置文件/etc/rsyslog.conf自定义规则放在/etc/rsyslog.d/*.conf# 基本语法格式 facility.severity target # 示例 *.info;mail.none /var/log/messages kern.* /var/log/kernel.log local0.* /var/log/device_app.log2.3 Facility日志来源Facility说明auth认证相关kern内核日志mail邮件系统daemon后台守护进程local0~local7自定义应用工控最常用*所有2.4 Severity日志级别从高到低级别名称说明0EMERG系统不可用1ALERT必须立即处理2CRIT严重错误3ERR错误4WARNING警告5NOTICE正常但值得关注6INFO信息7DEBUG调试规则中用*表示所有级别.表示该级别及以上.表示仅该级别。三、日志持久化配置很多嵌入式系统默认把日志写在内存文件系统tmpfs里重启就没了。工控设备要求日志必须落盘# /etc/rsyslog.d/20-industrial.conf # 内核日志持久化 kern.* /var/log/kernel.log # 应用日志使用local0-local7 local0.* /var/log/app_main.log local1.* /var/log/app_sensor.log local2.* /var/log/app_network.log # 系统核心日志 *.info;mail.none;authpriv.none /var/log/messages # 紧急日志直接发到控制台 *.emerg :omusrmsg:*同时确认/etc/rsyslog.conf中没有把日志写到/dev/null或只留内存的路径。确保/var/log目录挂载在可持久化分区上不是 tmpfs。四、日志分割策略 —— logrotate日志文件不分割会越来越大最终撑满磁盘。logrotate就是干这事的。4.1 logrotate 工作原理logrotate通过 cron 定时调用按照配置规则对日志文件进行轮转rotate、压缩compress、删除remove。4.2 配置文件示例# /etc/logrotate.d/industrial # 应用主日志 /var/log/app_main.log { daily # 每天轮转 rotate 30 # 保留30天 size 10M # 超过10M也轮转双触发条件 compress # 压缩旧日志 delaycompress # 延迟一次压缩最近一份不压 missingok # 文件不存在不报错 notifempty # 空文件不轮转 copytruncate # 拷贝后清空原文件应用无需重启 dateext # 文件名带日期 } # 内核日志 /var/log/kernel.log { weekly rotate 12 compress missingok notifempty copytruncate } # 系统消息日志 /var/log/messages { daily rotate 60 size 50M compress delaycompress sharedscripts postrotate /etc/init.d/rsyslog reload /dev/null 21 endscript }4.3 关键参数解读参数说明daily/weekly/monthly轮转周期rotate N保留N份历史日志size文件超过该大小也轮转compressgzip压缩旧日志省空间copytruncate拷贝后截断原文件应用无需重启即可继续写postrotate轮转后执行的脚本通知服务重新打开文件copytruncatevspostrotate工控场景推荐copytruncate因为嵌入式设备上重启服务比较麻烦copytruncate 能让应用无感继续写日志。4.4 手动触发轮转测试# 测试不真正执行只打印会发生什么logrotate-d/etc/logrotate.d/industrial# 强制执行轮转logrotate-f/etc/logrotate.d/industrial五、崩溃信息留存 —— Core Dump程序崩溃时如果配置了 core dump系统会生成一个内存转储文件用 GDB 就能定位崩溃点。5.1 开启 core dump# 取消 core 文件大小限制ulimit-cunlimited# 永久生效写入 /etc/profile 或 /etc/security/limits.confecho* soft core unlimited/etc/security/limits.confecho* hard core unlimited/etc/security/limits.conf5.2 配置 core 文件路径和格式# 查看当前设置cat/proc/sys/kernel/core_pattern# 设置 core 文件保存路径和命名格式echo/var/coredump/core.%e.%p.%t/proc/sys/kernel/core_pattern格式说明占位符含义%e可执行文件名%p进程PID%t崩溃时间戳%s触发崩溃的信号编号别忘了创建目录并设权限mkdir-p/var/coredumpchmod777/var/coredump5.3 用 GDB 分析 core 文件# 编译时加 -g 选项保留调试信息arm-linux-gnueabihf-gcc-g-omyapp myapp.c# 分析崩溃文件gdb ./myapp /var/coredump/core.myapp.1234.1689000000# 进入 GDB 后查看崩溃位置(gdb)bt# 查看调用栈(gdb)print var# 查看变量值5.4 程序崩溃自动收集信息工控场景可以写一个脚本通过 core_pattern 的管道功能自动处理崩溃# core_pattern 可以指定一个程序来处理 core dumpecho|/usr/bin/core_handler %e %p %t %s/proc/sys/kernel/core_patterncore_handler.sh脚本可以把崩溃信息打包、发通知、记录日志#!/bin/sh# /usr/bin/core_handlerEXEC$1PID$2TIME$3SIG$4COREDIR/var/coredumploggerCRASH:$EXEC(PID$PID, SIG$SIG) crashed at$(date)# 从 stdin 读取 core dump 数据并保存cat$COREDIR/core.${EXEC}.${PID}.${TIME}六、应用日志规范6.1 用 syslog() 代替 printf工控应用不要用printf打日志没法管理改用syslog()#includesyslog.hintmain(){/* 打开日志指定 facility 为 local0 */openlog(mydevice,LOG_PID|LOG_NDELAY,LOG_LOCAL0);syslog(LOG_INFO,Device started, version 1.2.0);syslog(LOG_WARNING,Temperature high: %d degrees,75);syslog(LOG_ERR,Sensor read failed: %s,strerror(errno));/* 崩溃前留下遗言 */if(critical_error){syslog(LOG_CRIT,Fatal error, shutting down);abort();/* 触发 core dump */}closelog();return0;}6.2 日志级别使用建议场景建议级别启动/关闭信息INFO周期性数据上报DEBUG默认关闭异常但可恢复WARNING功能不可用ERR即将崩溃CRIT别拿 INFO 当 DEBUG 用否则日志文件会被周期数据刷爆。七、远程日志集中收集多个工控设备需要统一管理日志时可以让 rsyslog 把日志转发到中心服务器客户端工控设备# /etc/rsyslog.d/30-remote.conf # 使用TCP转发到日志服务器 *.* 192.168.1.100:514 # 表示TCP 表示UDP服务端日志服务器# /etc/rsyslog.conf 开启接收 $ModLoad imtcp $InputTCPServerRun 514 # 按设备IP分目录存储 $template RemoteLogs,/var/log/remote/%fromhost%/%$YEAR%_%$MONTH%_%$DAY%.log *.* ?RemoteLogs这样每个设备的日志都自动归档到/var/log/remote/设备IP/下集中查看方便。八、完整配置示例汇总以一个典型的工控板为例完整配置清单rsyslog 配置/etc/rsyslog.d/20-industrial.conf$FileCreateMode 0644 kern.* /var/log/kernel.log local0.* /var/log/app_main.log local1.* /var/log/app_sensor.log *.info;local0.none;local1.none;kern.none /var/log/messageslogrotate 配置/etc/logrotate.d/industrial/var/log/app_main.log /var/log/app_sensor.log /var/log/kernel.log /var/log/messages { daily rotate 30 size 10M compress delaycompress missingok notifempty copytruncate dateext }core dump 配置写入/etc/profile或启动脚本ulimit-cunlimitedmkdir-p/var/coredumpecho/var/coredump/core.%e.%p.%t/proc/sys/kernel/core_pattern九、工控日志管理最佳实践清单序号实践说明1日志必须落盘/var/log不能挂载在 tmpfs 上2应用用 syslog()不要 printf便于统一管理3开启 core dumpulimit -c unlimited 配置 core_pattern4logrotate 定期轮转否则磁盘早晚被撑满5压缩历史日志gzip 压缩率通常 80% 以上6区分日志级别INFO/WARNING/ERR 分清楚7关键操作留日志开关机、参数修改、报警事件8远程日志备份重要设备日志转发到服务器9磁盘空间监控日志目录加磁盘监控满了自动清理10带时间戳所有日志条目必须包含精确到秒的时间日志系统就是工控设备的黑匣子。平时不觉得重要真出事的时候它就是你定位问题的唯一线索。把 rsyslog、logrotate、core dump 三件套配好后续运维能少走一半弯路。