记一次logger无法发送消息的问题排查

背景

logger是一个在Linux和Unix操作系统中使用的命令行工具,可以直接向系本地syslog文件或远程Syslog服务器发送消息。logger为写日志提供了不同的选项,如设置优先级、指定远程系统或指定Syslog端口。

在调试rsyslog收发功能的时候,突然出现logger无法向本地及远程任何地方发送消息的情况,在对该问题的排查定位中使用的手段和思路,对于深入调查linux上同类问题有一定的参考价值。

问题描述

常规使用,logger无法给本地系统日志和远端发送消息,无显式报错,而在这之前能够正常工作。

具体复现如下:

logger -p local1.info "my name is Hanmeimei"
# -p, --priority priority_level,指定输入消息的优先级
# 在执行命令后,本地的syslog收不到信息;

排查与定位

  1. 首先排除rsyslog升级、配置等原因,因为之前一直正常运行,没人修改这些配置。

  2. 如果重启该机器,可以立即解决这个问题,logger -p local1.info "msg"可以正常使用。重启机器是一个重操作,代价很大,一般不作首要处理方案,需要进一步定位原因,减轻影响。

  3. 我现在有3台机器都出现这个问题,我重启了2台,留下一台做对比研究使用(后分别称作对照机与问题机)。

  4. 因为logger命令本身无法直接查看,没有找到日志,暂无法追踪,要想其他办法去查——了解到可以使用strace指令跟踪logger命令的调用栈情况,如下:

  5. 执行strace -f logger -p local1.info "123"

    strace介绍:

    顾名思义,strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。strace底层使用内核的ptrace特性来实现其功能。

    strace作为一种动态跟踪工具,能够帮助运维高效地定位进程和服务故障。

    这里,-f 表示跟踪由fork调用所产生的子进程,后面跟的是原始命令。

  6. 分别获取到对照机与问题机的上述指令的输出。使用Compare或者IDEA进行内容的对比:

在这里插入图片描述

  1. 左侧是对照机正常的输出,右侧是有问题的。通过对比,两个文件内容只有一处实质不同,即正常输出比问题机多了一行内容②,而这一行就是实际要发送的内容(“123”)。

  2. 问题发生在①处,正常的这里返回了0,异常的这里返回-1,(报错…-1 ECONNREFUSED (Connection refused))——因为连接被拒绝,①处门都没打开,当然也就没有后面发送消息的②了。

在这里插入图片描述

  1. 综上,关键信息出现——指向了/dev/log,错误为:连接被拒绝!因此没有成功发出消息。我们顺藤摸瓜:这个/dev/log是个特殊文件,它的属性是srw-rw-rw-s代表Unix domain socket,也称为网络套接字

在这里插入图片描述

  1. 继续追溯到/dev/logsystemd-journald.socket有关系。

    systemd-journald的补充:

    systemd-journald 是一个收集并存储各类日志数据的系统服务。如果在启动期间存在 /var/log/journal/ 目录,那么日志将会被持久存储在此目录中, 否则将会临时存储在 /run/log/journal/ 目录中(关机即丢失)。

    以 “.socket” 为后缀的单元文件, 封装了一个用于进程间通信的套接字(socket)或管道(FIFO), 以支持基于套接字的启动。

    systemd-journald将监听以下这些套接字和路径,在文件系统中可见:

    /dev/kmsg, /dev/log, /run/systemd/journal/dev-log, /run/systemd/journal/socket, /run/systemd/journal/stdout

解决方案

使用systemctl restart systemd-journald.socket重启端口(并不是systemd-journald.service),仅此一步就可以解决问题,logger能够成功发送消息了。

注意:没有重新启动rsyslogd。

小结

本文通过strace来跟踪比较两个执行路径,直接获取到了关键报错,再据此线索解决问题。此外,开启rsyslogdebug级别日志也许能看到更详细的信息,但在可能的情况下strace更利于发现问题的真相。

在定位到/dev/log之后问题被解决,但解决方案与socket“拒绝连接”的原因之间尚有链条缺失,由于测试环境已经销毁,无法追踪了。有其他老师提到可能是system启动的systemd-journaldrsyslog sock有冲突,导致rsyslog套接字无法正常发送数据,但问题的概率特征与本文有出入。另有提及配置修改导致不记录日志的现象,将/etc/systemd/journald.conf中的配置ForwardToSyslog,修改为yes即可(针对的是systemd-journald.service)。

对于/dev/log丢失的情况,论坛提到使用手动链接也可以:ln -s /run/systemd/journal/dev-log /dev/log

参考

如何在systemd + rsyslog主机中还原/ dev / log?

Ubuntu18.04系统rsyslog不记录日志问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1024点线面

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值