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.
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.
log4j2.yml
im Ordner src / main / resources
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.
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')
}
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
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
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.
Die folgenden Gründe sind möglich, warum log4j2.yml
nicht geladen wird.
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)
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.
[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;
}
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.
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.
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