如何在 bash systemd 单元中添加自定义日志字段值

如何在 bash systemd 单元中添加自定义日志字段值

我有运行 bash 文件的 systemd 服务。该脚本的所有输出都会记录在 systemd 日志中,并由 systemd 正确归因于相应的单元:

# myservice.sh
echo "PROGRESS 1/5"
echo "PROGRESS 2/5"
echo "PROGRESS 3/10"
echo "PROGRESS 9/10"
> journalctl -eu my-service
oct. 19 16:01:38 my-computer systemd[1]: Started My service.
oct. 19 16:01:40 my-computer my-service[137083]: PROGRESS: 1/5
oct. 19 16:01:42 my-computer my-service[137083]: PROGRESS: 2/5
oct. 19 16:01:44 my-computer my-service[137083]: PROGRESS: 3/10
oct. 19 16:01:46 my-computer my-service[137083]: PROGRESS: 9/10
oct. 19 16:01:46 my-computer systemd[1]: my-service.service: Succeeded.

但是,我想通过添加新字段在日志条目中添加其他信息。我尝试使用logger此方法但没有成功:字段未正确存储,并且记录的行未标记为来自 my-service.service。

# myservice.sh
function log_progress() {
    logger --tag my-service --priority user.info \
           --rfc5424
           --sd-id lcupdater@1 \
           --sd-param "PROGRESS_VALUE=\"$2\"" \
           --sd-param "PROGRESS_TO=\"$3\"" \
            "$1"
}

log_progress "Doing stuff" 1 5
log_progress "Doing more stuff" 2 5
log_progress "Going on..." 3 10
log_progress "Almost done..." 9 10

> journalctl -e -o json
{
  "_UID": "0",
  "_GID": "0",
  "_PID": "147370",
  "_SOURCE_REALTIME_TIMESTAMP": "1603120378691356",
  "MESSAGE": "1 2020-10-19T17:12:58.691328+02:00 my-computer my-service - - [timeQuality tzKnown=\"1\" isSynced=\"1\" syncAccuracy=\"132000\"][lcupdater@1 PROGRESS_VALUE=\"9\" PROGRESS_TO=\"10\"] Almost d
one...",
  "__MONOTONIC_TIMESTAMP": "28976809066",
  "_TRANSPORT": "syslog",
  "SYSLOG_RAW": "<14>1 2020-10-19T17:12:58.691328+02:00 my-computer my-service - - [timeQuality tzKnown=\"1\" isSynced=\"1\" syncAccuracy=\"132000\"][lcupdater@1 PROGRESS_VALUE=\"9\" PROGRESS_TO=\"10\"] A
lmost done...",
  "SYSLOG_FACILITY": "1",
  "PRIORITY": "6",
  "__REALTIME_TIMESTAMP": "1603120378691368"
}

字段 _SYSLOG_UNIT 丢失,PROGRESS_VALUE 和 PROGRESS_TO 未正确存储。有办法实现这一点吗?

编辑:

实现此目的的一种详细但更正确的方法是使用logger --journald

function log_progress() {
    logger --journald <<EOF
MESSAGE=$1
PROGRESS_VALUE=$2
PROGRESS_TO=$3
SYSLOG_IDENTIFIER=my-service
SYSLOG_FACILITY=3
PRIORITY=6
_SYSTEMD_UNIT=my-service.service
EOF
}

但是,字段 _SYSTEMD_UNIT 被删除,因为只允许 systemd 操作它。

答案1

绝对可以根据systemd.journal-fields文档(“新字段可以由应用程序自由定义,[...]”但是我找到的唯一解决方案通过journald-socket 和c-library 使用本机消息传递。我还没有找到任何可以在 shell 脚本中轻松使用的东西,甚至没有系统猫接受 json 作为输入。

到目前为止,最简单的方法可能是用 python 重写应用程序并使用systemd.journal-模块

相关内容