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

Отключить буферизацию в модульном файле systemd?

Когда я пишу свой unit-файл, я хочу, чтобы весь вывод Exec*-параметры (ExecStartPre=, ExecStartPost=, ExecStart=, and ExecStopPost=) для отправки в журнал. Но, очевидно, вывод каким-то образом буферизуется, поэтому нет никакой уверенности в том, что будет записано в журнал.

В моем юнит-файле (ulftest.service) У меня есть следующий раздел:

...
ExecStartPre=/bin/echo 'Hello'
ExecStartPre=/usr/bin/who
ExecStart=/storage/_test/venv/bin/python /storage/_test/ulftestservice.py
...

Поэтому я ожидал, что будет список зарегистрированных пользователей (4 из меня) и Привет отображается в журнале отдельно от обычных строк «Запуск», «Запуск», «Остановка» и «Остановка».

Это НЕ дело. Это совершенно (по крайней мере для меня) случайность, появятся они или нет.

Я написал небольшой тестовый цикл, который перезапускает службу каждые 2 секунды:

$ for x in `seq 100`; do echo $x; sudo systemctl restart ulftest.service ; sleep 2; done

После запуска вещи я получаю это в журнале:

...
2017-05-10T09:40:36+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:40:38+0000 ulf44 who[27344]: ulf      pts/0        2017-05-04 09:07 (192.168.0.180)
2017-05-10T09:40:38+0000 ulf44 who[27344]: ulf      pts/1        2017-05-04 12:36 (192.168.0.180)
2017-05-10T09:40:38+0000 ulf44 who[27344]: ulf      pts/2        2017-05-05 06:48 (192.168.0.180)
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
...
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/0        2017-05-04 09:07 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/1        2017-05-04 12:36 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/2        2017-05-05 06:48 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/3        2017-05-05 11:44 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
...

Обратите внимание, что для 100 перезапусков я не получаю вывода, большую часть времени я не получаю Привет но я получаю 2 раунда вывода из who но с полным только одним из них.

Я на свежем Ubuntu 16.04. Я также задал похожий вопрос по теме переполнение стека.

Это особенность, ошибка или просто что-то, что я полностью ошибаюсь? Пожалуйста, посоветуй мне!

Помимо очистки стандартного ввода, вы можете использовать unbuffer команда из expect package.i

Ваш файл модуля будет выглядеть примерно так:

... [Service] ExecStart=/usr/bin/unbuffer /path/to/your/scripts.py ...

Другой вариант, который может дать вам немного больше контроля, - это использование stdbuf который вызывает setvbuf() но это работает только в том случае, если процесс, который вы запускаете, не вызывает сам setvbuf (), чтобы аннулировать изменения.

man systemd.exec

Думаю нужно попробовать использовать в своем агрегате StandardOutput=journal

 journal connects standard output with the journal which is accessible via journalctl(1). Note that everything that is written to syslog or kmsg (see below) is
           implicitly stored in the journal as well, the specific two options listed below are hence supersets of this one.