问题描述
在Ubuntu 12.04上,我可以在/var/log/syslog
中找到Upstart日志消息。
命令:
# initctl log-priority info
# initctl emit hello
日志:
Apr 1 01:56:56 precise64 kernel: [ 8365.820425] init: Connection from private client
Apr 1 01:56:56 precise64 kernel: [ 8365.821130] init: Handling hello event
在Ubuntu 13.10上,消息不会出现在syslog
或/var/log
目录下的任何其他位置,尽管logger hello
之类的命令按预期工作。我应该在其他地方找他们吗?是否需要在某处更改配置设置?
有一个似乎在Ubuntu 13.04上遇到同样问题的人的question on Server Fault,以及更多的here和here,它们也可能描述了同样的问题。不幸的是,这些问题没有提供问题的线索。
最佳解决思路
编辑2016-06-02
如果您正在尝试查找“Upstart日志消息”,请选中/var/log/upstart/
。这就是Upstart从Upstart服务中保存stdout
和stderr
的地方。感谢leopd的回答指出这一点。
如果您正在寻找来自Upstart本身的日志消息,这些消息由initctl log-priority
配置并由initctl emit
发出,请继续阅读!
精简版
日志条目实际上应该显示在dmesg中。尽管如此,它们在/var/log
中默认不显示。
如果您也想在/var/log
中使用它们,请将$KLogPermitNonKernelFacility on
添加到rsyslogd的配置中。我建议创建一个自定义文件,如/etc/rsyslog.d/60-custom.conf
,以避免编辑/etc/rsyslog.conf
,因为它由dpkg管理。现在,将Upstart的log-priority
设置为info
后,Upstart消息应显示在/var/log/syslog
中。
长版
这花了我几天追踪,但显然Upstart(1.5)没有登录到syslog,也就是说,它没有调用glibc函数syslog()
。相反,Upstart记录到内核环缓冲区,这是dmesg读取的内容。现在,我不认为用户空间进程可以写入该缓冲区,但显然他们可以写入/dev/kmsg
,而这正是Upstart所做的。这就是这个难题的第一部分。
第二部分是widely-held认为写入内核环缓冲区的消息会被内核自动复制到syslog中(至少这是我一直认为的)。事实证明,这实际上是由用户空间守护进程完成的,传统上是klogd,它与syslogd协同工作。显然rsyslogd取代了syslogd,但显然它也取代了klogd(有点:最后看注释)。
第三部分是从用户空间写入内核环缓冲区的消息实际上与从内核空间写入的消息看起来不同:它们具有不同的功能。 dmesg有一些与之交互的选项:-x
将显示设施(和优先级),而-u
和-k
告诉dmesg分别仅显示用户设施消息和内核设施消息。
现在这里是关键:默认情况下,rsyslogd在从内核环缓冲区读取消息时忽略具有non-kernel功能的消息。相关的配置选项是$KLogPermitNonKernelFacility
,默认情况下处于关闭状态,如果您希望rsyslogd处理这些消息,则需要将其打开。请注意,rsyslogd配置的其余部分将来自内核环缓冲区的所有消息视为具有kern
功能,无论它们在内核环缓冲区中具有什么功能。
更多信息
syslog
代码可以通过调用man 3 syslog
中描述的glibc函数syslog()
写入syslog。显然这些函数写入/dev/log
。代码可以通过读取/dev/log
从syslog中读取,这就是syslogd
及其替代品所做的。 rsyslogd
使用其imuxsock
输入模块读取/dev/log
。
内核环缓冲区
内核空间通过调用内核函数 printk()写入此缓冲区,因此它有时称为printk缓冲区。用户空间可以通过写入/dev /kmsg来写入。用户空间可以通过以下几种方法从这个缓冲区中读取:它可以从/proc /kmsg读取(默认情况下是dmesg),或者它可以从/dev /kmsg读取,或者可以调用系统调用 syslog(),这在man中有描述2 syslog与man 3 syslog中描述的glibc function syslog()完全不同。 glibc实际上为系统调用 syslog()提供了一个封装器,称为 klogctl(),以帮助缓解这种混乱。
传统上,klogd
从其中一个接口读取,然后调用glibc函数syslog()
将它们复制到syslog中。 rsyslogd通过其imklog
输入模块读取其中一个接口,但AFAIK不打扰调用glibc syslog()
,这就是为什么它不像klogd;它只是处理imklog
的输出,就像处理来自任何其他输入模块的输出一样。还有一点需要注意,所有imklog
输出都具有kern
功能,而不管内核环形缓冲区中的设施消息如何。
参考
-
http://upstart.ubuntu.com/cookbook/#initctl-log-priority(错误地指出Upstart记录到syslog)
-
https://www.kernel.org/doc/Documentation/ABI/testing/dev-kmsg
-
http://www.gnu.org/software/libc/manual/html_node/Overview-of-Syslog.html
-
http://www.rsyslog.com/doc/v5-stable/configuration/modules/imklog.html(请注意,这是针对v5的,在Ubuntu 12.04中使用。这些选项在最近的rsyslog版本中被认为是遗留的)
次佳解决思路
我在/var/log/upstart/
找到了我的