通常,日志消息被写入stderr。我想知道拆分日志消息是否是一个好主意/实践,这样就可以将错误和警告发送到stderr,而将调试/信息/通知消息转到stdout?或者,考虑到许多专用日志进程都只从stdin读取,这是否与此无关,因为stderr和stdout中的源日志消息需要合并并重定向到记录器的stdin。
更新
下面的两个答案都提到了syslog,我认为我需要详细澄清设置。
我询问的守护进程正在前景中自行运行。such是通过监视进程(如runit或supervisord )来管理的。在这两种情况下,守护进程的stderr和stdout将被监控进程捕获,监控进程的任务是决定如何和在何处存储日志(可能是syslog,或者在UDP网络中的其他地方)。守护进程不必担心写入日志的内容和位置,因为它们只是写到stdout/stderr。
对于runit,它的日志记录工具svlogd将从它的stdin中读取重定向日志消息,这些日志消息是托管守护进程的stderr/stdout组合的。至于supervisord,它可以记录stderr和stdout以分离日志文件。
因此,在这种特定的设置中,在stderr和stdout之间拆分日志,还是只写其中一个日志,是一个很好的实践吗?
发布于 2014-08-20 19:30:47
我不建议将stdout和stderr混合在您的程序中,但是如何在程序外部处理它取决于您。stdout用于处理用于管道的数据,而stderr则专门用于非数据消息。这使得某些行为成为可能,例如批处理,而不改变现有的交互行为。你的情况不一样
因为runit在通过svlog进行日志记录方面有一点不同,而且您正在编写的服务很可能不会去守护(在本例中,这意味着“从tty中分离”),所以如果您想要通过/etc/sv/<servicename>/run脚本将所有内容捕获到单个日志中,那么就由您自己决定。在大多数情况下,大多数运行脚本使用
exec 2>&1 将这两个流融合在一起,因为大多数服务不会通过stdout传递数据。如果您确实想使用svlog,您需要在/etc/sv/<servicename>/log/run上创建一个脚本,并使用适当的命令来启动它。它看起来可能类似(但不完全类似)如下:
#!/bin/sh
exec 2>&1
exec svlog -tt main其中main是指向日志目录的符号链接。
发布于 2013-03-10 06:44:54
首先,一些需要澄清的重要内容:STDOUT和STDERR在守护进程成功启动后很少与其上下文相关,除非您正在使用调试开关调用它们。
守护进程的全部要点是,它需要与控制终端脱离关联,以便在注销后保持不变。一旦没有终端,所有消息都需要发送到syslog守护进程或由进程直接管理的日志文件。
如果您实际上并不是指守护进程,而实际上是指您自己编写的任何shell脚本或类似的shell脚本,那么逻辑应该是这样的:
STDOUT:您希望被管道或基本输出重定向所困的任何东西。STDERR:“带外”消息。不管怎么说,你想要的东西都会撞到某人的终端,即使他们在做某种重定向。(因此,它们与错误相关联)让用户决定是否也要重定向这些消息,如您所提到的将STDERR重定向到STDIN。发布于 2013-03-10 06:45:52
如果是守护进程,我建议使用syslog接口将消息直接记录到日志。运行"man 3 syslog“获取信息。如果有必要,您的程序还可以有一个debug选项(参数指定优先级),它告诉守护进程程序不要在后台运行,也可以登录到stderr。
我会编写一个以优先级和字符串作为参数的日志记录函数。它应该调用syslog()来正确地记录消息,如果优先级大于或等于全局调试优先级值,则将消息输出到stderr和syslog()。调用syslog(..., "%s", msg)以避免消息中的百分比字符被搞砸。(或者使您的函数接受可变数量的参数,并将arglist传递给vsyslog())。
确保在程序初始化时调用openlog(..., LOG_PID, LOG_DAEMON)。如果您处于调试模式,可以在| LOG_PERROR之后添加LOG_DAEMON,这将避免编写上面提到的日志记录函数。但是这样你就失去了根据优先级进行过滤的能力。
您可能(如果使用Ubuntu)需要配置/etc/rsyslog.conf以确保记录守护进程消息。
PS -如果守护进程是shell脚本,请使用logger命令。
https://serverfault.com/questions/486370
复制相似问题