Настраиваем уровень логирования подсистем Logme
В многокомпонентном приложении один канал логирования часто используется сразу несколькими компонентами. Logme позволяет задать отдельный уровень логирования подсистемы, не меняя уровень всего канала. Благодаря этому можно включить DEBUG только для проблемного компонента или, наоборот, подавить слишком частые INFO-сообщения одной подсистемы.
Представим сервер, в котором подсистемы HTTP, TLS, AUTH и POLICY пишут в один журнал:
2026-07-28 14:37:05:201 #HTTP Accept(): Accepted connection from 192.168.1.25
2026-07-28 14:37:05:204 #AUTH Authenticate(): User john authenticated
2026-07-28 14:37:05:208 #POLICY Apply(): Policy 17 applied
2026-07-28 14:37:05:212 #TLS Handshake(): TLS connection established
Уровень канала установлен в INFO. Для штатной работы этого достаточно: в журнал попадают основные события, но низкоуровневая диагностика не создаёт лишний шум.
Проблема начинается, когда подробные сообщения нужны только от одной подсистемы.
Почему уровень канала не всегда подходит для диагностики
Допустим, некоторые клиенты периодически не могут установить TLS-соединение. На уровне INFO в журнале может остаться только итоговая ошибка:
2026-07-28 14:41:52:018 E #TLS Error: Failed to establish a secure connection
По такой строке нельзя определить, на каком этапе возникла проблема:
- клиент не прислал корректный
ClientHello; - не удалось согласовать версию TLS;
- стороны не нашли общий набор шифров;
- завершилась ошибкой проверка сертификата;
- соединение оборвалось во время handshake.
Для расследования нужны сообщения уровня DEBUG.
Можно временно переключить весь канал с INFO на DEBUG, но тогда подробные сообщения начнут писать все подсистемы:
2026-07-28 14:42:31:101 D #HTTP ParseHeader(): Parsed header Host
2026-07-28 14:42:31:102 D #HTTP ParseHeader(): Parsed header User-Agent
2026-07-28 14:42:31:103 D #POLICY Evaluate(): Evaluating condition 31
2026-07-28 14:42:31:104 D #POLICY Evaluate(): Evaluating condition 32
2026-07-28 14:42:31:105 D #AUTH FindToken(): Looking up token in cache
2026-07-28 14:42:31:106 D #TLS Handshake(): Starting TLS handshake
2026-07-28 14:42:31:107 D #HTTP ParseBody(): Received 512 bytes
2026-07-28 14:42:31:108 D #POLICY Evaluate(): Condition 31 returned true
Нужная информация в журнале присутствует, но быстро теряется среди посторонних сообщений.
На нагруженной системе глобальный DEBUG создаёт и другие проблемы:
- журнал быстрее достигает ограничения по размеру;
- старые записи раньше уходят в ротацию;
- увеличивается объём записи на диск;
- форматируются сообщения, которые не относятся к расследованию;
- анализ журнала занимает больше времени;
- редкая ошибка может затеряться среди тысяч строк других компонентов.
Особенно неудобно это при плавающих проблемах, которые воспроизводятся раз в несколько часов. Глобальный DEBUG приходится держать включённым долго, хотя большая часть собранных данных не представляет интереса.
Как задать отдельный уровень логирования подсистемы
Вместо изменения уровня всего канала можно задать override только для TLS:
Уровень канала: INFO
Уровень подсистемы TLS: DEBUG
Уровень канала остаётся прежним для HTTP, AUTH, POLICY и остальных компонентов. Только сообщения с SID TLS начинают проходить начиная с уровня DEBUG.
Журнал становится заметно полезнее:
2026-07-28 14:45:17:201 #HTTP Accept(): Accepted connection from 192.168.1.25
2026-07-28 14:45:17:203 D #TLS Handshake(): Starting TLS handshake
2026-07-28 14:45:17:204 D #TLS Handshake(): Received ClientHello
2026-07-28 14:45:17:205 D #TLS Handshake(): Client requested TLS 1.3
2026-07-28 14:45:17:206 D #TLS Handshake(): Selected cipher TLS_AES_256_GCM_SHA384
2026-07-28 14:45:17:207 D #TLS Verify(): Verifying certificate chain
2026-07-28 14:45:17:209 D #TLS Verify(): Certificate expires at 2026-07-20 00:00:00
2026-07-28 14:45:17:211 E #TLS Error: Certificate verification failed: certificate has expired
2026-07-28 14:45:17:214 #POLICY Apply(): Policy 17 applied
Теперь видна вся последовательность TLS-handshake:
Starting TLS handshake
Received ClientHello
Client requested TLS 1.3
Selected cipher TLS_AES_256_GCM_SHA384
Verifying certificate chain
Certificate verification failed: certificate has expired
При этом в журнал не попадают отладочные сообщения парсера HTTP, кеша аутентификации и интерпретатора политик.
Иными словами, отдельный уровень логирования подсистемы позволяет получить подробную диагностику именно там, где она нужна, не переводя всё приложение в DEBUG.
Почему для этого не обязательно создавать отдельный канал
На первый взгляд можно создать отдельный канал для каждой подсистемы:
http
tls
auth
policy
Но канал обычно отвечает не только за уровень фильтрации. С ним могут быть связаны:
- файл назначения;
- набор backend-ов;
- вывод в консоль;
- системный журнал;
- правила ротации;
- ограничения размера;
- форматирование строк;
- сетевой вывод;
- callback-обработчики.
Если разделить подсистемы по каналам только ради разных уровней, придётся дублировать или усложнять конфигурацию.
Subsystem level override решает задачу без изменения архитектуры каналов. Сообщения продолжают попадать в те же backend-ы и файлы, но порог фильтрации выбирается с учётом SID.
Это особенно удобно, когда один канал намеренно объединяет события нескольких логически связанных компонентов.
Override может сделать журнал не только подробнее, но и тише
Отдельный уровень логирования подсистемы полезен и в обратной ситуации.
Допустим, канал работает на INFO, но подсистема HTTP регистрирует каждый запрос:
2026-07-28 15:01:17:441 #HTTP Accept(): Accepted connection from 192.168.1.31
2026-07-28 15:01:17:443 #HTTP Parse(): Request GET /api/status
2026-07-28 15:01:17:447 #HTTP Send(): Response 200, 842 bytes
2026-07-28 15:01:17:451 #HTTP Accept(): Accepted connection from 192.168.1.32
2026-07-28 15:01:17:453 #HTTP Parse(): Request GET /api/status
2026-07-28 15:01:17:456 #HTTP Send(): Response 200, 842 bytes
Если повысить уровень всего канала до WARN, одновременно исчезнут полезные события остальных подсистем:
#AUTH User john authenticated
#POLICY Policy 17 applied
#TLS TLS connection established
Вместо этого можно оставить канал на INFO, а для HTTP задать WARN:
Уровень канала: INFO
Уровень подсистемы HTTP: WARN
После этого обычные HTTP-запросы перестают попадать в журнал, но предупреждения и ошибки сохраняются:
2026-07-28 15:02:03:101 #AUTH Authenticate(): User john authenticated
2026-07-28 15:02:03:108 #POLICY Apply(): Policy 17 applied
2026-07-28 15:02:08:512 W #HTTP Send(): Client response is delayed by 5240 ms
2026-07-28 15:02:11:737 E #HTTP Error: Failed to accept connection: too many open files
Рутинный поток запросов больше не занимает место в журнале, но действительно важные события HTTP не потеряны.
Как выбирается итоговый уровень сообщения
Уровень канала остаётся правилом по умолчанию.
Например:
Канал: INFO
Без overrides все подсистемы используют этот уровень:
HTTP → INFO
TLS → INFO
AUTH → INFO
POLICY → INFO
После настройки индивидуальных уровней:
TLS → DEBUG
HTTP → WARN
получается следующая схема:
HTTP → WARN
TLS → DEBUG
AUTH → INFO
POLICY → INFO
Override именно заменяет уровень канала для соответствующей подсистемы.
Это не дополнительный фильтр, который может быть только строже основного уровня. Override работает в обе стороны:
INFO → DEBUG
позволяет включить более подробную диагностику, а:
INFO → WARN
позволяет подавить рутинные сообщения.
Благодаря этому одна подсистема может писать подробнее остальных, а другая — значительно меньше.
Несколько уровней подсистем одновременно
В реальном приложении часто требуется настроить сразу несколько компонентов.
Например:
Уровень канала: INFO
TLS: DEBUG
HTTP: WARN
POLICY: ERROR
Такая конфигурация означает:
TLSпишет подробную диагностику handshake;HTTPоставляет предупреждения и ошибки;POLICYсообщает только об ошибках;AUTHи остальные подсистемы продолжают использоватьINFO.
Журнал при этом может одновременно стать и подробнее, и компактнее:
2026-07-28 16:18:40:100 #AUTH Authenticate(): User john authenticated
2026-07-28 16:18:40:103 D #TLS Handshake(): Starting TLS handshake
2026-07-28 16:18:40:104 D #TLS Handshake(): Received ClientHello
2026-07-28 16:18:40:106 D #TLS Verify(): Verifying certificate chain
2026-07-28 16:18:40:109 E #TLS Error: Certificate verification failed
2026-07-28 16:18:42:320 W #HTTP Send(): Client response is delayed by 5240 ms
В нём отсутствуют:
- обычные
INFO-сообщенияHTTP; - отладочные сообщения
HTTP; - отладочные сообщения
AUTH; - информационные и отладочные сообщения
POLICY.
При этом подробная последовательность TLS остаётся доступной.
Почему точечная настройка особенно полезна для редких ошибок
Некоторые проблемы нельзя воспроизвести сразу после включения диагностики. Ошибка может возникать раз в несколько часов или только при определённой нагрузке.
При глобальном DEBUG за это время журнал может:
- вырасти до большого размера;
- несколько раз пройти ротацию;
- удалить важные записи до момента выгрузки;
- создать заметную дополнительную нагрузку;
- накопить слишком много данных для ручного анализа.
Индивидуальный уровень логирования подсистемы позволяет держать диагностику включённой дольше. Доля полезных строк становится выше, а история до и после сбоя сохраняется лучше.
Это даёт практические преимущества:
- проще дождаться редкого воспроизведения;
- легче найти начало проблемной последовательности;
- можно увидеть события непосредственно перед ошибкой;
- разработчику передаётся меньший набор файлов;
- анализ занимает меньше времени.
Временная диагностика работающей системы
Subsystem level override хорошо подходит для расследования проблем в рабочем окружении.
Типичный процесс выглядит так:
- Приложение продолжает работать со штатным уровнем канала.
- Для проблемной подсистемы временно устанавливается
DEBUG. - Инженер дожидается повторения ошибки.
- Из журнала извлекается нужный временной интервал.
- Override удаляется.
- Подсистема снова использует уровень канала.
Например, до расследования:
Канал: INFO
TLS: уровень канала
Во время расследования:
Канал: INFO
TLS: DEBUG
После удаления override:
Канал: INFO
TLS: уровень канала
Не требуется запоминать и восстанавливать отдельное прежнее значение для TLS. После удаления индивидуальной настройки подсистема автоматически возвращается к общему уровню своего канала.
Что происходит с сообщениями без SID
Override применяется к сообщениям, для которых Logme определил соответствующий SID.
Если сообщение не связано ни с одной подсистемой, для него продолжает использоваться уровень канала.
Например:
Уровень канала: INFO
Уровень TLS: DEBUG
Сообщение с SID TLS может пройти на уровне DEBUG, а сообщение без SID по-прежнему будет отфильтровано по INFO.
Поэтому механизм наиболее эффективен, когда сообщения компонентов последовательно помечаются соответствующими SID. Если часть TLS-кода пишет без SID, индивидуальный уровень TLS на такие строки не повлияет.
Когда subsystem override особенно полезен
Отдельный уровень логирования подсистемы особенно полезен в нескольких случаях.
Диагностика одного проблемного компонента
Нужно включить DEBUG для TLS, базы данных, сетевого транспорта или интерпретатора правил, не затрагивая остальное приложение.
Подавление шумного компонента
Одна подсистема пишет слишком много INFO, но полностью отключать информационные сообщения всего канала нельзя.
Сбор данных о редкой ошибке
Диагностику необходимо держать включённой продолжительное время, и глобальный DEBUG создаёт слишком большой объём.
Работа с общим каналом
Разные подсистемы намеренно используют один файл и один набор backend-ов, поэтому создание дополнительных каналов нежелательно.
Настройка журнала под конкретный инцидент
Для одной подсистемы нужен DEBUG, для другой достаточно WARN, а третью требуется ограничить уровнем ERROR.
Что даёт уровень логирования подсистемы на практике
Без subsystem overrides обычно приходится выбирать между двумя крайностями:
- включить
DEBUGдля всего канала и получить большое количество посторонних данных; - оставить штатный уровень и не увидеть деталей проблемного компонента.
Индивидуальный уровень логирования подсистемы позволяет избежать этого компромисса.
Он помогает:
- включить подробные сообщения только для нужного компонента;
- подавить шум одной подсистемы без потери полезных событий остальных;
- уменьшить объём журнала;
- снизить количество лишней обработки;
- дольше собирать диагностику редкой ошибки;
- сохранить больше полезной истории;
- быстрее найти связанную последовательность событий;
- вернуть штатное поведение простым удалением override.
Уровень канала остаётся общим правилом, а subsystem overrides позволяют точечно изменить его там, где это действительно необходимо.