我正在更新一套适用于 RHEL7 的程序,其中一些C++, 一些爪哇。如果它们作为 systemd 服务启动,我希望它们写入 systemd 日志。如果它们直接在终端运行,例如为了测试,我希望它们写入标准输出。我怎样才能最优雅地做到这一点?
我想利用日志的高级功能——记录严重性、文件名、行号、线程名等——所以简单地写入标准输出是不够的。
我所做的搜索得到了检查进程的父 PID 或检查其 cgroup 的建议。有没有更好的办法?这些看起来像是笨拙的解决方案。理想情况下,有一个我可以调用的函数,或者一个要检查的环境变量。
附加信息:
- 为了C++我计划调用的程序sd_journal_print(3)。
- 为了爪哇程序我打算使用SLF4J + Logback +logback日志。
(我的后备计划是使用命令行开关,但自动检测肯定会很好。)
答案1
在 systemd 版本 231 中,JOURNAL_STREAM
为此目的引入了环境变量。您的程序检查其值,将其值与其标准错误的设备和 i 节点号进行比较,并相应地更改其行为。
什么时候不是连接到日志后,您(当然)可以始终使用诸如 JSON 之类的东西(每个对象一行)写入标准错误,以便在那里也有结构化日志记录。 RFC 5424 还具有(更有限的)结构化数据选项。
答案2
systemd
已经为您优雅地处理了这种情况,如中所述系统执行程序。
登录到标准输出。当通过 systemd 运行时,systemd 将默认将 STDOUT 重定向到日志。
另一种选择是journal+console
如果您总是想同时登录两者。
记录到 STDOUT 也是一种最佳实践12 要素应用程序设计。