web-dev-qa-db-fra.com

Nom du journal de consignation avec un caractère générique

Est-il possible d'utiliser un caractère générique pour le nom de l'enregistreur qui correspond à différents packages afin d'éviter de les spécifier tous individuellement? Donc au lieu d'écrire

<logger name="com.package1.web" level="debug"   
<logger name="com.package2.web" level="debug"  
<logger name="com.package3.web" level="debug"  

Je voudrais spécifier seulement une entrée un peu comme ceci:

<logger name="com.*.web" level="debug"  

Si quelqu'un connaît un moyen ou aussi simplement que ce n'est pas une possibilité, je l'apprécierais beaucoup

5
petrichory

Vous pouvez le faire avec des filtres dans l'appender. En gros, vous devez configurer un enregistreur pour "com. *" Avec le niveau DEBUG et appliquer un filtre DENYANT tous les événements DEBUG (ou amoureux) qui ne sont PAS "com. *. Web".

J'avoue que c'est assez compliqué.

En ce qui concerne les performances, il est également médiocre: les événements de débogage sont créés pour les événements tous "com. *", Et uniquement à l’appender, ils sont jetés ou conservés.

Quoi qu'il en soit, exemple logback.xml:

<configuration scan="true" debug="true">
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
            <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
                <expression>
                    !(e.loggerName ==~ "com\\..*\\.web") &amp;&amp;
                    DEBUG.toInt() >= e.level.toInt()
                </expression>
            </evaluator>
            <OnMismatch>NEUTRAL</OnMismatch>
            <OnMatch>DENY</OnMatch>
        </filter>
        <encoder>
            <pattern>%p [%d{HH:mm:ss,SSS}] %c - %m\n</pattern>
        </encoder>
    </appender>

    <logger name="com" level="DEBUG" />

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

Code de test:

public void test() throws Exception{
    getLogger("com.package1.web").debug("some debug onto com.package1.web");
    getLogger("com.package2.web").debug("some debug onto com.package2.web");
    getLogger("com.package3.web").debug("some debug onto com.package3.web");
    getLogger("com.package1.web").info("some info onto com.package1.web");
    getLogger("com.package2.web").info("some info onto com.package2.web");
    getLogger("com.package3.web").info("some info onto com.package3.web");
    getLogger("com.package3.notweb").debug("some debug onto com.package3.notweb");
    getLogger("com.package3.notweb").info("some info onto com.package3.notweb");
}

public Logger getLogger(String loggerName) {
    return LoggerFactory.getLogger(loggerName);
}

Résultat:

DEBUG [12:30:46] com.package1.web - some debug onto com.package1.web
DEBUG [12:30:46] com.package2.web - some debug onto com.package2.web
DEBUG [12:30:46] com.package3.web - some debug onto com.package3.web
INFO [12:30:46] com.package1.web - some info onto com.package1.web
INFO [12:30:46] com.package2.web - some info onto com.package2.web
INFO [12:30:46] com.package3.web - some info onto com.package3.web
INFO [12:30:46] com.package3.notweb - some info onto com.package3.notweb

comme vous pouvez le constater, les journaux de débogage sont écrits uniquement pour "com. *. web"

5
riskop

TL; DR

Logback ne prend pas en charge les caractères génériques aux niveaux intermédiaires dans le nom du consignateur.

Détail

Logback (implicitement) prend en charge les caractères génériques à la fin du nom du logger, donc <logger name="com.package1.web" ...> signifie en réalité:

  • Classes dans com.package1.webet dans tous les sous-packages de com.package1.web

Logback fait cela en créant une hiérarchie de loggers; l'enregistreur pour com.package1.web est associé à un enregistreur pour com.package1 qui est associé à un enregistreur à com qui est parent de l'enregistreur ROOT.

Ainsi, si vous déclarez <logger name="com.package1.web" level="debug"> et tentez ensuite d'émettre un message de journal de débogage pour un enregistreur sur com.package1.web.foo.bar, Logback expliquera la hiérarchie de cet enregistreur jusqu'à ce qu'il trouve un enregistreur pour lequel le niveau DEBUG est activé, il le trouvera à com.package1.web émettre l'événement de journal DEBUG.

Toutefois, Logback ne créera pas de hiérarchie basée sur une carte réseau à un niveau intermédiaire dans le nom du journal. Donc ça ...

<logger name="com.*.web" level="debug">

... ne fera pas que Logback crée des enregistreurs pour: 

  • com.package1.web
  • com.package2.web
  • com.package3.web

Le comportement hiérarchique de Logback ne sera pas appliqué lorsque le caractère générique est présenté à un niveau intermédiaire dans le nom du journal.

Solution possible

Un avantage de ce comportement de hiérarchie est qu’il vous permet d’appliquer la configuration du consignateur à un package et à toutes les classes situées en dessous de ce package, c’est-à-dire qu’il crée une association entre les instances du consignateur en fonction de leur parenté. Vous pourriez établir cette association en fournissant un nom de consignateur explicite, plutôt que de le remplacer par défaut par le nom de la classe actuelle.

Par exemple:

<logger name="DEBUG_LOGGER" level="debug">

Ensuite, partout où vous souhaitez utiliser le consignateur de débogage, créez simplement une instance de consignateur de la manière suivante:

private final Logger logger = LoggerFactory.getLogger("DEBUG_LOGGER");

Il est clair que cette approche présente également des inconvénients. Je la mentionne simplement ici pour montrer qu’il existe un autre moyen (autre que le nom de classe pleinement qualifié) d’associer des instances de consignateur et de leur appliquer un niveau.

1
glytching