[JAVA] Utilisez log4j2 avec YAML + Gradle

Quand je cherchais un enregistreur Java, j'ai entendu dire que log4j2 pouvait écrire un fichier de configuration en YAML, alors je l'ai essayé. Cependant, j'y étais plus accro que prévu, je vais donc résumer la méthode pour le faire fonctionner avec YAML. Je ne pense pas que XML soit un format que les êtres humains peuvent lire et écrire, alors j'utilise Gradle au lieu de Maven pour créer des exemples d'applications.

Postscript

log4j2.yml n'est pas chargé

Effectuez le travail suivant en référence à Ecrire les paramètres Log4j2 dans YAML, essayez de l'utiliser avec Spring Boot et sortez le journal. J'ai essayé de partir.

dependencies {
    compile('org.apache.logging.log4j:log4j-core:2.7')
    compile('org.apache.logging.log4j:log4j-api:2.7')

    compile('com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.8.5')
}

Cependant, le journal des erreurs suivant continue d'être généré sans pitié. Je n'ai pas trouvé de solution en recherchant sur Google le libellé du journal des erreurs ou en recherchant Stack Overflow.

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

Conclusion

Les dépendances requises jackson-core et jackson-databind. Voici la bonne réponse pour la description de build.gradle. L'exemple de code est disponible sur ici, veuillez donc vous y référer si nécessaire.

dependencies {
    compile('org.apache.logging.log4j:log4j-core:2.7')
    compile('org.apache.logging.log4j:log4j-api:2.7')

    compile('com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.8.5')
    compile('com.fasterxml.jackson.core:jackson-core:2.8.5')
    compile('com.fasterxml.jackson.core:jackson-databind:2.8.5')
}

Paramètres YAML et sortie du journal

Pour référence, il s'agit d'un exemple de configuration YAML simple. Envoie les journaux vers la console au niveau du journal en fonction de la hiérarchie du package.

Configuration:
  status: debug

  Appenders:
    Console:
      name: CONSOLE
      target: SYSTEM_OUT
      PatternLayout:
        Pattern: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %c{3} - %msg%n"

  Loggers:
    Logger:
      - name: cobot00.gs.first
        additivity: false
        level: warn
        AppenderRef:
          - ref: CONSOLE
      - name: cobot00.gs.first.second
        additivity: false
        level: info
        AppenderRef:
          - ref: CONSOLE
    Root:
      level: debug
      AppenderRef:
        ref: CONSOLE

layer.png

S'il s'agit d'un package ou d'une hiérarchie de classes comme ci-dessus, le journal sera généré comme suit.

2017-01-30 22:56:49.007 [main] WARN  gs.first.FirstLayer - warning
2017-01-30 22:56:49.008 [main] ERROR gs.first.FirstLayer - error

2017-01-30 22:56:49.010 [main] INFO  first.second.SecondLayer - SecondLayer(number=2, tag=Gradle)
2017-01-30 22:56:49.011 [main] WARN  first.second.SecondLayer - warning
2017-01-30 22:56:49.011 [main] ERROR first.second.SecondLayer - error

2017-01-30 22:56:49.013 [main] INFO  second.third.ThirdLayer - ThirdLayer(number=3, tag=YAML)
2017-01-30 22:56:49.013 [main] WARN  second.third.ThirdLayer - warning
2017-01-30 22:56:49.013 [main] ERROR second.third.ThirdLayer - error

Résolution de mystère

Ceci est une explication de la façon dont j'ai remarqué le manque de dépendances. Je pense que ce sera pour ceux qui sont intermédiaires ou supérieurs à Java.

Le pass passe-t-il en premier lieu?

Voici les raisons possibles pour lesquelles log4j2.yml n'est pas chargé.

  1. Le chemin d'accès au répertoire du fichier de configuration ne passe pas
  2. Il manque quelque chose au-delà de la connaissance humaine

