[英]Systemd service and structured logging
I have a systemd service which is of type simple
.我有一个 systemd 服务,它的类型是
simple
。
I want my service to log key-value pairs.我希望我的服务记录键值对。
Up to now my simple service just prints it log to stdout in a custom key-value syntax.到目前为止,我的简单服务只是以自定义键值语法将它的日志打印到标准输出。
I would like to avoid my custom key-value syntax it use an official way to do structured logging.我想避免我的自定义键值语法,它使用官方方式进行结构化日志记录。
Is there a way to use structured logs with systemd?有没有办法在 systemd 中使用结构化日志?
For example my service writes this to stdout:例如,我的服务将其写入标准输出:
{"key1": "value1", "key2": 1234}
It would be great of systemd could read the string as json. systemd 可以将字符串读取为 json 会很棒。
You can log structured data to systemd
and then view it as is or in json format您可以将结构化数据记录到
systemd
,然后按原样或以 json 格式查看
Let's say we log key-value pairs in json format假设我们以 json 格式记录键值对
systemd-cat -t "struct_logs" echo '{"key1": "value1", "key2": 1234}'
Then we read them as is然后我们按原样阅读它们
sudo journalctl -t 'struct_logs' --lines 1 --no-pager
Apr 30 21:46:14 linux-ar struct_logs[17455]: {"key1": "value1", "key2": 1234}
Or in json format或者json格式
sudo journalctl -t 'struct_logs' --lines 1 --no-pager -o json-pretty
{
"__CURSOR" : "s=b6d07ffffffffff2787cea140a0db88a5;i=db8;b=c9b2132ffffffffe5807625fe;m=9fa5b3f81;t=58fffffff87eab;x=6402818ea7e32a5b",
"__REALTIME_TIMESTAMP" : "1556671574343339",
"__MONOTONIC_TIMESTAMP" : "42854989697",
"_BOOT_ID" : "fffffffffffff24ec7a237b5e5807625fe",
"PRIORITY" : "6",
"_MACHINE_ID" : "fffffffffff66c86aaaaaaaaaa",
"_HOSTNAME" : "linux-ar",
"_TRANSPORT" : "stdout",
"_UID" : "1000",
"_GID" : "100",
"SYSLOG_IDENTIFIER" : "struct_logs",
"MESSAGE" : "{\"key1\": \"value1\", \"key2\": 1234}",
"_PID" : "17455"
}
Going further you can recover your exact log messages with the help of jq
更进一步,您可以在
jq
的帮助下恢复准确的日志消息
sudo journalctl -t 'struct_logs' --lines 1 --no-pager -o json-pretty | jq -r '.MESSAGE'
{"key1": "value1", "key2": 1234}
It could be possible also to log custom keys provided that the user has the proper rights to do that.如果用户有适当的权限,也可以记录自定义密钥。 A service should be able to do that
服务应该能够做到这一点
sudo logger --journald <<end
MESSAGE_ID=67feb6ffbaf24c5cbec13c008dd72309
MESSAGE=The dogs bark, but the caravan goes on.
SYSLOG_IDENTIFIER=struct_logs
KEY=bark
VALUE=goes on
end
Hope this helps.希望这可以帮助。
Have a look at Structured logging to journald from within a docker container ;查看从 docker 容器内记录到日志的结构化日志记录; your application should use the
sd_journal_send
method if you want to specify custom fields.如果您想指定自定义字段,您的应用程序应该使用
sd_journal_send
方法。
If your application is unable to do that you can also output json - which will end up in the MESSAGE
field you can then parse yourself.如果您的应用程序无法执行此操作,您还可以输出 json - 它将最终出现在
MESSAGE
字段中,然后您可以自己解析。 For example - I wrote SystemdJournal2Gelf to send the journal entries to Graylog and it also supports json output in the MESSAGE
, sending it to Graylog as separate fields for filtering例如 - 我编写了SystemdJournal2Gelf来将日志条目发送到 Graylog,它还支持
MESSAGE
json 输出,将其作为单独的字段发送到 Graylog 进行过滤
If you don't want to modify the application you could use a separate script - something like this:如果您不想修改应用程序,您可以使用单独的脚本 - 如下所示:
[Service]
ExecStart=/bin/sh -c '/bin/my-app | while read l; do echo "$l" | logger --journald; done'
You could even convert json
to key/value pairs if you want, or use StandardOutput
to send your standard-output to a socket where you have a separate service listening.如果需要,您甚至可以将
json
转换为键/值对,或者使用StandardOutput
将您的标准输出发送到您有单独服务侦听的套接字。
Well, systemd does not make it easy to do structured logging from text stream.好吧,systemd 并没有让从文本流中进行结构化日志记录变得容易。 It want your to take a dependencies on its library and use
sd_journal_send
(see for example http://0pointer.de/blog/projects/journal-submit.html ).它希望您依赖其库并使用
sd_journal_send
(例如参见http://0pointer.de/blog/projects/journal-submit.html )。 I have not found any "text form" standard that allow systemd to understand that your line should not be smushed together in the MESSAGE
fields but rather should be interpreted as a key-value pair.我还没有找到任何允许 systemd 理解您的行不应该在
MESSAGE
字段中混在一起的“文本形式”标准,而应该被解释为键值对。 I guess a solution would be to write a helper process that parse your stdout and then call the systemd logger.我想一个解决方案是编写一个帮助程序来解析您的标准输出,然后调用 systemd 记录器。 You would then pipe your process stdout process into
然后,您将通过管道将您的流程标准输出流程导入
However, I did found this answer that pipe directly into the journald socket.但是,我确实找到了这个答案, 该答案将管道直接插入到日志套接字中。 With clever use of jq, you could write something that exploit that.
通过巧妙地使用 jq,您可以编写一些利用它的东西。 But that seems hacky: I do not know if systemd really intend to keep any compatibility on that socket.
但这似乎很棘手:我不知道 systemd 是否真的打算在该套接字上保持任何兼容性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.