web-dev-qa-db-fra.com

comment définir les variables / propriétés de logback avant le chargement automatique de logback logback.xml?

Mon entreprise dispose d'un outil de gestion de l'environnement qui vous permet de rechercher des propriétés de l'environnement par programmation en Java. Je veux tirer parti de cet outil pour configurer la déconnexion. Par exemple, supposons que j'ai un logback.xml comme suit (la section appender de fichier en particulier):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- console appender -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd/HH:mm:ss.SSS} [%thread] %-5level %logger{20}: %msg%n</pattern>
        </encoder>
    </appender>

    <!-- file appender -->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${LOG_FILE:-/default/log/file/path</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd/HH:mm:ss.SSS} [%thread] %-5level %logger{20}: %msg%n</pattern>
        </encoder>
    </appender>

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

Donc, dans ce cas, je veux rechercher le LOG_FILE propriété de l'environnement (ou du système d'exploitation, si vous le souhaitez) et transmettez-la à logback avant que logback charge logback.xml afin qu'il connaisse la valeur de LOG_FILE. Alors, comment puis-je y parvenir? BTW, je sais comment définir un appender de fichier par programme, mais ce n'est pas ce que je veux ici.

Merci beaucoup.

23
JBT

Après m'être beaucoup gratté la tête, je me suis installé avec la solution suivante.

Tout d'abord, placez logback.xml en dehors du chemin de classe pour que logback ne charge rien automatiquement.

Ensuite, ajoutez les paramètres de l'environnement aux propriétés du système afin que logback puisse les rechercher lors de l'analyse de logback.xml.

Troisièmement, configurez la déconnexion par programme dans le code d'application. (La documentation officielle de déconnexion a n bel exemple de cela.)

Terminé.

11
JBT

Définir une propriété dans logback.xml et chargez-le dans le "contexte":

<property scope="context" name="logfolder" value="${location.of.the.log.folder}" />

Définissez ensuite votre appender référençant la propriété:

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${logfolder}/logfile.log</file>
    <append>true</append>
    <encoder>
        <pattern>[%d{ISO8601}] [%p] [%t] [%c] [%m]%n</pattern>
    </encoder>
</appender>

De la documentation :

Une propriété avec une étendue de contexte est insérée dans le contexte et dure aussi longtemps que le contexte ou jusqu'à ce qu'il soit effacé. Une fois définie, une propriété dans la portée du contexte fait partie du contexte. En tant que tel, il est disponible dans tous les événements de journalisation, y compris ceux envoyés aux hôtes distants via la sérialisation.

La portée par défaut, qui est "locale", pourrait donc être suffisante.

15
Alexandre Santos

Je veux rechercher le LOG_FILE propriété de l'environnement (ou du système d'exploitation, si vous voulez)

Voici les alternatives:

  1. Si par environnement , vous voulez dire ce que l'on appelle généralement variables d'environnement , vous pouvez faites-y directement référence dans le fichier de configuration sans trop de tracas.

  2. Si vous ne parlez pas de variables d'environnement, mais plutôt de quelque chose qui nécessite un code personnalisé pour accéder, vous pouvez implémenter un ch.qos.logback.core.spi.PropertyDefiner qui récupère et renvoie la valeur.

    par exemple.

    public class MyCompanyEnvironmentGrabber extends PropertyDefinerBase {
    
        @Override
        public String getPropertyValue() {
            return ...; // grab the value from company environment
        }
    }
    
  3. Il y a apparemment rapports on peut configurer par programme une variable avant logback.xml est chargé en le mettant avant tout appel à logger, et en faisant attention à l'ordre de chargement de ClassLoader ... Cependant, je pense que c'est très fragile car n'utilisant pas static logger est très difficile à contrôler lorsque la base de code devient complexe.

Tout compte fait, puisque logback.xml est chargé presque immédiatement après le démarrage de l'instance Java, des moyens sûrs de définir dynamiquement la valeur d'une variable semblent limités à:

  1. Le placer en dehors du programme Java, par exemple via un script Shell appelant, en utilisant des variables d'environnement ou des propriétés système (-D).
  2. Le renvoyer via le ch.qos.logback.core.spi.PropertyDefiner rappeler.
  3. Configuration dans un ch.qos.logback.classic.spi.LoggerContextListener comme dans cette réponse .
  4. Retarder artificiellement le chargement de logback.xmlcomme le fait l'OP dans sa réponse .
10
antak