Должна ли программа переднего плана вызываться журналом разбиения демона между stderr и stdout на основе уровней серьезности?

Обычно сообщения журнала записываются в stderr. Мне интересно, будет ли хорошей идеей / практикой разделять сообщения журнала, чтобы ошибки и предупреждения отправлялись в stderr, а сообщения отладки / информационные / уведомления отправлялись в stdout? Или это не имеет значения, учитывая, что многие выделенные процессы ведения журнала все равно читают только из stdin, что требует объединения исходных сообщений журнала в stderr и stdout и перенаправления их в stdin logger.

[Обновить]

Два ответа ниже оба упомянули системный журнал, я думаю, что мне нужно уточнить настройку в деталях.

Запрошенные мной процессы-демоны работают на переднем плане сами по себе. Демонизация управляется контролирующими процессами, такими как runit или же supervisord, В обоих случаях stderr и stdout процессов-демонов будут захвачены контролирующими процессами, и задача контролирующих процессов - решить, как и где хранить журналы (может быть syslog или где-то еще в сети через UDP)., Процессы-демоны не должны беспокоиться о том, что и где писать логи, поскольку они просто пишут в stdout /stderr.

В случае runit, его каротаж svlogd будет читать из его стандартного перенаправленного сообщения журнала, которые объединены в stderr /stdout управляемого процесса демона. Что касается supervisord, он может записывать stderr и stdout в отдельные файлы журнала.

Таким образом, в этих конкретных настройках рекомендуется разделять журналы между stderr и stdout или просто записывать в один из них?

4 ответа

Решение

Я бы не советовал совмещать stdout и stderr внутри вашей программы, но как вы справляетесь с этим снаружи, зависит от вас. stdout был предназначен для обработанных данных, предназначенных для конвейера, в то время как stderr специально для сообщений без данных. Это делает возможным определенное поведение, такое как пакетная обработка, без изменения существующего интерактивного поведения. Ваш случай отличается - есть хороший шанс, что stdout значит мало или ничего.

Так как runit немного отличается от входа через svlogи служба, которую вы пишете, скорее всего, не будет демонизирована (что в данном случае означает "отключение от tty"), тогда вам решать, хотите ли вы записать все в один журнал или нет через /etc/sv/<servicename>/run скрипт. По большей части большинство запускаемых скриптов используют

exec 2>&1 

объединить два потока, так как большинство служб не передают данные через стандартный вывод. Если вы хотите использовать svlog вам нужно будет создать скрипт на /etc/sv/<servicename>/log/run с соответствующей командой, чтобы запустить его. Это, вероятно, выглядит примерно так (но не совсем так):

#!/bin/sh
exec 2>&1
exec svlog -tt main

где main символическая ссылка на каталог журналов

Во-первых, кое-что важное, чтобы уточнить: STDOUT а также STDERR редко бывают релевантными в контексте процесса демона после его успешного запуска, если только вы не вызываете его с переключателем отладки.

Весь смысл демона в том, что он должен отмежеваться от наличия управляющего терминала, чтобы он мог сохраняться после выхода из системы. Если терминала нет, все сообщения необходимо отправлять либо демону syslog, либо файлу журнала, управляемому непосредственно процессом.

Если вы на самом деле не имеете в виду демонов и на самом деле имеете в виду какой-либо сценарий оболочки или аналогичный, который вы пишете сами, тогда логика должна быть такой:

  • STDOUT: Все, что вы хотите, чтобы быть пойманным в ловушку с помощью каналов или основного перенаправления вывода.
  • STDERR: Сообщения "Out of band". Вещи, которые вы хотите поразить чей-то терминал, в любом случае, даже если они делают какое-то перенаправление. (следовательно, почему они связаны с ошибками). Позвольте пользователю решить, хотят ли они также перенаправить эти сообщения, т.е. STDERR в STDIN как вы упомянули.

Я не думаю, что вы должны использовать как stdout, так и stderr для регистрации. Если у вас есть сообщения журнала с различной степенью важности, они должны быть помечены префиксом, чтобы их было легко фильтровать / сортировать с помощью svlogd,

Я бы сказал, что использование как stdout, так и stderr для регистрации нарушит принцип наименьшего удивления.

Если это демон, я рекомендую использовать интерфейс системного журнала для записи ваших сообщений непосредственно в журналы. Запустите "man 3 syslog" для информации. При необходимости ваша программа также может иметь опцию отладки (с параметром, который задает приоритет), который говорит программе-демону не запускаться в фоновом режиме, а также регистрироваться в stderr.

Я бы написал функцию регистрации, которая принимает приоритет и строку в качестве аргумента. Он должен вызвать syslog() для правильной регистрации сообщения, и, если приоритет больше или равен значению глобального приоритета отладки, вывести сообщение в stderr, а также syslog(). Вызов syslog(..., "%s", msg) чтобы избежать процентов символов в сообщении от провала. (Или заставьте вашу функцию принимать переменное число аргументов и передать arglist в vsyslog().)

Убедитесь, что вы звоните openlog(..., LOG_PID, LOG_DAEMON) в инициализации вашей программы. Вы можете добавить | LOG_PERROR после LOG_DAEMON, если вы находитесь в режиме отладки, что позволит избежать написания функции регистрации, упомянутой выше. Но тогда вы потеряете способность фильтровать по приоритету.

Вы можете (если используете Ubuntu) настроить /etc/rsyslog.conf чтобы гарантировать, что сообщения демона регистрируются.

PS - используйте команду logger, если ваш демон является сценарием оболочки

Другие вопросы по тегам