Рейтинг:0

Установить приоритет INFO/ERROR для сообщений, регистрируемых в журнале через stdout и stderr?

флаг jp

У нас есть много производственных приложений (собственных и сторонних), которые оставляют вход в процесс, который запускает приложение, и просто входят в стандартный вывод за ИНФОРМАЦИЯ и стдерр за ОШИБКА журналы (т.е. только 2 приоритета журналов: ИНФО|ОШИБКА).

С сервисным блоком systemd для приложения это можно настроить следующим образом:

StandardOutput=журнал
StandardError=журнал

Это позволяет devops управлять всем через модули systemd и журнал, чтобы упростить централизованный сбор журналов, мониторинг всего... и им не нужно беспокоиться о поиске и анализе различных журналов в разных форматах/местоположениях для каждого приложения, которое они развертывают.

Журнал systemd имеет систему приоритетов сообщений, совместимую с 7-уровневой системой приоритетов сообщений syslog. ИНФОРМАЦИЯ уровень 6 и ОШИБКА уровень 3. См. ссылки для более подробной информации.

Проблема в том, что systemd/journal, по-видимому, не различает сообщения, записанные в журнал, из stdout и stderr. Сообщения stdout и stderr записываются в журнал с приоритетом по умолчанию 6 (ИНФОРМАЦИЯ).

Пример: «Необычное приложение»

/opt/log-test.sh

#!/бин/баш

эхо "Это ОШИБКА" 1>&2
эхо "Это информация"

выход 0

/etc/systemd/system/log-test.service

[Ед. изм]
Description=проверка журнала для журнала

[Оказание услуг]
Тип=простой

ExecStart=/opt/log-test.sh

StandardOutput=журнал
StandardError=журнал
SyslogIdentifier=лог-тест

запустите его и проверьте журнал

$ systemctl запустить лог-тест
$ journalctl -u лог-тест
-- Журналы начинаются в четверг 07.04.2022, 08:17:16 UTC, заканчиваются в четверг, 07.04.2022, 16:35:02 UTC. --
07 апреля, 16:34:58 host.example.com systemd[1]: начата проверка журнала для журнала.
07 апреля 16:34:58 host.example.com log-test.sh[29909]: это ОШИБКА
07 апреля 16:34:58 host.example.com log-test.sh[29909]: Это ИНФОРМАЦИЯ
$ journalctl -u log-test -p 6 # приоритет информации системного журнала
-- Журналы начинаются в четверг 07.04.2022 08:17:16 UTC, заканчиваются в четверг 07.04.2022 16:35:08 UTC. --
07 апреля, 16:34:58 host.example.com systemd[1]: начата проверка журнала для журнала.
07 апреля 16:34:58 host.example.com log-test.sh[29909]: это ОШИБКА
07 апреля 16:34:58 host.example.com log-test.sh[29909]: Это ИНФОРМАЦИЯ
$ journalctl -u log-test -p 3 # приоритет ошибки системного журнала
-- Нет записей --
$

Вы можете видеть, что сообщения stderr и stdout имеют приоритет 6 (ИНФОРМАЦИЯ) при записи в журнал.

Это проблема, потому что у нас нет простого способа отличить вывод на stdout от stderr при использовании stdio->журнал в качестве основного средства регистрации.

Это было обсуждалось раньше и решения возможны, но не реализована. Я надеюсь, что команда systemd в конце концов реализует это, но пока мне нужно решение.

Кто-нибудь нашел разумное решение, чтобы сообщения, написанные на стандартный вывод и стандартный вывод, имели разные приоритеты в журнале? без изменения того, как приложение ведет журнал?

Я не хочу, чтобы все приложения, которые мы развертываем (не все написанные нами), должны были реализовывать интеграцию журнала или системного журнала, чтобы получить приоритет журнала, когда нам действительно нужны только два уровня: ИНФОРМАЦИЯ (стандартный вывод) и ОШИБКА (стдерр).

Многое из того, что мы развертываем, не является контейнерным, поэтому полагаться на средства ведения журналов контейнера также не решение для нас.

То, что stderr и stdout отправляются в журнал/системный журнал с разными приоритетами по умолчанию, очень важно для облегчения мониторинга ошибок распределенного журнала (при условии соблюдения гигиены разработчика в отношении написания только того, что требует внимания к stderr).

Использованная литература:

Рейтинг:1
флаг tz

