例如,我有一个使用sd_journal_send进行写入的应用程序。而不是更改应用程序,我尝试通过-v /var/log/systemd/journal:/var/log/systemd/journal进行传递。
它在我的Ubuntu 16.04桌面上运行良好,但在使用Ubuntu 16.04基础镜像的CoreOS实例上没有运行。 我不太明白为什么。也许有更好的发送到journal的方法?
Docker journald输出日志选项有哪些限制?它似乎不支持应用程序编写除消息字段之外的内容。
所以我发现我需要 -v /dev/log:/dev/log
但还存在另一个问题,即没有与启动docker容器的服务文件关联。手动添加UNIT:servicename.service并未解决问题。因此,在查看和运输服务日志时,它与exe关联而不是容器或服务。谁遇到了这些问题,你是如何解决的?
扩展一下,C程序可以像这样写入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;
}
这将写入日志并添加自定义字段,如HOME、TERM、PAGE_SIZE等。当我使用journalbeat将它们发送到ELK堆栈时,这些字段会很好地出现在elasticsearch中,我可以直接搜索它们。
然而,似乎docker只是简单地获取应用程序的stdout,并将其提供给journald,并仅添加了一些自己的字段,例如CONTAINER_ID。
当在docker容器中使用此类程序,然后从服务文件运行它们时,会产生一些问题。
1)我必须通过一些目录和设备文件来使其使用sd_journal_send进行写入。
2)如果您从systemd .service文件启动容器,并希望使用journalctl -u servicename查看消息,则不会看到这些日志消息,因为它们通过不同的路径进入日志,且与运行它们的服务无关联。
3)您可以使用docker的journald日志记录驱动程序添加一些任意字段/标签,但它们是固定的、一次性的添加,将出现在每个发送的消息中,且不会发生变化。它们不像上面C代码中想要的动态字段。
本质上,journald日志驱动程序在我的情况下是不够的。
有没有建议如何链接服务名称,以便journalctl -u显示来自sd_journal_send的日志消息?因为这样就可以解决问题了。
-- 我已经找到了一个解决方案。如果其他人对我是如何解决它感兴趣,我将在下面提供答案。
journalctl -u
会将其视为另一个单元。Docker是问题所在。我将不得不深入源代码并查看docker中sysyemd日志驱动程序支持的内容。可能需要进行扩展。 - hookenzvagrant@vagrant:~/journald$ gcc test.c /tmp/ccLHPQPH.o: In function
main': test.c:(.text+0x8b): undefined reference tosd_journal_send_with_location' collect2: error: ld returned 1 exit status
- Tarun Lalwani