linux 为什么要通过journal命令查看程序的Syslog?

6mw9ycah  于 2023-01-01  发布在  Linux
关注(0)|答案(3)|浏览(308)

我正在写一个用syslog()发送日志的程序,然后我配置了rsyslog服务,把日志保存在Linux下的一个文件中,这个过程大部分时间都是正常的,但是有时候有些日志并没有发送到rsyslog,而是我用journalctl -f -u Myservice命令的时候可以看到,我用的是LinuxDebian Jessie版本,你知道是什么问题,怎么解决吗?

ogsagwnx

ogsagwnx1#

不严格地说,使用systemd时,日志的管理方式如下:

Process calls syslog()--写入--〉/dev/log = /run/systemd/journal/dev-log--读取者--〉systemd-journald--转发到--〉/run/systemd/journal/syslog--读取者--〉rsyslogd

让我们更详细地了解一下...

  • /lib/systemd/system/systemd-journald-dev-log。套接字 * 是用于捕获来自 /dev/log 的消息的systemd套接字单元:
[...]
[Socket]
Service=systemd-journald.service
ListenDatagram=/run/systemd/journal/dev-log
Symlinks=/dev/log
SocketMode=0666
[...]

在上述插座单元中,有两件重要的事情:

  • 为该套接字触发的服务是systemd-journald;
  • /dev/log 是指向 /run/systemd/journal/dev-log 的符号链接:
$ ls -l /dev/log
lrwxrwxrwx 1 root root 28 sept.  14 09:47 /dev/log -> /run/systemd/journal/dev-log
$ ls -l /run/systemd/journal/dev-log
srw-rw-rw- 1 root root 0 sept.  14 09:47 /run/systemd/journal/dev-log

因此,任何调用syslog()的进程实际上都写入到 /dev/log 中,/dev/log/run/systemd/journal/dev-log 的同义词。当systemd-journald从这个套接字读取时,这使得它捕获所有写入到 /dev/log中的进程的日志。但是systemd实现了一种机制,将这些日志转发到任何“注册”的服务。
有一个 syslog.socket 单元用于设置 /run/systemd/journal/syslog 套接字:

[...]
[Socket]
ListenDatagram=/run/systemd/journal/syslog
[...]

相应的 syslog.service 随后触发。后者实际上是到实际syslog服务的符号链接(例如rsyslogdsyslog-ng)。下面是一个示例,其中它是到 rsyslog.service 的符号链接:

$ ls -l /etc/systemd/system/syslog.service 
lrwxrwxrwx 1 root root 35 juin    5  2021 /etc/systemd/system/syslog.service -> /lib/systemd/system/rsyslog.service

后一服务的内容执行rsyslogd守护进程:

[...]
[Service]
Type=notify
ExecStart=/usr/sbin/rsyslogd -n -iNONE
[...]

我们可以通过查看 syslog 服务(字段“TriggeredBy”)的状态来验证其激活:

$ systemctl status syslog | cat
* rsyslog.service - System Logging Service
     Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2022-09-14 09:47:22 CEST; 32min ago
TriggeredBy: * syslog.socket
       Docs: man:rsyslogd(8)
             https://www.rsyslog.com/doc/
   Main PID: 728 (rsyslogd)
      Tasks: 4 (limit: 18404)
     Memory: 3.9M
     CGroup: /system.slice/rsyslog.service
             `-728 /usr/sbin/rsyslogd -n -iNONE
sept. 14 09:47:22 xxx systemd[1]: Starting System Logging Service...
sept. 14 09:47:22 xxx rsyslogd[728]: imuxsock: Acquired UNIX socket '/run/systemd/journal/syslog' (fd 3) from systemd.  [v8.2001.0]

上面的启动消息显示rsyslogd已通过unix套接字 /run/systemd/journal/syslog(文件描述符id 3)。这由rsyslogdimuxsock模块管理。这确实是rsyslogd进程打开的文件描述符的一部分:

$ sudo ls -l /proc/`pidof rsyslogd`/fd
total 0
lr-x------ 1 root root 64 sept.  14 09:47 0 -> /dev/null
l-wx------ 1 root root 64 sept.  14 09:47 1 -> /dev/null
l-wx------ 1 root root 64 sept.  14 09:47 10 -> /var/log/kern.log
l-wx------ 1 root root 64 sept.  14 09:47 11 -> /var/log/mail.log
l-wx------ 1 root root 64 sept.  14 09:47 2 -> /dev/null
lrwx------ 1 root root 64 sept.  14 09:47 3 -> 'socket:[1339]'
lr-x------ 1 root root 64 sept.  14 09:47 4 -> /dev/urandom
lrwx------ 1 root root 64 sept.  14 09:47 5 -> 'socket:[36221]'
lr-x------ 1 root root 64 sept.  14 09:47 6 -> /proc/kmsg
lrwx------ 1 root root 64 sept.  14 09:47 7 -> 'socket:[36999]'
l-wx------ 1 root root 64 sept.  14 09:47 8 -> /var/log/syslog
l-wx------ 1 root root 64 sept.  14 09:47 9 -> /var/log/auth.log

systemd-journaldconfiguration决定是否将从 /run/systemd/journal/dev-log 读取的内容转发到 /run/systemd/journal/syslog

$ cat /etc/systemd/journald.conf | grep ForwardToSyslog
#ForwardToSyslog=yes

上面的注解行表示默认值为**“yes”**。

回答操作员的问题

如果进程发送的一些日志在rsyslogd的输出中没有看到,但在systemd-journald的输出中看到,这可能意味着rsyslogd与应用程序相比启动得不够早。后者的日志记录由systemd-journald读取,但不转发到rsyslogd。后者从systemdmulti-user.target 开始,而systemd-journald在系统启动的最开始启动。
为了验证这一点,systemctl status syslog.service的结果显示激活日期,并将其与 systemd-journald.service 和应用程序的激活日期进行比较。
应用程序的服务文件中可能缺少类似“After=syslog.service”的同步密钥。

更多参考

https://www.freedesktop.org/wiki/Software/systemd/syslog/

sz81bmfz

sz81bmfz2#

这完全取决于rsyslog服务是否运行,遇到问题时请检查rsyslog是否运行。

luaexgnf

luaexgnf3#

最后,我找到了一个很好的答案。在rsyslog配置文件中,我们可以添加不同的方法来获取消息。我有许多使用contains过滤器的过滤器。这显著降低了性能,因为它需要完全搜索过滤器值的字符串。然后我发现startswith过滤器在搜索字符串中的值方面要好得多。我更改了消息结构,以便可以使用startswith过滤器。然后我将rsyslog过滤器更改为startswith。现在性能好多了,并且没有消息发送到日志。语法如下所示:
:msg, startswith, "val" # instead of (:msg, contains, "val")

相关问题