在Ubuntu 16.04上,rsyslog和journald之间的关系

我正在运行一个纯净的Ubuntu 16.04服务器,我试图弄清楚默认情况下日志是如何设置的。我可以看到journaldrsyslog都已安装并运行,但对于日志消息的处理方式并不明确。
大多数消息似乎同时出现在/var/log/syslogjournalctl中,但我无法在/etc/systemd/journald.conf(默认情况下基本上都是注释掉的)、/etc/rsyslog.conf/etc/rsyslog.d/50-default.conf中找到任何关于两者之间转发的明确配置。 我尝试寻找官方文档,甚至一篇解释Ubuntu中这两者设置的博客文章,但没有找到任何信息。
为了进一步增加我的困惑,我在主机上执行了logger -p local1.info Test,发现没有将任何内容写入/var/log/syslog,而该消息确实出现在journalctl中。
我的问题是:
  1. journald和rsyslog在Ubuntu 16.04(默认情况下)是如何一起工作的?
  2. 为什么从logger发送的消息似乎只出现在日志中,而不出现在syslog中?

更新:事实证明logger没有按预期工作是我的疏忽,所以与主要问题无关。

2个回答

默认情况下,rsyslog 使用 "imuxsock" 模块,该模块提供以下功能:

通过本地 Unix 套接字接收 syslog 消息的能力。最重要的是,这是 syslog(3) 调用将 syslog 消息传递给 rsyslogd 的机制 [1]

rsyslog 可以使用名为 "imjournal" 的模块从 systemd-journal 导入结构化日志消息 [2]
可以像这样加载它:
module(load="imjournal") 

在:

/etc/rsyslog.conf

另一方面,“systemd-journald”自己捕获所有数据。
man systemd-journald

systemd-journald is a system service that collects and stores logging data. It creates and maintains structured, indexed journals based on logging information that is received from a variety of sources:

   ·   Kernel log messages, via kmsg
   ·   Simple system log messages, via the libc syslog(3) call
   ·   Structured system log messages via the native Journal API, 
       see sd_journal_print(4)
   ·   Standard output and standard error of system services
   ·   Audit records, via the audit subsystem
你可以在仍然可以访问系统日志的情况下,通过使用journalctl来禁用rsyslogd
$ sudo systemctl mask rsyslogd
$ sudo systemctl stop syslog.socket
$ sudo systemctl stop rsyslog.service
$ systemctl is-active rsyslog.service 
inactive
$ logger -p mail.info Helllooo
$ journalctl

比如说,CentOS使用"imuxsock"模块通过rsyslog捕获所有的"systemd-journald"数据,而openSUSE根本没有"syslog"。
要找出为什么您的消息没有发送到/var/log/syslog,您应该检查这个文件:
less /etc/rsyslog.d/50-default.conf

寻找*.info,看它们将被存储在哪里,可能是另一个文件,比如messages
对我来说,它会同时显示在journalctlsyslog中。

logger -p .info hello 不是有效的命令。您没有提供任何设施名称。 - luv.preet
更新了答案.... - Ravexina
正如我在编辑中指出的那样,“logger”不起作用是我的错,所以现在已经修复了(无论如何,谢谢你的建议)。至于日志出现在两个地方,你关于“imuxsock”的说明似乎是关键:看起来rsyslog和journald都在监听本地syslog消息,这就是为什么这些条目会进入两个不同的日志文件。 - motns
我在Ubuntu上按照上述步骤操作,但现在无法从日志记录器中获取任何日志,嗯:root@T:~# logger -p mail.info Helllooo root@T:~# journalctl 未找到任何日志文件。 -- 没有条目 --有什么想法吗? - Hackeron
很好的回答。然而,我想知道的是,journald如何知道在rsyslog被禁用时打开syslog套接字(或者如果它不这样做,它如何获取syslog消息)?或者说,是否需要手动配置journald? - Matthijs Kooijman
答案解释了两者如何工作,但没有解释实际发生的事情。 - ygoe
在16.04版本中缺少的一点魔力是imuxsock被硬编码为查看/run/systemd/journal/syslog(SYSTEMD_PATH_LOG),而/lib/systemd/system/syslog.socketListenDatagram=/run/systemd/journal/syslog,这触发了/etc/systemd/system/syslog.service -> /lib/systemd/system/rsyslog.service debian/patches/Re-enable-journal-forwarding-to-syslog.patch使ForwardToSyslog成为默认选项,只进行了最基本的文档更新。 - eichin

Systemd是一个用于在系统启动时启动服务的初始化系统。 Journald负责为由systemd启动的服务生成日志。通过将journald与systemd集成,即使是最早的引导过程消息也可以提供给journald。
Rsyslog是一个专门用于日志处理的守护程序,与journald无关。它可以通过多种方式接收日志并以多种方式输出。默认情况下,它不会从journald接收日志消息。要实现这一点,您需要在/etc/rsyslog.conf文件中编写配置。
$ModLoad imjournal # im -> input module
OR
load(type="imjournal")

现在,它还可以接受来自journald的日志。但是我建议您不要更改/etc/rsyslog.conf文件。
在/etc/rsyslog.conf文件的末尾,有一行写着,
$IncludeConfig /etc/rsyslog.d/*.conf

这意味着在 /etc/rsyslog.d/ 文件夹中,所有以 .conf 结尾的文件都应在 rsyslog 加载期间包含。因此,您所有的自定义配置应放在这些文件中。

我建议您创建一个文件 /etc/rsyslog.d/journald.conf,并将下面的片段粘贴到其中。

以下是来自 rsyslog 官方页面的 imjournal 片段。

module(load="imjournal" PersistStateInterval="100"
   StateFile="/path/to/file") #load imjournal module
module(load="mmjsonparse") #load mmjsonparse module for structured logs

template(name="CEETemplate" type="string" string="%TIMESTAMP% %HOSTNAME% %syslogtag% @cee: %$!all-json%\n" ) #template for messages

action(type="mmjsonparse")
action(type="omfile" file="/var/log/ceelog" template="CEETemplate")

第一行 - 它加载imjournal模块以接收来自journald的日志。
第二行 - 加载mmjsonparse模块,用于解析日志。
第三行 - 这些日志按照模板中描述的格式进行结构化。
第四行 - 使用mmjsonparse模块解析这些日志。
第五行 - 根据给定模板的结构,使用omfile(输出模块文件 - 输出到文件)模块将这些日志发送到名为/var/log/ceelog的文件中。
根据您的需求对配置进行更改。

谢谢解释,但我认为@Ravexina的回答更接近帮助我理解rsyslog和journald的情况,默认情况下(无需额外配置)。 - motns