在Ubuntu 13.X上,Upstart日志消息存放在哪里?

在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这样的命令按预期工作。我应该在其他地方寻找它们吗?是否需要更改某个配置设置?
有一个来自Server Fault的问题,有人似乎在Ubuntu 13.04上遇到了相同的问题,还有这里这里可能也在描述同样的问题。遗憾的是,这些问题对于解决问题没有提供线索。
2个回答

编辑 2016-06-02

如果你想要查找一般的"Upstart日志信息",请检查/var/log/upstart/。这是Upstart保存Upstart服务的stdoutstderr的位置。感谢leopd的回答指出了这一点。

如果你正在寻找Upstart本身配置的由initctl log-priority设置并由initctl emit发出的日志信息,请继续阅读!

简短版本

实际上,日志条目应该显示在dmesg中。尽管如此,默认情况下它们不会显示在/var/log中。

如果你想让它们也出现在/var/log里,就在rsyslogd的配置中添加$KLogPermitNonKernelFacility on。我建议创建一个自定义文件,比如/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所做的。这是谜题的第一部分。

第二部分是有一种广泛的观点认为,写入内核环形缓冲区的消息会被内核自动复制到syslog中(至少我一直以为是这样)。事实证明,这实际上是由一个用户空间守护程序来完成的,传统上是klogd,它与syslogd配合使用。显然,rsyslogd取代了syslogd,但似乎也取代了klogd(在末尾的注释中有说明)。
第三部分是从用户空间写入内核环形缓冲区的消息实际上与从内核空间写入的消息不同:它们具有不同的设施。dmesg有一些选项与此交互:-x将显示设施(和优先级),而-u和-k告诉dmesg仅显示用户设施消息和内核设施消息,分别。
现在关键的一点是:默认情况下,rsyslogd在从内核环形缓冲区读取消息时会忽略非内核设施的消息。相关的配置选项是$KLogPermitNonKernelFacility,默认情况下关闭,如果你想让rsyslogd处理这些消息,需要将其打开。请注意,rsyslogd的其余配置将把内核环形缓冲区中的所有消息都视为具有kern设施,而不考虑它们在内核环形缓冲区中的设施。

更多信息

syslog

代码可以通过调用glibc函数syslog()将日志写入syslog,该函数在man 3 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函数syslog()完全不同。实际上,glibc提供了一个名为klogctl()的包装器来调用系统调用syslog(),以帮助消除这种混淆。
传统上,klogd 从这些接口之一读取,然后调用 glibc 函数 syslog() 将它们复制到系统日志中。rsyslogd 通过其 imklog 输入模块之一读取这些接口,但据我所知,它不会打扰调用 glibc 的 syslog(),这就是为什么它不完全像 klogd;它只是处理来自任何其他输入模块的输出,就像处理来自 imklog 的输出一样。还有一个额外的注意事项,即所有 imklog 输出都具有 kern 设施,而与内核环形缓冲区中的消息设施无关。

参考文献


4非常感谢您对为什么这个问题无法解决以及如何修复它进行了深入的解释。在相关问题的答案中提到了dmesg,但如果没有这里给出的上下文,它就毫无意义。 - Bradd Szonye

我在/var/log/upstart/找到了我的。


我在文件 /var/log/upstart/job.log 中找到了我的内容,其中 job 是我的任务的名称。 - Kenny Evitt
据我所知,这就是作业的标准输出(stdout)/标准错误(stderr)的去处。这个问题涉及到Upstart本身的日志消息,与任何特定的作业无关。 - Vanessa Phipps