背景

在Linux驱动调试工作中,如果遇到内核卡死,只能断电复位,复位后打开/var/log/syslog文件,会发现卡死时的日志都丢了。
原因我猜是内核卡死后文件系统的缓存无法同步到磁盘,于是掉电时卡死前的日志就丢了。
而这些日志对我们定位问题意义重大,有了这些日志,我们才知道卡死的原因是空指针?还是死锁?还是死循环?

解决方案1 串口转发

连接设备串口到上位机,然后配置好串口调试工具的波特率等参数,同时下位机在ubootgrub里配好console参数值(一般是console=/dev/ttyS0,115200之类的),串口打印就能看到了

优点:

  • 日志详尽,几乎不会丢日志

缺点:

  • 配置比较复杂
  • 操作麻烦,调试串口一般不对外开放,可能要拆机器
  • 上位机和下位机必须在一起,无法远程调试

解决方案2 实时轮询syslog文件

ssh连接到设备后,执行下面命令

watch -n 1 tail -30 /var/log/syslog

上面命令的意思是每间隔1s打印syslog文件的最后30行。这样当内核卡死时,watch命令已经将日志从文件系统缓存搬移到屏幕缓存,所以日志信息不会丢

优点:

  • 配置最为简单
  • 不像串口需要专门连线,只使用网口即可,操作简单

缺点:

  • 极端情况下会丢1s的日志
  • 日志回看不方便

更准确的说,该方法其实是ssh转发文件系统缓存。一般情况下,该方法也够用了。

解决方案3 网口转发

rsyslog系统主动向上位机转发日志,需要上位机显式接收

优点:

  • 不像串口需要专门连线,只使用网口即可,操作简单
  • 日志虽然没有串口详尽,但比watch命令版本要详尽,绝大部分场景够用了
  • 回看方便

缺点:

  • 配置比较复杂,不信往下看👇

发送端配置

修改设备的rsyslog配置文件,一般在/etc/rsyslog.d/50-default.conf,添加一行UDP转发规则

#  Default rules for rsyslog.
#
#           For more information see rsyslog.conf(5) and /etc/rsyslog.conf

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*         /var/log/auth.log
*.*;auth,authpriv.none      -/var/log/syslog
#cron.*             /var/log/cron.log
#daemon.*           -/var/log/daemon.log
kern.*              -/var/log/kern.log
#lpr.*              -/var/log/lpr.log
mail.*              -/var/log/mail.log
#user.*             -/var/log/user.log
*.*;auth,authpriv.none      @192.168.20.103     #将日志以UDP形式转发到目标IP

接收端配置

Visual Syslog Server for Windows

该软件开箱即用,非常方便,对应不复杂的需求,是够用了。
visual syslog server运行截图
附上软件的下载地址

tftpd64的syslog服务器模块

visual syslog server的时间戳解析自syslog消息,通常是无法精确到毫秒的,而且就算精确到毫秒,如果下位机的时间基准跟上位机不一致,上位机比对分析起来也很麻烦。
如果对时间戳的精准度有要求,可以使用tftpd64(tftpd32的64位版本)自带的syslog服务器模块
tftpd64的syslog服务器界面
使用说明:

  1. 首先点击Syslog server选项卡
  2. 点击Server interfaces下拉框,选中与下位机连接的网口
  3. 按照之前小节的内容开启下位机syslog的udp转发,然后重启下位机的syslog服务器
  4. 这时候tftpd64的Syslog server选项卡下就能刷出syslog信息了,注意,date列是上位机的时间戳,精确到毫秒哦
  5. 抓到关键的日志后记得及时点击copy按钮拷贝到剪贴板,存储到合适的文件里,然后点击clear按钮清空日志
  6. 解释下,tftpd64的Syslog server模块并不健壮,在受到密集log冲击或长时间运行后,很容易崩溃。

如果不能安装专门的syslog服务器,也可以用wireshark抓包来实现

使用wireshark的话,需要手动开启防火墙的syslog端口,syslog协议对应的端口号是514,如果不打开该端口,则wireshark收不到syslog消息:
514端口禁止访问
打开端口的步骤如下:

  1. 新建入站规则
    新建入站规则

  2. 应用于UDP 514端口
    应用于UDP 514端口

  3. 允许访问该端口
    允许访问该端口

  4. 应用该规则到所有场景
    应用该规则到所有场景

  5. 给规则起一个有意义的名字
    给规则起一个有意义的名字

  6. 打开wireshark,接收syslog消息,注意在过滤器栏填写syslog,这样就只显示syslog日志了。
    用wireshark接收syslog

总结

只要思想不滑坡,办法总比困难多。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