【问题标题】:Is there a way to redirect all stdout and stderr to systemd journal from within script?有没有办法从脚本中将所有 stdout 和 stderr 重定向到 systemd 日志?
【发布时间】:2019-06-21 00:25:35
【问题描述】:

我喜欢使用 systemd 的日志来查看和管理我自己的脚本日志的想法。我知道您可以根据每条消息从我的用户脚本登录到日志。

echo 'hello' | systemd-cat -t myscript -p emerg

有没有办法将所有消息重定向到日志,即使是由其他命令生成的消息?喜欢..

exec &> systemd-cat

更新:

部分成功。 从终端尝试了Inian的建议。

~/scripts/myscript.sh 2>&1 | systemd-cat -t myscript.sh

它起作用了,stdout 和 stderr 被定向到 systemd 的日志。 奇怪的是,

~/scripts/myscript.sh &> | systemd-cat -t myscript.sh

在我的 Bash 终端中不起作用。

当其他程序调用我的脚本时,我仍然需要在我的脚本中找到一种方法。

我试过了..

exec 2>&1 | systemd-cat -t myscript.sh

但它不起作用。

更新 2

从终端

systemd-cat ~/scripts/myscript.sh

有效。但我仍在寻找从脚本中执行此操作的方法。

【问题讨论】:

  • 哪个应用程序生成这些日志? shell 脚本或其他用户应用程序?
  • 来自我的个人 shell 脚本
  • your-script.sh &> | systemd-cat -t myscript 运行它不起作用吗?
  • 嗯。我没试过……
  • 不确定错误来自哪里,可能不是&>,你可以试试~/scripts/test.sh 2>&1 | systemd-cat -t test.sh

标签: bash logging stdout stderr systemd-journald


【解决方案1】:

显然,出于我无法理解的原因,您不能真正将所有 stdout 和 stderr 从脚本中重定向到 journald,因为它必须通过管道输入。为了解决这个问题,我发现了人们在 syslog 中使用的一个技巧记录器,其工作方式类似。

您可以将所有代码包装到一个函数中,然后将该函数通过管道传输到 systemd-cat。

#!/bin/bash

mycode(){
  echo "hello world"
  echor "echo typo producing error"
}
mycode | systemd-cat -t myscript.sh

exit 0

然后搜索日志日志..

journalctl -t myscript.sh --since yesterday

我很失望没有更直接的方法来做到这一点。

【讨论】:

    【解决方案2】:

    systemd-cat 的管道是一个需要与您的脚本同时运行的进程。 Bash 为此提供了一个工具,尽管它不能移植到 POSIX sh

    exec > >(systemd-cat -t myscript -p emerg) 2>&1
    

    >(command) 进程替换会启动另一个进程并返回一个伪文件名(类似于/dev/fd/63),您可以重定向到该伪文件名。如果您想将其移植到 POSIX sh,这基本上是 mkfifo hacks 的包装器。

    【讨论】:

    • 你可以使用你的脚本路径作为标签:-t $(realpath "$0")你可以为你的stderr设置不同的优先级:2> >(... -p err)结果为:exec > >(systemd-cat -t "$(realpath "$0")" -p info ) 2> >(systemd-cat -t "$(realpath "$0")" -p err )
    【解决方案3】:

    如果您的脚本碰巧不是 shell 脚本,而是其他允许加载链接到 -lsystemd 的扩展模块的编程语言,还有另一种方法。有一个库函数sd_journal_stream_fd 与手头的任务完全匹配。从 bash 本身(而不是某些孩子)调用它似乎充其量是困难的。例如,在 Python 中,它以 systemd.journal.stream 的形式提供。这个函数本质上是连接一个unix域流套接字并传达正在传输的数据类型(例如优先级)。在这里使用 shell 的困难部分是让它连接一个 unix 域套接字(而不是在一个孩子中连接)。

    此答案的关键思想由 Freenode/libera.chat 用户 grawity 给出。

    【讨论】:

      猜你喜欢
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 2014-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多