Назад | Перейти на главную страницу

Journald не регистрирует сообщения об ошибках перед неудачным завершением программы.

Я вызываю модуль python3 с помощью systemd (версия: systemd 232) на debian stretch. Проблема в том, что если модуль python вызывает исключение, сообщение об исключении (stderr) и некоторые предыдущие распечатки (stdout) не выводятся в журнал до того, как модуль завершится с ошибкой.

Конфигурация сервиса выглядит так:

[Unit]
Description=Some Service
After=network.target

StartLimitIntervalSec=3
StartLimitBurst=2

[Service]
User=foo

PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir -p /var/run/foo
ExecStartPre=/bin/chown user:user /var/run/foo/

Type=simple
PIDFile=/var/run/foo/foo.pid
ExecStart=/usr/local/bin/foo_continual
Restart=always
RestartPreventExitStatus=0
RestartSec=2

StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

foo_continual - это сценарий bash, который настраивает виртуальную среду Python, а затем запускает модуль Python:

#!/bin/bash
source /home/foo/environment/bin/activate || exit 1
python -u -m foo.main || exit 1

Скрипт содержит некоторые print() звонки. Я даже тестировал flush=True к одному из них, и он содержит исключение, которое должно быть напечатано в stderr и заставит программу выйти с кодом выхода, отличным от 0. Проблема в том, что журналы journald не содержат полного вывода, включая сообщение об ошибке:

Dec 01 18:32:07 TESTING systemd[1]: foo.service: Service hold-off time over, scheduling restart.
Dec 01 18:32:07 TESTING systemd[1]: Stopped Some Service.
Dec 01 18:32:07 TESTING systemd[1]: Started Some Service.
Dec 01 18:32:08 TESTING foo_continual[50903]: Print some stuff...
Dec 01 18:32:08 TESTING systemd[1]: foo.service: Main process exited, code=exited, status=1/FAILURE
Dec 01 18:32:08 TESTING systemd[1]: foo.service: Unit entered failed state.
Dec 01 18:32:08 TESTING systemd[1]: foo.service: Failed with result 'exit-code'.
Dec 01 18:32:10 TESTING systemd[1]: foo.service: Service hold-off time over, scheduling restart.
Dec 01 18:32:10 TESTING systemd[1]: Stopped Some Service.
Dec 01 18:32:10 TESTING systemd[1]: Started Some Service.
Dec 01 18:32:10 TESTING systemd[1]: foo.service: Main process exited, code=exited, status=1/FAILURE

Он должен напечатать больше текста, включая ошибку в stderr после «Напечатать кое-что». Как я могу заставить jorunald записывать весь вывод перед выходом из программы?

Единственное решение, которое я нашел, не очень хорошее, но оно работает. В файле bash засыпайте перед выходом, чтобы дать журналу возможность записать вывод:

#!/bin/bash
function fail {
    sleep 2
    exit 1
}
source /home/foo/environment/bin/activate || fail
python -u -m foo.main || fail