Wenn Sie versuchen, Code zu ändern, der für die Erstellung von Loggern verantwortlich ist, müssen als Referenz eine Reihe von Regeln erfüllt sein, damit ein Logger funktioniert.
Diese Regeln wurden in einem großartigen und hilfreichen Artikel Programmatische Konfiguration von slf4j / logback beschrieben :
Jetzt habe ich Erfahrung mit der programmatischen Konfiguration von slf4j / logback.
Aufgabe
Ein Programm muss für jede verarbeitete Eingabedatei eine separate Protokolldatei öffnen.
Lösung für Aufgabe
Anstatt Logback über XML zu konfigurieren, muss man Encoder, Appender und Logger „manuell“ instanziieren und sie dann konfigurieren und miteinander verknüpfen.
Vorsichtsmaßnahme 1
Logback wird verrückt, wenn versucht wird, den Encoder (dh PatternLayoutEncoder) zwischen Appendern zu teilen.
Lösung für Vorbehalt 1
Erstellen Sie für jeden Appender einen separaten Encoder.
Vorsichtsmaßnahme 2
Logback weigert sich, irgendetwas zu protokollieren, wenn Encoder und Appender nicht mit dem Protokollierungskontext verknüpft sind.
Lösung für Vorbehalt 2
Rufen Sie setContext für jeden Encoder und Appender auf und übergeben Sie LoggerFactory als Parameter.
Vorsichtsmaßnahme 3
Logback weigert sich, irgendetwas zu protokollieren, wenn Encoder und Appender nicht gestartet werden.
Lösung für Vorbehalt 3
Encoder und Appender müssen in der richtigen Reihenfolge gestartet werden, dh zuerst Encoder, dann Appender.
Vorsichtsmaßnahme 4
RollingPolicy-Objekte (dh TimeBasedRollingPolicy) erzeugen seltsame Fehlermeldungen wie "Datumsformat nicht erkannt", wenn sie nicht an denselben Kontext wie Appender angehängt sind.
Lösung für Vorbehalt 4
Rufen Sie setContext auf RollingPolicy genauso auf wie auf Encodern und Appendern.
Hier ist ein Arbeitsbeispiel für die manuelle Logback-Konfiguration:
package testpackage
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.LoggerContext
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.rolling.RollingFileAppender
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy
import org.slf4j.LoggerFactory
class TestLogConfig {
public static void main(String[] args) {
LoggerContext logCtx = LoggerFactory.getILoggerFactory();
PatternLayoutEncoder logEncoder = new PatternLayoutEncoder();
logEncoder.setContext(logCtx);
logEncoder.setPattern("%-12date{YYYY-MM-dd HH:mm:ss.SSS} %-5level - %msg%n");
logEncoder.start();
ConsoleAppender logConsoleAppender = new ConsoleAppender();
logConsoleAppender.setContext(logCtx);
logConsoleAppender.setName("console");
logConsoleAppender.setEncoder(logEncoder);
logConsoleAppender.start();
logEncoder = new PatternLayoutEncoder();
logEncoder.setContext(logCtx);
logEncoder.setPattern("%-12date{YYYY-MM-dd HH:mm:ss.SSS} %-5level - %msg%n");
logEncoder.start();
RollingFileAppender logFileAppender = new RollingFileAppender();
logFileAppender.setContext(logCtx);
logFileAppender.setName("logFile");
logFileAppender.setEncoder(logEncoder);
logFileAppender.setAppend(true);
logFileAppender.setFile("logs/logfile.log");
TimeBasedRollingPolicy logFilePolicy = new TimeBasedRollingPolicy();
logFilePolicy.setContext(logCtx);
logFilePolicy.setParent(logFileAppender);
logFilePolicy.setFileNamePattern("logs/logfile-%d{yyyy-MM-dd_HH}.log");
logFilePolicy.setMaxHistory(7);
logFilePolicy.start();
logFileAppender.setRollingPolicy(logFilePolicy);
logFileAppender.start();
Logger log = logCtx.getLogger("Main");
log.setAdditive(false);
log.setLevel(Level.INFO);
log.addAppender(logConsoleAppender);
log.addAppender(logFileAppender);
}
}