Если вам нужно использовать стандартный вывод/стдерр, вы можете использовать sd-демон префикс ведения журнала.

Предварительно добавьте свой стдерр с <3> отправить ОШИБКА приоритет журнал журнал.

Используя ваш журнал-test.sh и журнал-test.service:

#!/бин/баш

>&2 echo "<3>Это ОШИБКА"
эхо "Это информация"

выход 0

И журналctl вывод:

$ журналctl -u лог-тест -p 3
02 мая 01:22:58 host.example.com log-test.sh[29909]: это ОШИБКА

Если твой модное приложение имеет любой API для записи системный журнал, вы можете использовать это для записи в дейтаграмму UNIX /dev/журнал (обычно доступны для записи по умолчанию и регистрируются в журнал) вместо стандартный вывод/стдерр. Используйте тег syslog для идентификации вашего модное приложение, приоритет системного журнала ошибка или же Информация в зависимости от ваших потребностей и любого средства системного журнала.

Например, в Bash мы можем использовать регистратор:

# посылаем сообщение INFO в journalctl
$ logger -t fancy-app -u /dev/log -p user.info "Это ИНФОРМАЦИЯ"

# отправить сообщение об ОШИБКЕ в journalctl
$ logger -t fancy-app -u /dev/log -p user.error "Это ОШИБКА"

# показать сообщения журнала для fancy-app
$ journalctl -t модное-приложение
02 мая 01:23:38 host.example.com fancy-app[27302]: Это ИНФОРМАЦИЯ
02 мая 01:23:39 host.example.com fancy-app[27303]: это ОШИБКА

# показать сообщения об ошибках журнала для fancy-app
$ журналctl -t необычное-приложение -p 3
02 мая 01:23:39 host.example.com fancy-app[27303]: это ОШИБКА

Обратите внимание, что в большинстве дистрибутивов журнал записи обычно пересылаются в локальный демон системного журнала (системный журнал-ng, rsyslog, ...), поэтому, вероятно, проверьте фильтры системного журнала или, возможно, используйте местный0...местный7 удобства.

У нас есть много производственных приложений (собственных и сторонних), которые оставляют регистрацию в контейнере и просто регистрируются в stdout для журналов INFO и stderr для журналов ERROR (т.е. только 2 приоритета журнала: INFO|ERROR).

Большинство движков контейнеров должны иметь возможность вести журнал в системном журнале. Не зная вашего контейнерного движка, я буду использовать Docker в качестве примера.

Докер имеет драйвер регистрации системного журнала который можно использовать для отправки сообщений журнала в формате системного журнала любой цели системного журнала. Вы должны иметь возможность войти в журнал с чем-то вроде:

докер запустить \
    --log-драйвер системный журнал \
    --log-opt syslog-address=unix:///dev/log \
    --log-opt syslog-facility=пользователь \
    --log-opt тег=причудливое-приложение \
    причудливое приложение: последнее

Докер также имеет драйвер ведения журналов имеется в наличии. Например:

докер запустить \
    --журнал-драйвер\
    --log-opt тег=причудливое-приложение \
    причудливое приложение: последнее

Оба драйвера регистрации (системный журнал и журнал) поддерживает разделение между стандартный вывод и стдерр; то есть стандартный вывод сообщения будут регистрироваться с ИНФОРМАЦИЯ приоритет и стдерр сообщения будут регистрироваться с ОШИБКА приоритет.

Философии и флеймы в сторону, почему бы не войти в настоящий системный журнал? Он проще, хранится в текстовом формате и обычно поддерживается программным обеспечением для управления журналами (см. Грейлог, Логсташ, Бумажный след).

mattpr avatar
флаг jp
Спасибо за ваш ответ, я переварю детали позже сегодня после еще нескольких чашек кофе. Мы не используем контейнеры для многих вещей, так что это не мгновенное решение. Некоторые из остальных выглядят полезными. Мы выполняем централизованную агрегацию журналов с помощью ELK или Graylog (в настоящее время Graylog) и можем использовать/переносить как системный журнал, так и журнал (через journalbeat теперь filebeat) в кластер агрегации журналов. Проблема по-прежнему заключается в том, что мы часто не можем контролировать код приложения, которое мы развертываем (например, стороннее приложение, для которого мы не хотим поддерживать исправление ведения журнала), и часто приложения по умолчанию используют stdout/stderr... или, что еще хуже, их собственные файлы ведения журнала. /форматы.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.