Ich muss Log-Logger und andere Bits dynamisch für Klassen erstellen, die dynamisch geladen und neu geladen werden. Ich habe eine variable Anzahl dieser Klassen, obwohl es insgesamt weniger als 150 sein wird. Leistung ist ein großes Anliegen und dies ist eine hochgradige Threaded und extrem gleichzeitige Umgebung, so dass die Idee der Verwendung von MDC wird nicht aufgrund von möglicherweise Tausende von Anrufen pro Sekunde, wenn die Dinge schief gehen. Ich möchte auch nicht direkt die Logger in die Klassen bringen, ich möchte, dass sie sie einfach mit getLogger aus der Luft ziehen, wie es typisch ist.Log-Logger und Appender dynamisch erstellen
Jede Klasse muss alle Fehlermeldungen in ihre eigene Fehlerdatei und alle Trace-Nachrichten in ihre eigene Trace-Datei eintragen. Beide Dateien müssen sich jeden Abend rollen. Darüber hinaus muss alles, was im System angemeldet ist, auch in den Hauptsystemprotokollen enden.
Ich habe das folgende Code-Snippet erstellt, um diese Idee auszuprobieren. Es scheint, als würde es funktionieren, aber die Ergebnisse sind nicht das, was ich erwarten würde. Hier haben wir das Testprogramm, das direkt ausgeführt werden können:
package logbacktesting;
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.classic.filter.LevelFilter;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.util.StatusPrinter;
import org.slf4j.LoggerFactory;
public class Main {
public static void main(String[] args) {
Logger templateLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.myapp");
LoggerContext loggerContext = templateLogger.getLoggerContext();
String[] nameList = new String[] {"test1.class", "test2.class"};
// Set up the pattern
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
encoder.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
encoder.start();
// Spin over the names to create all the needed objects
for(int i = 0; i < nameList.length; i++) {
String name = nameList[i];
// Set up the roll over policies and the name when it rolls over
TimeBasedRollingPolicy tracePolicy = new TimeBasedRollingPolicy();
tracePolicy.setContext(loggerContext);
tracePolicy.setFileNamePattern(name + "-Trace-%d{yyyy-MM-dd}.log");
tracePolicy.setMaxHistory(30);
TimeBasedRollingPolicy errorPolicy = new TimeBasedRollingPolicy();
errorPolicy.setContext(loggerContext);
errorPolicy.setFileNamePattern(name + "-Error-logFile.%d{yyyy-MM-dd}.log");
errorPolicy.setMaxHistory(30);
// Set up the filters to ensure things get split as expected
LevelFilter traceFilter = new LevelFilter();
traceFilter.setContext(loggerContext);
traceFilter.setLevel(Level.TRACE);
traceFilter.setOnMatch(FilterReply.ACCEPT);
traceFilter.setOnMismatch(FilterReply.DENY);
LevelFilter errorFilter = new LevelFilter();
errorFilter.setContext(loggerContext);
errorFilter.setLevel(Level.ERROR);
errorFilter.setOnMatch(FilterReply.ACCEPT);
errorFilter.setOnMismatch(FilterReply.DENY);
// Set up the trace and error appenders
RollingFileAppender rollingFileAppenderTrace = new RollingFileAppender();
rollingFileAppenderTrace.setContext(loggerContext);
rollingFileAppenderTrace.setName(name + "-Trace");
rollingFileAppenderTrace.setFile(name + "-Trace.log");
rollingFileAppenderTrace.setEncoder(encoder);
rollingFileAppenderTrace.setRollingPolicy(tracePolicy);
rollingFileAppenderTrace.addFilter(traceFilter);
tracePolicy.setParent(rollingFileAppenderTrace);
RollingFileAppender rollingFileAppenderError = new RollingFileAppender();
rollingFileAppenderError.setContext(loggerContext);
rollingFileAppenderError.setName(name + "-Error");
rollingFileAppenderError.setFile(name + "-Error.log");
rollingFileAppenderError.setEncoder(encoder);
rollingFileAppenderError.setRollingPolicy(errorPolicy);
rollingFileAppenderError.addFilter(errorFilter);
errorPolicy.setParent(rollingFileAppenderError);
// Start everything
tracePolicy.start();
errorPolicy.start();
traceFilter.start();
errorFilter.start();
rollingFileAppenderTrace.start();
rollingFileAppenderError.start();
// attach the rolling file appenders to the logger
Logger logger = (ch.qos.logback.classic.Logger) loggerContext.getLogger(name);
logger.addAppender(rollingFileAppenderTrace);
logger.addAppender(rollingFileAppenderError);
}
StatusPrinter.print(loggerContext);
// Test it to see what happens
for(int i = 0; i < nameList.length; i++) {
String name = nameList[i];
Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(name);
logger.error("error message");
logger.warn("warn message");
logger.info("info message");
logger.debug("debug message");
logger.trace("trace message");
}
Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.myapp");
logger.error("generic error message ");
}
}
Hier wird die logback.xml Datei:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
Wenn Sie diesen Code ausführen, wird es richtig alles in die Haupt-Protokolldatei protokollieren . Und es wird 2 Trace und 2 Fehlerprotokolle wie erwartet erstellen. Keine der Trace-Nachrichten wird jedoch in den Trace-Protokolldateien gespeichert, und beide Fehlermeldungen landen in der Fehlerdatei der Klasse 2. Es verhält sich so, als ob alle 4 Appender zum selben Logger hinzugefügt werden und nur der letzte Appender, der hinzugefügt wird, funktioniert. Ich würde gerne verstehen, was ich hier mache. Vielen Dank!
Welche Version Logbuch ist das? – fge
Sieht ziemlich gut aus. Das einzige Problem, das ich aus einem flüchtigen Blick erkennen konnte, ist, dass Sie keine Encoder freigeben sollten. Sie müssen für jede Datei/RollingFileAppender eine neue Datei erstellen. – Ceki
Ah, toller Fang. Das hat absolut Probleme verursacht. Das andere Problem war, dass die root-Ebene von debug Trace sein sollte! Vielen Dank! –