我有一个系统,其中运行着多个守护进程(作为 systemd 单元),这些守护进程将日志信息输出到 Arch Linux 中的日志。我想将其中一些单元文件的日志输出定向到一个单独的文本文件中,其位置由我指定,本质上是为单元子集创建一个日志文件。我该如何去做呢?
答案1
更新:对于较新的 systemd 版本(自 systemd 236 起),这实际上是可能的。看系统执行程序为了标准输出和标准误差节。这些支持以下选项(摘录):
这文件路径选项可用于将特定文件系统对象连接到标准输出。语义与 StandardInput= 的相同选项类似,请参见上文。如果路径引用文件系统上的常规文件,则将其打开(如果尚不存在则创建)以便在文件开头写入,但不会截断它。如果标准输入和输出定向到同一文件路径,则仅打开一次,以进行读取、写入和复制。当指定的路径引用文件系统中的 AF_UNIX 套接字时,这特别有用,因为在这种情况下,仅为输入和输出创建单个流连接。
附加:路径与上面的 file:path 类似,但它以附加模式打开文件。
截断:路径与上面的 file:path 类似,但它在打开文件时会截断文件。对于具有多个命令行的单元,例如具有多个 ExecStart= 的 Type=oneshot 服务,或具有 ExecCondition=、ExecStartPre= 或 ExecStartPost= 的服务,输出文件将重新打开,因此会针对每个命令行重新截断。如果输出文件被截断,而另一个进程仍然打开该文件,例如,通过与 ExecStart= 同时运行 ExecReload=,并且另一个进程继续写入该文件而不调整其偏移量,则该文件的文件指针之间的空间两个进程可能会填充 NUL 字节,从而生成稀疏文件。因此,truncate:path 通常仅适用于一次仅运行一个进程的单元,例如具有单个 ExecStart= 且没有 ExecStartPost=、ExecReload=、ExecStop= 或类似内容的服务。
[...]
这FD:名称选项将标准输出连接到套接字单元提供的特定命名文件描述符。名称可以指定为该选项的一部分,后面是“:”字符(例如“fd:foobar”)。如果未指定名称,则隐含名称“stdout”(即“fd”相当于“fd:stdout”)。必须通过 Sockets= 选项提供至少一个定义指定名称的套接字单元,并且文件描述符名称可能与其包含的套接字单元的名称不同。如果找到多个匹配项,则将使用第一个匹配项。有关命名描述符及其顺序的更多详细信息,请参阅 systemd.socket(5) 中的 FileDescriptorName= 。
原答案:
似乎这是不可能的,也是上游不需要的(将 stdout/stderr 重定向到单个文件)参见例如http://lists.freedesktop.org/archives/systemd-devel/2012-March/004705.html- 阅读整个线程以获取更多上下文信息,了解其工作原理。
您可以做的就是记录到系统日志,然后写入单个文件。或者相反,如果该单元调用某个可以自行写入日志的程序,则使用该程序将日志记录到文件中。
您可能还想看看查看systemd服务的stdout/stderr
您已经可以使用当前设置执行的操作是
journalctl -u yourunitname > yourlogfile_for_yourunitname
将单位“yourunitname”的整个日志输出定向到文件中。
在后一部分中,您还应该看看上述邮件列表线程中 Lennart 的提示:
在最近的 systemd 版本上,类似的东西
systemd-journalctl -o cat _SYSTEMD_UNIT=postgresql.service
应该创建一个非常简单的输出,仅包含实际消息而没有其他内容。你甚至可以传递“-f”并使其生效。”
编辑:
实际上,对于较新的 systemd 版本,该命令只是日志控制据我所知,上述长命令与相同journalctl -u yourunitname
,您也可以-f
在那里“跟随”输出(如 tailf 或 tail -f 中所示)。