从 docker 容器内将结构化日志写入日志的最佳方法是什么?
例如,我有一个使用sd_journal_send写入的应用程序 ,我没有更改应用程序,而是尝试通过
-v /var/log/systemd/journal:/var/log/systemd/journal
它适用于我的 Ubuntu 16.04 桌面,但不适用于运行应用程序的 CoreOS 实例(使用 Ubuntu 16.04 基础映像)。我不太明白为什么。也许有更好的方式发送到期刊?
docker Journald 输出日志记录选项有哪些限制?它似乎不支持应用程序写入的内容不仅仅是消息字段。
--
所以我发现我需要-v /dev/log:/dev/log
但还有一个问题就是与启动docker容器的服务文件没有关联。手动添加 UNIT: servicename.service 没有解决问题。因此,在查看和传送服务日志时,它与 exe 相关联,但与容器或服务无关。谁遇到过这些问题,您是如何解决的?
——好吧,让我稍微扩展一下。
AC 程序可以像这样写入 systemd 日志:
#include <systemd/sd-journal.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
sd_journal_send("MESSAGE=Hello World!",
"MESSAGE_ID=52fb62f99e2c49d89cfbf9d6de5e3555",
"PRIORITY=5",
"HOME=%s", getenv("HOME"),
"TERM=%s", getenv("TERM"),
"PAGE_SIZE=%li", sysconf(_SC_PAGESIZE),
"N_CPUS=%li", sysconf(_SC_NPROCESSORS_ONLN),
NULL);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这会写入日志并添加自定义字段,如 HOME、TERM、PAGE_SIZE 等。当我使用 Journalbeat 将它们发送到 ELK 堆栈时,这些字段最终会很好地出现在 elasticsearch 中,我可以直接搜索它们。
然而,docker 似乎只是简单地获取应用程序的标准输出,并将其提供给日志,仅包含它自己添加的几个字段。例如 CONTAINER_ID。
当在 Docker 容器内使用这样的程序然后从服务文件运行它们时,会产生一个小问题。
1)我必须传递一些目录和设备文件才能使用 …
我的印象是,可能有一种方法可以直接将 json 数据写入 systemd 日志,而无需先将其转换为sd_journal*函数期望的格式。这可能吗?
我的怀疑是因为一些关于内置 json 解析器的评论。然而,手册页另有建议。
另外,我注意到如果您以格式写入标准输出
<priority> message
Run Code Online (Sandbox Code Playgroud)
优先级将在 PRIORITY="priority" 字段中结束,消息将在 MESSAGE="message" 字段中结束。但是可以输入其他结构化的字段数据吗?
注意:手册页没有讨论我提到的最后一个特性。因此,如果它们稍微过时,我不会感到惊讶,这就是我问的原因。