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

Rio*_*Rio 7 logging daemon stderr stdin stdout

通常日志消息写入 stderr。我想知道拆分日志消息是否是一个好主意/实践,以便错误和警告转到标准错误,而调试/信息/通知消息转到标准输出?或者这是否无关紧要,因为许多专用日志记录进程无论如何只能从 stdin 读取,这需要将 stderr 和 stdout 中的源日志消息组合起来并重定向到记录器的 stdin。

[更新]

下面的两个答案都提到了系统日志,我想我需要详细说明设置。

我询问的守护进程自己在前台运行。守护进程由监督进程管理,例如runitsupervisord。在这两种情况下,守护进程的 stderr 和 stdout 将被监督进程捕获,并且监督进程的工作是决定如何以及在哪里存储日志(可能是系统日志,或者通过 UDP 网络中的其他地方) . 守护进程不必担心写入日志的内容和位置,因为它们只是写入 stdout/stderr。

在 的情况下runit,其日志记录工具svlogd将从其 stdin 中读取重定向的日志消息,这些消息是托管守护进程的 stderr/stdout 组合。至于supervisord,它可以记录 stderr 和 stdout 以分隔日志文件。

因此,在这种特定设置中,在 stderr 和 stdout 之间拆分日志还是仅写入其中一个是一种好习惯?

And*_*w B 5

首先,一些重要的澄清:STDOUTSTDERR很少的守护进程的框架内有关一旦成功启动,除非你调用一个带有调试开关。

守护进程的全部意义在于它需要将自己与控制终端分离,以便在注销后可以持续存在。一旦没有终端,所有消息都需要发送到系统日志守护程序或由进程直接管理的日志文件。

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

  • STDOUT:任何你想被管道或基本输出重定向捕获的东西。
  • STDERR:“带外”消息。无论如何,即使他们正在执行某种重定向,您也希望访问某人的终端。(因此为什么它们与错误相关联)让用户决定他们是否也想重定向这些消息,即重定向STDERRSTDIN您提到的。

  • 我认为我的答案在编辑后仍然有效。如果正在设计任何类型的前台进程,为了符合[最小惊喜](http://en.wikipedia.org/wiki/Principle_of_least_astonishment)原则,它应该被设计成可以在终端内部运行。在其前面放置一个监督守护进程不应改变软件的设计方式。 (2认同)

Ave*_*yne 4

我不建议在程序中混合 stdout 和 stderr ,但如何在外部处理它取决于你。stdout用于处理管道中的数据,而stderr专门用于非数据消息。这使得某些行为成为可能,例如批处理,而无需改变现有的交互行为。你的情况有所不同 - 标准输出很可能意味着什么。

因为runit通过 进行日志记录的方式略有不同svlog,并且您正在编写的服务很可能不会守护进程(在这种情况下意味着“从 tty 分离”),那么如果您想将所有内容捕获到单个服务,则由您决定通过脚本记录或不记录/etc/sv/<servicename>/run。大多数情况下,大多数运行脚本都使用

exec 2>&1 
Run Code Online (Sandbox Code Playgroud)

将两个流融合在一起,因为大多数服务不通过标准输出传递数据。如果您确实想使用,svlog则需要使用/etc/sv/<servicename>/log/run适当的命令创建一个脚本来启动它。它可能看起来类似于(但不完全相同):

#!/bin/sh
exec 2>&1
exec svlog -tt main
Run Code Online (Sandbox Code Playgroud)

其中main是指向日志目录的符号链接。