[JAVA] Verwenden Sie log4j2 mit YAML + Gradle

Als ich nach einem Java-Logger suchte, hörte ich, dass log4j2 eine Konfigurationsdatei in YAML schreiben kann, also habe ich es versucht. Ich war jedoch süchtiger als erwartet, daher werde ich die Methode zusammenfassen, damit es mit YAML funktioniert. Ich denke nicht, dass XML ein Format ist, das Menschen lesen und schreiben können, deshalb verwende ich Gradle anstelle von Maven, um Beispielanwendungen zu erstellen.

Nachtrag

log4j2.yml wird nicht geladen

Führen Sie die folgenden Arbeiten unter Bezugnahme auf Log4j2-Einstellungen in YAML schreiben, versuchen Sie es mit Spring Boot zu verwenden aus und geben Sie das Protokoll aus. Ich habe versucht zu gehen.

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')
}

Das folgende Fehlerprotokoll wird jedoch weiterhin rücksichtslos ausgegeben. Ich konnte keine Lösung finden, indem ich den Wortlaut des Fehlerprotokolls googelte oder nach "Stapelüberlauf" suchte.

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

Fazit

Die Abhängigkeiten erforderten "Jackson-Core" und "Jackson-Databind". Das Folgende ist die richtige Antwort für die Beschreibung von "build.gradle". Der Beispielcode ist unter [hier] verfügbar (https://github.com/cobot00/log4j2simple). Bitte beziehen Sie sich bei Bedarf darauf.

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')
}

YAML-Einstellungen und Protokollausgabe

Als Referenz ist dies ein einfaches YAML-Konfigurationsbeispiel. Gibt Protokolle auf Protokollebene gemäß der Pakethierarchie an die Konsole aus.

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

Wenn es sich um eine Paket- oder Klassenhierarchie wie oben handelt, wird das Protokoll wie folgt ausgegeben.

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ätsel lösen

Dies ist eine Erklärung dafür, wie ich das Fehlen von Abhängigkeiten bemerkt habe. Ich denke, dass es für diejenigen sein wird, die zwischen oder über Java sind.

Besteht der Pass überhaupt?

Die folgenden Gründe sind möglich, warum log4j2.yml nicht geladen wird.

  1. Der Pfad zum Konfigurationsdateiverzeichnis wird nicht übergeben
  2. Es fehlt an etwas, das über das menschliche Wissen hinausgeht

Benennen wir zuerst "log4j2.yml" in "log4j2.xml" um, um den Fall von "1" zu überprüfen. Dann tritt die folgende Ausnahme auf.

[Fatal Error] log4j2.xml:1:1:Für den Prolog kann kein Inhalt angegeben werden.
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;Für den Prolog kann kein Inhalt angegeben werden.
  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)
(Unterlassung)

Es scheint, dass es als "log4j2.xml" erkannt und als XML analysiert wird. Ich interessiere mich für die folgenden Protokolle. Ist es nicht möglich, durch Untersuchen der Klasse "ConfigurationFactory" Hinweise zu erhalten?

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

Lassen Sie uns den Quellcode von log4j2 untersuchen

Wenn Sie sich die Treffer ansehen, die mit "log4j2" "ConfigurationFactory" als Schlüsselwort gegoogelt wurden, wird Artikel der URL mit "https: // github.com" beginnen /blob/master/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java) kann gefunden werden. Gehen Sie über den Link zur Hauptseite des Repositorys, überprüfen Sie die URL für Clone und führen Sie "git clone" aus.

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

Wenn Sie sich das Projekt ansehen, ist pom.xml vorhanden. Führen Sie daher den folgenden Maven-Befehl aus, um es in Eclipse zu importieren.

mvn eclipse:eclipse

Wenn Sie nach dem Import in Eclipse als Maven-Projekt die Klasse "ConfigurationFactory" und ihre Umgebung überprüfen, werden Sie feststellen, dass sich unter dem Paket "config" ein echtes Paket wie "json" "xml" yaml "befindet.

config.png

[YamlConfigurationFactory](https://github.com/apache/logging-log4j2/blob/master/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ im Paket "yaml" yaml / YamlConfigurationFactory.java) Die Klasse existiert. Wenn Sie sich die Implementierung von "YamlConfigurationFactory" ansehen, werden Sie von Anfang an die Antwort sehen. Es scheint, dass "YamlConfigurationFactory" erst wirksam wird, wenn alle in der Variablen "Abhängigkeiten" definierten Klassen vollständig sind. Wenn Sie "build.gradle" so ändern, dass "com.fasterxml.jackson.databind" "com.fasterxml.jackson.core" in der Abhängigkeit enthalten ist, verschwindet das Fehlerprotokoll des Beispiels und der Inhalt wird in "log4j2.yml" festgelegt Das Protokoll wird jetzt mit ausgegeben.

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;
}

