守护进程调用的前台程序是否应该根据严重性级别在stderr和stdout之间分割日志logging?

通常日志消息被写入stderr。 我想知道如果这是一个好主意/实践分裂日志消息,以便错误和警告转到标准错误,而debugging/信息/通知消息转到标准输出,而不是? 或者这是不相干的,因为许多专用的日志logging过程只能从stdin读取,这需要将stderr和stdout中的源日志消息合并,并redirect到logging器的stdin。

[更新]

下面的两个答案都提到了syslog,我想我需要详细说明安装。

我问的守护进程自己在前台运行。 守护进程由监督进程(如runitsupervisord 。 在这两种情况下,守护进程的stderr和stdout都将被监督进程捕获,监督进程的工作是决定如何以及在哪里存储日志(可能是syslog,或者通过UDP在networking上的其他地方) 。 守护进程不必担心写什么和在哪里写日志,因为他们只是写入标准输出/标准错误。

runit的情况下,其日志logging工具svlogd将从stdin中读取redirect的日志消息,这些日志消息与managed守护进程的stderr / stdout组合在一起。 至于supervisord ,它可以loggingstderr和stdout来分离日志文件。

所以在这个特定的设置中,将stderr和stdout之间的日志分开,还是写入其中之一是一个好习惯?

我不会build议你的程序混合stdout和stderr,但是你在外面如何处理它取决于你。 stdout是专门用于stream水线的处理数据,而stderr专门用于非数据消息。 这使得某些行为成为可能,例如批处理,而不改变现有的交互行为。 你的情况是不同的 – 有一个很好的机会stdout意味着什么也没有。

因为runit有一点不同,所以你写的服务很可能不会守护进程(在这种情况下,这意味着“从tty分离”),那么如果你想捕获所有的东西通过/etc/sv/<servicename>/run脚本/etc/sv/<servicename>/run单个日志。 大多数运行脚本使用

 exec 2>&1 

将两个stream融合在一起,因为大多数服务不通过stdout传递数据。 如果你想使用svlog你需要在/etc/sv/<servicename>/log/run用相应的命令创build一个脚本来启动它。 它可能看起来相似(但不完全一样):

 #!/bin/sh exec 2>&1 exec svlog -tt main 

其中main是一个logging目录的符号链接。

首先,需要澄清一些重要的事情:一旦成功启动,守护进程中的STDOUTSTDERR就很less相关,除非您正在调用带有debugging开关的进程。

守护进程的重点在于它需要与控制terminal断开连接,以便在注销后可以保留。 一旦没有terminal,所有消息都需要发送到syslog守护进程或由进程直接pipe理的日志文件。

如果你实际上不是指守护进程,而只是指你自己编写的任何shell脚本或类似文件,那么逻辑通常应该是这样的:

  • STDOUT :任何你想被pipe道或基本输出redirect困住。
  • STDERR :“带外”消息。 无论如何,即使他们正在做某种redirect,也要打到别人的terminal。 (因此为什么它们与错误相关)让用户决定是否也要redirect这些消息,也就是说,像前面提到的那样,将STDERRredirect到STDIN

如果是守护进程,我build议使用syslog接口将消息直接logging到日志中。 运行“man 3 syslog”获取信息。 如有必要,程序还可以有一个debugging选项(带有一个指定优先级的参数),它告诉守护程序不要在后台运行,也可以login到stderr。

我会写一个日志函数,它将一个优先级和string作为参数。 它应该调用syslog()来正确logging消息,如果优先级大于或等于全局debugging优先级值,则将消息输出到stderr以及syslog()。 调用syslog(..., "%s", msg)以避免消息中的百分比字符被搞乱。 (或者让你的函数获取可变数量的参数并将parameter passing给vsyslog()。)

确保在程序初始化时调用openlog(..., LOG_PID, LOG_DAEMON) 。 你可以添加| LOG_PERROR | LOG_PERROR后的LOG_PERROR如果处于debugging模式,这将避免必须写上述日志loggingfunction。 但是你会失去根据优先级进行过滤的能力。

你可能(如果使用Ubuntu的话)需要configuration/etc/rsyslog.conf来确保守护进程消息被logging。

PS – 如果守护进程是shell脚本,则使用logger命令

我不认为你应该同时使用stdout和stderr进行日志logging。 如果您的日志消息具有不同的严重性,则应该使用前缀对其进行标记,以便使用svlogd对其进行过滤/sorting。

我认为使用stdout和stderr进行日志logging将违反最less惊喜的原则。