Разница между ** 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-journalAPI (как описано в 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.
Другие вопросы по тегам