Я работаю над большим проектом с множеством подмодулей. При отладке компонента xyz этот компонент часто обращается к службам в других модулях. Чтобы регистрировать каждое сообщение отладки, мы должны определить множество регистраторов в нашем logback.xml.

Можно ли определить общие суперлоггеры или родительские регистраторы?

Пример: вместо того, чтобы писать это:

<logger name="com.a.b.c.xyz" level="debug" />
<logger name="com.a.b.d.core.xyz" level="debug" />
<logger name="com.a.b.e.xyz" level="debug" />
<logger name="com.a.b.e.f.xyz" level="debug" />
<logger name="com.a.b.t.services.xyz" level="debug" />

Можно определить что-то вроде этого:

<logger name="xyz-super" level="debug">
    <child-logger name="..." />
    <child-logger name="..." />
    ...
</logger>

После завершения отладки модуля xyz все забывают, какие пакеты были для него важны, поэтому сохранение этих родительских регистраторов поможет в решении будущих проблем.

2
Bytewright 7 Июн 2018 в 12:00

1 ответ

Лучший ответ

Если я понимаю, о чем вы просите, у вас есть концепция «компонента», который пересекает пакеты Java, и вы хотите обрабатывать настройку уровня ведения журнала на основе того, в каком компоненте он находится, а не обязательно, в каком пакете он находится. Я вижу несколько подходов, которые можно предпринять.

  1. Хотя стандарт для имени регистратора основан на имени класса (и, следовательно, на пакете Java, в котором находится класс), вам не нужно использовать это имя для ваших имен регистратора. То есть у вас может быть иерархия регистраторов, отличная от иерархии ваших пакетов. В вашем классе com.a.b.c.xyz вы можете получить регистратор с:

    final Logger logger = LoggerFactory.getLogger("com.a.b.xyz.c");
    

    Находясь в классе com.a.b.d.core.xyz, возьмите регистратор с:

    final Logger logger = LoggerFactory.getLogger("com.a.b.xyz.d.core");
    

    И затем вы можете просто использовать обычные определения уровня регистратора, установив уровень ведения журнала для com.a.b.xyz, чтобы получить все регистраторы под этим компонентом. Это немного нетрадиционно и может сбить с толку разработчиков, плохо знакомых с вашим проектом, но если вы действительно хотите, чтобы иерархия ведения журналов и иерархия пакетов отличались друг от друга, вы можете это сделать.

  2. Другой подход - оставить иерархию имен журналов как есть, но использовать маркер SLF4J / Logback механизм, позволяющий «пометить» каждое сообщение журнала для каждого компонента.

    final Logger logger = LoggerFactory.getLogger(getClass());
    final Marker xyzComponent = MarkerFactory.getMarker("XYZ");
    …
    logger.info(xyzComponent, "A log message");
    

    Затем вы можете настроить фильтры в Logback на основе маркеров, которые вы ищете. Это действительно требует, чтобы вы были последовательны и удостоверились, что каждое сообщение, о котором вы заботитесь, помечено соответствующим маркером, но это самое близкое к «суперлоггеру» или «групповому логгеру», которое есть в архитектуре SLF4J. Механизм маркеров действительно мощный и позволяет вам делать с ним все, что угодно, при условии, что ваши сообщения имеют правильный маркер и вы настроили конфигурацию ведения журнала, чтобы фильтровать только сообщения с правильным фильтром.

  3. Другой подход, который я могу придумать, - это в основном продолжать делать то, что вы делаете сейчас, и указывать множество отдельных средств ведения журнала на уровне отладки, но иметь эти параметры конфигурации ведения журнала «отладки» для каждого компонента в отдельных файлах. Затем, когда вам нужно отладить компонент, вам просто нужно добавить (или раскомментировать?) Соответствующий включить элемент в основные настройки ведения журнала.

    В файле xyz-debug.xml:

    <included>
        <logger name="com.a.b.c.xyz" level="debug" />
        <logger name="com.a.b.d.core.xyz" level="debug" />
        <logger name="com.a.b.e.xyz" level="debug" />
        <logger name="com.a.b.e.f.xyz" level="debug" />
        <logger name="com.a.b.t.services.xyz" level="debug" />
    </included>
    

    В файле abc-debug.xml:

    <included>
        <logger name="com.a.b.c.abc" level="debug" />
        <logger name="com.a.b.d.core.abc" level="debug" />
        <logger name="com.a.b.e.abc" level="debug" />
        <logger name="com.a.b.e.f.abc" level="debug" />
        <logger name="com.a.b.t.services.abc" level="debug" />
    </included>
    

    А затем в вашем основном файле logback.xml:

    <!--<include file="xyz-debug.xml"/>-->
    <!--<include file="abc-debug.xml"/>-->
    

    И вы просто раскомментируете соответствующую строку, когда вам нужно отладить этот компонент. Возможно, это немного неудобно и упрощенно, и может действительно сбить с толку, если кто-то забудет обновить xyz-debug.xml, когда компонент xyz является частью нового пакета, но я могу представить, что это работает достаточно хорошо для некоторых команд. Также не требуется никаких изменений кода, что может быть плюсом.

Logback и SLF4J имеют много силы и возможностей, что (как обычно) одновременно и сильная, и слабая сторона, поскольку может потребоваться время, чтобы изучить все, что они могут делать. Но обычно можно найти способ заставить их работать так, как вы хотите, а иногда можно найти способ даже лучше, чем то, что вы планировали.

1
user65839user65839 7 Июн 2018 в 23:26