Zusätzliche Validierung

Ich frage mich, warum dies die Implementierung ist, obwohl die YAML-Konfigurationsdatei jetzt geladen ist. ConfigurationFactory.java ist der Schlüssel zum Lesen und Interpretieren der Konfigurationsdatei des Loggers. Ich habe versucht, den Ablauf der Verarbeitung zu verfolgen, der sich auf Apache (Logging / Log4J / Core / Config / ConfigurationFactory.java) konzentriert. Grob gesagt war die Implementierung so, dass die entsprechenden Erweiterungen entsprechend ihrer Priorität im Round-Robin-Verfahren auf das Vorhandensein von Dateien überprüft wurden und die erste Treffereinstellungsdatei verwendet wurde. Nachfolgend finden Sie die Priorität von Erweiterungen.

Priorität der Konfigurationsdateierweiterung

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

Bei der Ausführung eines Tests wird der Dateiname mit "Test" berücksichtigt, um der Testdatei Priorität einzuräumen. Unter Berücksichtigung der Priorität der Erweiterung und der Testdatei wird die Dateiexistenzprüfung schließlich in der folgenden Reihenfolge ausgeführt. Und für YAML und JSON werden zusätzliche Klassen zum Parsen benötigt. Überprüfen Sie daher die Abhängigkeiten mit der Factory-Klasse und ignorieren Sie das Vorhandensein der Konfigurationsdatei, wenn nicht alle erforderlichen Bibliotheken verfügbar sind. Es ist eine Implementierung, die durchgeführt wird. Dies kann zu Situationen führen, in denen "log4j2.xml" gelesen wird, "log4j2.yml" und "log4j2.json" jedoch ignoriert werden.

Priorität des Konfigurationsdateinamens

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

Die Überprüfung der Abhängigkeitsbibliothek wird wie folgt implementiert, aber es scheint, dass "Fehlende Abhängigkeiten für die Json-Unterstützung" aufgrund der Protokollstufe nicht ausgegeben wird. Es scheint, dass eine andere Einstellung erforderlich ist, um dieses Protokoll auszugeben ...

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

Recommended Posts

Verwenden Sie log4j2 mit YAML + Gradle
Verwenden Sie ProGuard mit Gradle
Verwenden Sie WebJars mit Gradle
Verwenden Sie jlink mit gradle
Integrationstest mit Gradle
Verwenden Sie Puphpeteer mit Docker
Verwenden Sie XVim2 mit Xcode 12.0.1
Verwenden von CentOS mit LXD
Installieren Sie Gradle auf ubuntu16.04
Datenkern beginnend mit Gradle
Verwenden Sie Webmock mit Rspec
Wie benutzt man Gradle?
Beginnen Sie mit Gradle
Verwenden Sie Lambda-Ebenen mit Java
Erstellen Sie mit Gradle ein Java-Multiprojekt
Verwenden Sie GDAL mit Python mit Docker
Gradle + Kotlin-Glas mit DSL generieren
Verwenden Sie Thymeleaf mit Azure-Funktionen
[PHP8] Installieren und verwenden Sie die YAML-Funktion (YAML-Parser) von PECL mit Docker
Verwenden Sie die Bulk-API mit RestHighLevelClient
Lombok arbeitet nicht mit Gradle5
Verwenden Sie SDKMAN! Mit Git Bash
Verwenden Sie Spring JDBC mit Spring Boot
Verwenden Sie Ruby mit Google Colab
Hallo Welt mit SpringBoot / Gradle
[Docker] Wird immer mit Docker + Rails verwendet
Verwenden Sie PlantUML mit Visual Studio Code
Verwenden Sie die Standardauthentifizierung mit Spring Boot
Erstellen eines Java-Projekts mit Gradle
Verwenden Sie Java mit MSYS und Cygwin
Verwenden Sie den Konstruktor mit Argumenten in cucumber-picocontainer
Verwenden Sie Microsoft Graph mit Standard-Java
Verwenden Sie den PostgreSQL-Inet-Typ mit DbUnit
Ich habe versucht, JOOQ mit Gradle zu verwenden
Verwenden Sie Bootstrap 4 mit PlayFramework 2.6 (kein CDN)
Ausgabe Testabdeckung mit Klee + Gradle
Ich kann Lombok nicht mit Gradle installieren.
Verwenden Sie Azure Bing SpellCheck mit Java
Verwenden Sie JDBC mit Java und Scala.
Verwenden Sie DataDog APM mit nicht unterstützten Frameworks
Verwenden Sie Java 11 mit Google Cloud-Funktionen
Wie man mssql-tools mit alpine benutzt
Beginnend mit Spring Boot 0. Verwenden Sie Spring CLI
Verwenden von cuda11.0 mit pytorch mit Docker
Entwickeln Sie die Verarbeitung mit IntelliJ + Kotlin + Gradle