Разница между ** journalctl -u test.service ** и ** journalctl CONTAINER_NAME = test **
У меня есть служебный файл systemd, который запускает контейнер докеров с драйвером журнала journald.
ExecStart=/usr/bin/docker run \
--name ${CONTAINER_NAME} \
-p ${PORT}:8080 \
--add-host ${DNS} \
-v /etc/localtime:/etc/localtime:ro \
--log-driver=journald \
--log-opt tag="docker.{{.Name}}" \
${RESPOSITORY_NAME}/${CONTAINER_NAME}
ExecStop=-/usr/bin/docker stop ${CONTAINER_NAME}
Когда я проверяю журналы через journalctl, я вижу два разных _TRANSPORT. С journalctl -u test.service я вижу _TRANSPORT = stdout. И с Journalctl CONTAINER_NAME=test я вижу _TRANSPORT=journal
В чем разница?
1 ответ
Разница здесь в том, как журналы попадают в systemd-journald
прежде, чем они будут зарегистрированы.
На данный момент поддерживаемые транспорты (по крайней мере, согласно _TRANSPORT
поле в systemd-journald
): аудит, драйвер, системный журнал, журнал, стандартный вывод и ядро (см. systemd.journal-fields(7)).
В вашем случае все зарегистрировано в stdout
командами, выполняемыми ExecStart=
а также ExecStop=
директивы регистрируются под _TRANSPORT=stdout
транспорт.
Однако Docker внутренне способен использовать драйвер ведения журнала journald, который, среди прочего, вводит несколько настраиваемых полей журнала, одно из которых являетсяCONTAINER_ID=
. Это просто другой метод доставки данныхsystemd-journald
- вместо того, чтобы полагаться на systemd, чтобы поймать и отправить все от stdout до systemd-journald
, Docker внутренне отправляет все прямо в systemd-journald
сам по себе.
Этого можно добиться, используя sd-journal
API (как описано в sd-journal(3)). Docker использует привязки Go -systemd дляsd-journal
Библиотека C.
Простой пример:
hello.c
#include <stdio.h>
#include <systemd/sd-journal.h>
int main(void)
{
printf("Hello from stdout\n");
sd_journal_print(LOG_INFO, "Hello from journald");
return 0;
}
# gcc -o /var/tmp/hello -lsystemd hello.c
# cat > /etc/systemd/system/hello.service << EOF
[Service]
ExecStart=/var/tmp/hello
EOF
# systemctl daemon-reload
# systemctl start test.service
Теперь, если я проверю журнал, я увижу оба сообщения:
# journalctl -u hello.service
-- Logs begin at Mon 2019-09-30 22:08:02 CEST, end at Fri 2020-03-27 17:11:29 CET. --
Mar 27 17:08:28 localhost systemd[1]: Started hello.service.
Mar 27 17:08:28 localhost hello[921852]: Hello from journald
Mar 27 17:08:28 localhost hello[921852]: Hello from stdout
Mar 27 17:08:28 localhost systemd[1]: hello.service: Succeeded.
Но каждый из них прибыл на своем транспорте:
# journalctl -u hello.service _TRANSPORT=stdout
-- Logs begin at Mon 2019-09-30 22:08:02 CEST, end at Fri 2020-03-27 17:12:29 CET. --
Mar 27 17:08:28 localhost hello[921852]: Hello from stdout
# journalctl -u hello.service _TRANSPORT=journal
-- Logs begin at Mon 2019-09-30 22:08:02 CEST, end at Fri 2020-03-27 17:12:29 CET. --
Mar 27 17:08:28 localhost systemd[1]: Started hello.service.
Mar 27 17:08:28 localhost hello[921852]: Hello from journald
Mar 27 17:08:28 localhost systemd[1]: hello.service: Succeeded.