2014-10-31 11 views
10

Ich möchte log4j ohne jede Konfigurationsdatei verwenden. Was ich wan ist, etwas zu tun wie:Wie konfiguriere ich Logger programmatisch in log4j2.02?

logger = (Logger) LogManager.getLogger(this.getClass()); 
String pattern = "[%level] %m%n"; 
//do something to make this logger output to an local file "/xxx/yyy/zzz.log" 

ich diese Antwort gefunden haben: Configuring Log4j Loggers Programmatically.

Aber die Dokumentation von Logger#addAppender sagt: Diese Methode ist nicht durch die öffentliche API ausgesetzt und wird in erster Linie für Unit-Tests verwendet.

Ich bin nicht sicher, ob es der richtige Weg ist, diese Methode in meinem Code zu verwenden, oder es gibt andere bessere Lösung, um mein Problem zu lösen.

Antwort

19

The official documentation zeigt ein Beispiel:

  1. Wenn die Konfigurationsdatei wird neu geladen und werden die manuell vorgenommenen Änderungen werden die Konfiguration geändert wird: Programatically

    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); 
    final Configuration config = ctx.getConfiguration(); 
    
    Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null, null,null, null); 
    Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config); 
    appender.start(); 
    config.addAppender(appender); 
    
    AppenderRef ref = AppenderRef.createAppenderRef("File", null, null); 
    AppenderRef[] refs = new AppenderRef[] {ref}; 
    LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j", "true", refs, null, config, null); 
    loggerConfig.addAppender(appender, null, null); 
    config.addLogger("org.apache.logging.log4j", loggerConfig); 
    ctx.updateLoggers(); 
    

    Mit diesen Einschränkungen der aktuellen Konfiguration hinzufügen verloren sein.

  2. Änderung der laufenden Konfiguration erfordert, dass alle aufgerufenen Methoden (addAppender und addLogger) synchronisiert werden.

Diese Lösung vermeidet org.apache.logging.log4j.core.Logger, Verfahren von der Kern Implementierung zu verwenden und es vermeidet schmutzig Guss wie folgt aus:

import org.apache.logging.log4j.Logger; 

Logger logger = (Logger) LogManager.getLogger(this.getClass()); 
((org.apache.logging.log4j.core.Logger) logger).addAppender(...); // Bypassing the public API 
+0

Wenn Sie planen, das Logger-Jar zu schattieren, um es vollständig auszublenden, fügen Sie es als erste Zeile hinzu: LogManager.setFactory (new Log4jContextFactory()); Jetzt können Sie auch alle Konfigurations- und Eigenschaftendateien mit einem Schattenfilter weglassen. – bebbo

0

Wenn ich einfach auf Ihre Anforderung antworte, kann ich drei Optionen vorschlagen. Ich benutze die erste für eine Art Bootstrap-Logger-Konfiguration; aber ich dachte, der zweite wäre zuerst notwendig. Ihre dritte Wahl scheint umständlich, da Sie verschiedene log4j API-s aufrufen müssen, um konfiguriert zu werden.

Mit Log4j über die einfache Logging-Framework für Java ...

  1. Machen Sie eine 'minimal' oder 'Standard' log4j.properties Datei in Ihren Ressourcen für die JAR-Datei. Dann erklären einige Statik ...

    private static final URL LOGGER_CONFIG_URL = resolveConfigUrl(); 
        : 
    
    private static URL resolveConfigUrl(){ 
    
        URL url = LogConfig.class.getResource(LOGGER_CONFIG_NAME); 
    
        if(null == url) // Second chance, try for a file. 
        { 
         url = FileHelp.resolveUrlNameAsUrlToFile(LOGGER_CONFIG_NAME); 
            //-- Make this function with: url = tmpFile.toURI().toURL() 
            // Plus appropriate try/catch and error checks. 
         } 
         return url; 
    } 
    
    private static void configureLogger(){ 
    
        BasicConfigurator.configure(); 
        PropertyConfigurator.configure(LOGGER_CONFIG_URL ); 
        LOG.info("Logging config done: " + LOGGER_CONFIG_NAME); 
    } 
    
  2. Schreiben Sie config ein Stream stattdessen eine Datei in Ihrem JAR zu platzieren und dann den Strom in die Log-Konfigurator als String geben und das obige Beispiel (mehr verwenden oder Weniger).

  3. Sie können die slf4j API verwenden, um Ihre Log-Konfiguration zu machen, anstatt direkt in Log4j zu schreiben. Die meisten Orte, die mir gefallen haben, bevorzugen die SLF4J Route.

Persönlich bevorzuge ich Option # 1; es ist leicht zu pflegen. Einfach und Sie können den Code immer neu anordnen, um eine Datei zu akzeptieren/suchen, die zuerst geladen werden soll. Es gibt einige andere seitliche Möglichkeiten, die Sie in Betracht ziehen können, z. B. das programmatische Festlegen von Umgebungsvariablen beim Start. Das scheint mir erfunden zu sein.

Die Art und Weise, wie ich # 1 verwende, besteht darin, eine Standard-/Bootstrap-Logger-Konfiguration über die Ressourcendatei einzurichten, die ihrerseits in die JAR-Datei eingebunden wird. Sie können die Dinge 'später rekonfigurieren, während diese Option Ihnen eine minimalistische Star-Up- oder Bootstrap-Konfiguration gibt. In den frühen Phasen habe ich festgestellt, dass Dinge (noch) nicht protokolliert wurden, weil die Logger-Initialisierung noch auf eingebetteten Apps stattfinden musste. Also behielt ich die einfache Option für Bootstrap (oder Standard) als eine grundlegende seitdem. Hoffe das hilft.

0

Mit der neuesten Version von log4j2, alle APIs wie

PatternLayout.createLayout, 
FileAppender.createAppender, 
LoggerConfig.createLogger 
erstellen

werden veraltet, es ist besser, ein benutzerdefiniertes Protokoll ConfigurationFactory zusammen mit ConfigurationBuilder für die programmgesteuerte Definition der Protokollkonfiguration zu verwenden.

Verwandte Themen