Tout d'abord, renommons log4j2.yml en log4j2.xml pour vérifier la casse de 1. Ensuite, l'exception suivante se produit.

[Fatal Error] log4j2.xml:1:1:Aucun contenu ne peut être spécifié pour le prologue.
ERROR StatusLogger Error parsing C:\coding\workspace\log4j2simple\bin\log4j2.xml
 org.xml.sax.SAXParseException; systemId: file:///C:/coding/workspace/log4j2simple/bin/log4j2.xml; lineNumber: 1; columnNumber: 1;Aucun contenu ne peut être spécifié pour le prologue.
  at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
  at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
  at org.apache.logging.log4j.core.config.xml.XmlConfiguration.<init>(XmlConfiguration.java:96)
  at org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory.getConfiguration(XmlConfigurationFactory.java:46)
  at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:519)
(Omission)

Il semble qu'il soit reconnu comme «log4j2.xml» et analysé comme XML. Je suis intéressé par les logs suivants. N'est-il pas possible d'obtenir des indices en examinant la classe ConfigurationFactory?

org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:519)

Examinons le code source de log4j2

Lorsque vous regardez les hits par googlé avec log4j2`` ConfigurationFactory comme mot clé, article de l'URL commençant par https: // github.com /blob/master/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java) peuvent être trouvés. Accédez à la page principale du référentiel à partir du lien, vérifiez l'URL de Clone et exécutez git clone.

git clone [email protected]:apache/logging-log4j2.git

Si vous regardez le projet, pom.xml existe, alors exécutez la commande Maven suivante pour l'importer dans eclipse.

mvn eclipse:eclipse

Après l'avoir importé dans eclipse en tant que projet Maven, si vous vérifiez la classe ConfigurationFactory et ses environs, vous remarquerez qu'il existe un vrai paquet tel que json`` xml`` yaml sous le paquet config.

config.png

[YamlConfigurationFactory](https://github.com/apache/logging-log4j2/blob/master/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ dans le paquet yaml yaml / YamlConfigurationFactory.java) La classe existe. Si vous regardez l'implémentation de YamlConfigurationFactory, vous verrez ce qui semble être la réponse depuis le début. Il semble que YamlConfigurationFactory ne prendra effet que si toutes les classes définies dans la variable dependencies sont complètes. Si vous modifiez build.gradle pour que com.fasterxml.jackson.databind`` com.fasterxml.jackson.core soit inclus dans la dépendance, le journal des erreurs de l'exemple disparaît et le contenu défini dans log4j2.yml Le journal est maintenant sorti avec.

private static final String[] dependencies = new String[] {
    "com.fasterxml.jackson.databind.ObjectMapper",
    "com.fasterxml.jackson.databind.JsonNode",
    "com.fasterxml.jackson.core.JsonParser",
    "com.fasterxml.jackson.dataformat.yaml.YAMLFactory"
};

private final boolean isActive;

public YamlConfigurationFactory() {
    for (final String dependency : dependencies) {
        if (!Loader.isClassAvailable(dependency)) {
            LOGGER.debug("Missing dependencies for Yaml support");
            isActive = false;
            return;
        }
    }
    isActive = true;
}

Validation supplémentaire

Je me demande pourquoi c'est l'implémentation même si le fichier de configuration YAML est maintenant chargé. ConfigurationFactory.java est la clé pour lire et interpréter le fichier de configuration de l'enregistreur. J'ai essayé de suivre le flux de traitement centré sur apache / logging / log4j / core / config / ConfigurationFactory.java). En gros, l'implémentation était telle que les extensions correspondantes étaient vérifiées pour l'existence de fichiers de manière circulaire en fonction de leur priorité, et le premier fichier de définition de hit a été utilisé. Voici la priorité des extensions.

Priorité de l'extension du fichier de configuration

priority extension
1 .properties
2 .yml
3 .yaml
4 .json
5 .jsn
6 .xml

