【问题标题】:Why Syslogs from a program is watched from the journal command?为什么从 journal 命令监视程序的系统日志?
【发布时间】:2022-12-30 04:40:55
【问题描述】:

我正在开发一个使用syslog() 发送日志的程序。然后我配置了rsyslog服务,将日志保存在Linux下的文件中。大多数情况下,此过程正常进行。但有时,有些日志没有发送到rsyslog。相反,我可以在使用 journalctl -f -u Myservice 命令时观看它们。我正在使用 Linux 的 Debian Jessie 版本。你知道问题是什么以及如何解决吗?

【问题讨论】:

  • I use the journal -f 你不用journalctl吗?
  • 您应该共享启动您的应用程序的 systemd 服务的内容。默认情况下,通过 systemd 启动的程序的 stderr 和 stdout 进入日志。
  • 您还可以分享“systemctl status your_service | cat”的结果

标签: linux systemd syslog systemd-journald


【解决方案1】:

笼统地说,使用 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.socket是从中捕获消息的 systemd 套接字单元/dev/log:

[...]
[Socket]
Service=systemd-journald.service
ListenDatagram=/run/systemd/journal/dev-log
Symlinks=/dev/log
SocketMode=0666
[...]

在上面的socket单元中,有两个重要的东西:

  • 为这个套接字触发的服务是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的同义词/run/systemd/journal/dev-log.当 systemd-journald 从这个套接字读取时,这使得它捕获所有写入进程的日志/dev/log.但是 systemd 实现了一种将这些日志转发到任何“已注册”服务的机制。

有一个系统日志.socket设置的单位/run/systemd/journal/syslog插座:

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

相应的系统日志服务之后被触发。后者实际上是指向实际系统日志服务的符号链接(例如 rsyslogd 或 syslog-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
[...]

我们可以通过查看系统日志服务(字段“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)。这是由rsyslogd的imuxsock模块管理的。这确实是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-journald 的 configuration 决定是否从中读取内容/run/systemd/journal/dev-log转发或不转发/run/systemd/journal/syslog:

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

上面的注释行表示默认是“是的”.

回答OP的问题

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

进一步参考

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      最后,我找到了一个很好的答案。在rsyslog 配置文件中,我们可以添加不同的方法来获取消息。我有很多带有 contains 过滤器的过滤器。这显着降低了性能,因为它需要完全搜索字符串以获取过滤器值。然后我发现 startswith 过滤器在搜索字符串中的值时要好得多。我更改了消息结构,以便可以使用 startswith 过滤器。我将 rsyslog 过滤器更改为 startswith。现在性能好多了,没有消息发送到日志。 语法是这样的:

      :msg, startswith, "val" # instead of (:msg, contains, "error")

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-26
        • 2018-08-07
        • 1970-01-01
        相关资源
        最近更新 更多