2012-05-17 17 views
11

Próbuję skonfigurować oddzielne pliki dziennika dla różnych pakietów. Używam klasy Wrapper do rejestratora log4j. Każda klasa w mojej aplikacji wywołuje tę samą klasę opakowania. Moja klasa wrapper:Jak tworzyć różne pliki dzienników dla różnych pakietów przy użyciu tego samego programu rejestrującego log4j?

public class MyLogger 
{ 
    private static Logger logger = Logger.getLogger(MyLogger.class.getName()); 
    .... 
    .... 
} 

To się nazywa tak:

MyLogger.write(, ,); 

Czy istnieje sposób skonfigurować log4j tak, że wysyła rejestrowanie różnych pakietów do różnych plików?

Dzięki!

Edit:

Oto moja log4j.properties file:

log4j.rootLogger=DEBUG, infoout, aar 
log4j.logger.com.businessservice.datapopulation=DEBUG, aar 
log4j.additivity.com.businessservice.datapopulation=false 

log4j.appender.infoout = org.apache.log4j.RollingFileAppender 
log4j.appender.infoout.file=/app/aar_frontend.log 
log4j.appender.infoout.append=true 
log4j.appender.infoout.Threshold=DEBUG 
log4j.appender.infoout.MaxFileSize=2MB 
log4j.appender.infoout.MaxBackupIndex=10 
log4j.appender.infoout.layout = org.apache.log4j.PatternLayout 
log4j.appender.infoout.layout.ConversionPattern = %m%n 

log4j.appender.aar = org.apache.log4j.RollingFileAppender 
log4j.appender.aar.file=/app/aar/aar_backend.log 
log4j.appender.aar.append=true 
log4j.appender.aar.Threshold=DEBUG 
log4j.appender.aar.MaxFileSize=2MB 
log4j.appender.aar.MaxBackupIndex=10 
log4j.appender.aar.layout = org.apache.log4j.PatternLayout 
log4j.appender.aar.layout.ConversionPattern = %m%n 

Odpowiedz

4

Jeśli utworzysz statyczny program rejestrujący w klasie MyLogger, masz jedną instancję programu Logger o nazwie ustawionej na MyLogger. Kiedy wywołujesz ten rejestrator z innych pakietów, Log4j nie jest w stanie ustalić pochodzenia tych połączeń, ponieważ wszystkie one używają tego samego Loggera.

Najlepszym sposobem, aby go obsłużyć, jest zdefiniowanie osobnego Logger w każdej klasie, ale jeśli chcesz używać jednej klasy jako punktu styku z Log4j, to można to zrobić:

package com.daniel.logger; 
import org.apache.log4j.Logger; 

import com.daniel.package1.ClassA; 
import com.daniel.package2.ClassB; 

public class MyLogger{ 

    public static void write(String message, Class<?> clazz){ 
     Logger.getLogger(clazz).info(message); 
    } 

    public static void main(String[] args){ 
     ClassA.log(); 
     ClassB.log(); 
    } 
} 

następnie jeden z klasy używając go może wyglądać tak:

package com.daniel.package1; 

import com.daniel.logger.MyLogger; 

public class ClassA { 

    public static void log(){ 
     MyLogger.write("ClassA",ClassA.class); 
    } 
} 

a plik log4j.properties wyglądałby następująco:

log4j.appender.package1=org.apache.log4j.FileAppender 
log4j.appender.package1.File=package1.log 
log4j.appender.package1.layout=org.apache.log4j.PatternLayout 

log4j.appender.package2=org.apache.log4j.FileAppender 
log4j.appender.package2.File=package2.log 
log4j.appender.package2.layout=org.apache.log4j.PatternLayout 

log4j.logger.com.daniel.package1=DEBUG,package1 
log4j.logger.com.daniel.package2=DEBUG,package2 

Jeśli nie chcesz przekazać klasy z ClassA, można użyć paskudną sztuczkę z refleksji, który dostaje powołanie nazwy klasy, ale nie polecam, aby w wyniku trafienia Osiągi:

public class MyLogger 
{ 

    public static void write(String message){ 
     StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 
     Logger.getLogger(stackTraceElements[2].getClassName()).info(message); 
    } 

    public static void main(String[] args){ 
     ClassA.log(); 
     ClassB.log(); 
    } 
} 
+0

Dzięki !.Jeszcze jedno pytanie: Czy mogę sprawdzić (w java) czy appender dla konkretnej klasy jest zdefiniowany czy nie w pliku konfiguracyjnym log4j? – HashimR

0

Można to zrobić tak (com.myco.a i com.myco.b bycia swoje 2 różne pakiety):

log4j.logger.com.myco.a=DEBUG, infoout 
log4j.logger.com.myco.b=DEBUG, aar 

Pozdrawiam.

+0

Próbowałem. Brak szczęścia! – HashimR

+0

Czy używasz tego samego programu rejestrującego w swoim kodzie? Masz na celu utworzenie rejestratora w każdej klasie – Philippe

+0

Używam tej samej klasy rejestratora wrappera we wszystkich moich aplikacjach. Również wspomniane w pytaniu. – HashimR

0

Utworzenie 2 elementów dodających i 2 rejestratorów wykonałoby to, co chcesz.

+0

Nie można osiągnąć używając pojedynczego 'Logger'a '? – HashimR

0

Odczytaj wymaganą niestandardową lokalizację pliku z pliku właściwości lub tak dla każdego pakietu. Następnie możesz użyć poniższej podanej metody, aby zaktualizować lokalizację pliku log4j w pliku prop log4j:

private void updateLog4jConfiguration(String logFile) { 
    java.util.Properties properties = new Properties(); 
    try { 
     InputStream configStream = getClass().getResourceAsStream("/log4j.properties"); 
     properties.load(configStream); 
     configStream.close(); 
     } 
    catch (IOException e) { 
     System.out.println("Error: Cannot laod configuration file "); 
     } 
    properties.setProperty("log4j.appender.FILE.file", logFile); 
    org.apache.log4j.LogManager.resetConfiguration(); 
    org.apache.log4j.PropertyConfigurator.configure(properties); 
} 
+1

To nie będzie zbyt dobrze. Log4j będzie musiał przełączać się pomiędzy dwoma plikami przez cały czas, zamykając strumień na jeden i otwierając na drugi. – daniel

Powiązane problemy