Lors de l'exécution d'un test, le nom du fichier contenant «test» est pris en compte afin de donner la priorité au fichier de test. Compte tenu de la priorité de l'extension et du fichier de test, le contrôle d'existence du fichier est finalement exécuté dans l'ordre suivant. Et pour YAML et JSON, des classes supplémentaires sont nécessaires pour l'analyse, donc vérifiez les dépendances avec la classe Factory et ignorez l'existence du fichier de configuration si toutes les bibliothèques requises ne sont pas disponibles. C'est une mise en œuvre qui est faite. Cela peut conduire à des situations où «log4j2.xml» est lu mais «log4j2.yml» et «log4j2.json» sont ignorés.

Priorité du nom du fichier de configuration

priority config file name
1 log4j2-test.properties
2 log4j2-test.yml
3 log4j2-test.yaml
4 log4j2-test.json
5 log4j2-test.jsn
6 log4j2-test.xml
7 log4j2.properties
8 log4j2.yml
9 log4j2.yaml
10 log4j2.json
11 log4j2.jsn
12 log4j2.xml

La vérification de la bibliothèque de dépendances est implémentée comme suit, mais il semble que "Dépendances manquantes pour le support Json" ne soit pas affiché à cause du niveau de journal. Il semble qu'un autre paramètre soit nécessaire pour sortir ce journal ...

for (final String dependency : dependencies) {
    if (!Loader.isClassAvailable(dependency)) {
        LOGGER.debug("Missing dependencies for Json support");
        isActive = false;
        return;
    }
}

Recommended Posts

Utilisez log4j2 avec YAML + Gradle
Utiliser ProGuard avec Gradle
Utiliser les WebJars avec Gradle
Utilisez jlink avec gradle
Test d'intégration avec Gradle
Utiliser Puphpeteer avec Docker
Utilisez XVim2 avec Xcode 12.0.1
Utilisation de CentOS avec LXD
Installez Gradle sur ubuntu16.04
Data Nucleus commençant par Gradle
Utiliser Webmock avec Rspec
Comment utiliser Gradle
Commencez avec Gradle
Utiliser des couches Lambda avec Java
Créer un multi-projet Java avec Gradle
Utiliser GDAL avec Python avec Docker
Pot Gradle + Kotlin-Generate avec DSL
Utiliser Thymeleaf avec Azure Functions
[PHP8] Installer et utiliser la fonction YAML de PECL (analyseur YAML) avec Docker
Utiliser l'API Bulk avec RestHighLevelClient
Lombok ne fonctionne pas avec Gradle5
Utilisez SDKMAN! Avec Git Bash
Utiliser Spring JDBC avec Spring Boot
Utilisez Ruby avec Google Colab
Hello World avec SpringBoot / Gradle
[Docker] À utiliser à tout moment avec Docker + Rails
Utiliser PlantUML avec Visual Studio Code
Utiliser l'authentification de base avec Spring Boot
Construire un projet Java avec Gradle
Utiliser java avec MSYS et Cygwin
Utiliser le constructeur avec des arguments dans cucumber-picocontainer
Utiliser Microsoft Graph avec Java standard
Utiliser le type inet PostgreSQL avec DbUnit
J'ai essayé d'utiliser JOOQ avec Gradle
Utilisez bootstrap 4 avec PlayFramework 2.6 (pas de CDN)
Couverture de test de sortie avec Clover + Gradle
Je ne peux pas installer lombok avec Gradle.
Utiliser Azure Bing SpellCheck avec Java
Utilisez JDBC avec Java et Scala.
Utiliser DataDog APM avec des frameworks non pris en charge
Utiliser Java 11 avec Google Cloud Functions
Comment utiliser mssql-tools avec Alpine
À partir de Spring Boot 0. Utilisez Spring CLI
Utilisation de cuda11.0 avec pytorch en utilisant Docker
Développer le traitement avec IntelliJ + Kotlin + Gradle