web-dev-qa-db-fra.com

Utiliser les propriétés de l'application de démarrage Spring dans log4j2.xml

Je travaille sur une application Web basée sur Spring Boot et souhaite utiliser log4j2 comme implémentation de l'enregistreur.
Tout fonctionne correctement avec la configuration de journalisation définie dans un fichier log4j2-spring.xml

Ce qui ne fonctionne pas: je veux utiliser des espaces réservés de propriétés dans le fichier log4j2-spring.xml qui doivent être résolus à partir des propriétés définies dans le fichier application.yml utilisé pour la configuration de Spring Boot. 

Est-ce possible? Si oui comment?

5
Ankit Gupta

La substitution directe de propriétés dans log4j2-spring.xml via un espace réservé de propriété est pas possible, car le log4j2-spring.xml sort du cadre de Spring et est utilisé uniquement à des fins de configuration.

Cependant, vous pouvez utiliser la fonctionnalité Log4j2 prête à l'emploi de la substitution de propriété, comme indiqué ci-après ici .

Étape 1 - Spécifiez le nom de la propriété et sa variable dans log4j2-spring.xml comme ci-dessous. 

<Configuration status="warn">
    <Properties>
        <Property name="someProp">${bundle:test:someKey}</Property>
    </Properties> 
    <!--other configs -->
</Configuration>

Étape 2 - Utilisez la propriété définie ci-dessus dans la configuration du journal suffixe correspondant au nom du fichier journal, par exemple

<Appenders>
    <File name="file" fileName="/path/to/logs/app-${someProp}.log">
        <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %-40c{1.} - %m%n"/>
    </File>
</Appenders>

Étape 3 - Créez un bundle (fichier de propriétés visible) pour contenir la valeur des propriétés par exemple, test.properties

# properties for log4j2
someKey=someValue
someKey1=someValue1

Dans votre cas, ce fichier contiendra les valeurs en yaml que vous souhaitez utiliser dans la configuration de log4j2. Si ces propriétés sont également utilisées dans l’application, elles seront dupliquées dans yaml et le bundle (fichier de propriétés) qui devrait être un compromis acceptable étant donné que spring ne peut pas les injecter dans la configuration log4j2.

Laissez savoir dans les commentaires au cas où plus d'informations sont nécessaires.

3
Bond - Java Bond

J'ai rencontré un problème similaire avec l'injection des propriétés Spring Boot YAML dans la configuration log4j xml, et j'ai trouvé une solution pour Spring Boot 1.5.X (et probablement 2.0, je ne l'ai pas testée), ce qui est un peu hacky et fonctionne sur le système. propriétés de recherche mais cela fonctionne certainement. 

Supposons que vous avez le profil "dev" dans votre application et une propriété à injecter, puis votre application-dev.yml ressemble à ceci:

property:
    toInject: someValue

Dans votre configuration xml log4j2-spring-dev.xml vous mettez quelque chose comme ceci:

<Properties>
    <property name="someProp">${sys:property.toInject}</property>
</Properties>

Maintenant, vous devez en quelque sorte transférer cette propriété de printemps à la propriété du système. Vous devez le faire après la préparation de l'environnement d'application et avant l'initialisation du système de journalisation. Dans Spring Boot, il existe un écouteur LoggingApplicationListener, qui initialise l'ensemble du système de journalisation et qui est déclenché par l'événement ApplicationEnvironmentPreparedEvent. Nous allons donc créer un écouteur avec un ordre de priorité supérieur à LoggingApplicationListener:

public class LoggingListener implements ApplicationListener, Ordered {

@Override
public int getOrder() {
    return LoggingApplicationListener.DEFAULT_ORDER - 1;
}

@Override
public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof ApplicationEnvironmentPreparedEvent) {
        ConfigurableEnvironment environment = ((ApplicationEnvironmentPreparedEvent) event).getEnvironment();
        List<String> activeProfiles = Arrays.asList(environment.getActiveProfiles());
        if (!activeProfiles.contains("dev")) {
            return;
        }

        String someProp = environment.getProperty("property.toInject")
        validateProperty(someProp);

        System.setProperty("property.toInject", someProp);
    }
}

Enregistrez maintenant cet auditeur dans votre application: 

public static void main(String[] args) {
    SpringApplication application = new SpringApplication(MyApplication.class);
    application.addListeners(new LoggingListener());
    application.run(args);
}

Et c'est tout. Vos propriétés de démarrage printanier doivent être "injectées" dans votre fichier de configuration log4j2. Cette solution fonctionne avec les propriétés classpath et --spring.config.location. Notez que cela ne fonctionnerait pas avec un système de configuration externe tel que Spring Cloud Config.

J'espère que ça aide 

1
DG94