2011-08-19 5 views
49

Chcę dodać niektóre instrukcje log.debug do klasy, nad którą pracuję, i chciałbym to zobaczyć w wynikach podczas uruchamiania testu. Chciałbym zastąpić właściwości log4j w wierszu poleceń, z czymś takim:Jak ustawić poziom log4j w wierszu poleceń?

-Dlog4j.logger.com.mypackage.Thingie=DEBUG 

Robię to często. Interesuje mnie tylko sposób przekazania tego w linii poleceń. Wiem, jak to zrobić z plikiem konfiguracyjnym, a to nie pasuje do mojego przepływu pracy.

Odpowiedz

12

log4j nie obsługuje tego bezpośrednio.

Ponieważ nie chcesz pliku konfiguracyjnego, najprawdopodobniej użyjesz programistycznej konfiguracji. Sugerowałbym, żebyś zajrzał do skanowania wszystkich właściwości systemu i jawnie zaprogramował to, co chcesz na podstawie tego.

41

Jako część argumentów jvm można ustawić -Dlog4j.configuration=file:"<FILE_PATH>". Gdzie FILE_PATH jest ścieżką do pliku log4j.properties.

Należy pamiętać, że od log4j2, nowa zmienna systemowa do wykorzystania jest log4j.configurationFile i umieścić w rzeczywistej ścieżki do pliku (czyli bez prefiksu file:) i automatycznie załadować fabrykę na podstawie rozszerzenia konfiguracji plik:

-Dlog4j.configurationFile=/path/to/log4jconfig.{ext} 
+3

Funkcja FILE_PATH jest faktycznie przeszukiwana w zmiennej CLASSPATH, w tym w plikach jar. –

+12

Musisz umieścić "file:" przed ścieżką, jeśli jest to plik na dysku. Innymi słowy ... -Dlog4j.configuration = file: http://stackoverflow.com/questions/778933/log4j-configuration-via-jvm-arguments – crowmagnumb

+0

Działa to tak jak w reklamie; jednak próbuję przesłonić ustawienie pliku właściwości w słoiku, a drugi wydaje się ustawić po. Jakakolwiek rada? –

6

podstawie Thorbjørn Ravn Andersens sugestią pisałem jakiś kod, który sprawia, że ​​praca ta

dodać następujące wcześnie główne metody i jest obecnie możliwe, aby ustawić poziom dziennika z wiersza Comand. Zostały one przetestowane w moim projekcie, ale jestem nowy w log4j i mogłem popełnić jakiś błąd. Jeśli tak, popraw mnie.

Logger.getRootLogger().setLevel(Level.WARN); 
    HashMap<String,Level> logLevels=new HashMap<String,Level>(); 
    logLevels.put("ALL",Level.ALL); 
    logLevels.put("TRACE",Level.TRACE); 
    logLevels.put("DEBUG",Level.DEBUG); 
    logLevels.put("INFO",Level.INFO); 
    logLevels.put("WARN",Level.WARN); 
    logLevels.put("ERROR",Level.ERROR); 
    logLevels.put("FATAL",Level.FATAL); 
    logLevels.put("OFF",Level.OFF); 
    for(String name:System.getProperties().stringPropertyNames()){ 
     String logger="log4j.logger."; 
     if(name.startsWith(logger)){ 
      String loggerName=name.substring(logger.length()); 
      String loggerValue=System.getProperty(name); 
      if(logLevels.containsKey(loggerValue)) 
       Logger.getLogger(loggerName).setLevel(logLevels.get(loggerValue)); 
      else 
       Logger.getRootLogger().warn("unknown log4j logg level on comand line: "+loggerValue); 
     } 
    } 
2

Na podstawie @lijat, oto uproszczona implementacja. W mojej aplikacji na wiosnę po prostu ładuję to jako fasolę.

public static void configureLog4jFromSystemProperties() 
{ 
    final String LOGGER_PREFIX = "log4j.logger."; 

    for(String propertyName : System.getProperties().stringPropertyNames()) 
    { 
    if (propertyName.startsWith(LOGGER_PREFIX)) { 
     String loggerName = propertyName.substring(LOGGER_PREFIX.length()); 
     String levelName = System.getProperty(propertyName, ""); 
     Level level = Level.toLevel(levelName); // defaults to DEBUG 
     if (!"".equals(levelName) && !levelName.toUpperCase().equals(level.toString())) { 
     logger.error("Skipping unrecognized log4j log level " + levelName + ": -D" + propertyName + "=" + levelName); 
     continue; 
     } 
     logger.info("Setting " + loggerName + " => " + level.toString()); 
     Logger.getLogger(loggerName).setLevel(level); 
    } 
    } 
} 
20

Te odpowiedzi faktycznie zniechęciły mnie do wypróbowania najprostszej możliwej rzeczy! Wystarczy określić wartość progową dla appender (powiedzmy, „Konsola”) w swojej log4j.configuration tak:

log4j.appender.console.threshold=${my.logging.threshold} 

Następnie w linii poleceń, to właściwość systemu -Dlog4j.info -Dmy.logging.threshold=INFO. Zakładam, że dowolną inną właściwość można sparametryzować w ten sposób, ale jest to najprostszy sposób na podniesienie lub obniżenie poziomu rejestrowania na całym świecie.

+0

Jestem prawie pewien, że to najprostsze rozwiązanie pierwotnego pytania! – Droj

+0

@Droj Może tak, ale OP chciał zrobić to wszystko w kodzie. Chacun, syn dna. –

+0

W moim przypadku chciałem ustawić także z linii poleceń, ale miałem już konfigurację. Po prostu nie chciałem edytować pliku, aby uzyskać inne rejestrowanie. Nie przeczytałem tego jako "wszystko w kodzie", ale może tak ... – Droj

7

Z Log4j2 można to osiągnąć, stosując następującą metodę użytkową dodaną do kodu.

private static void setLogLevel() { 
    if (Boolean.getBoolean("log4j.debug")) { 
    Configurator.setLevel(System.getProperty("log4j.logger"), Level.DEBUG); 
    } 
} 

Trzeba przywóz

import org.apache.logging.log4j.Level; 
import org.apache.logging.log4j.core.config.Configurator; 

teraz wywołać metodę setLogLevel w głównym() lub gdziekolwiek właściwe i przechodzić linia poleceń params -Dlog4j.logger=com.mypackage.Thingie i -Dlog4j.debug=true.

+1

To powinno być zaakceptowaną odpowiedzią teraz, gdy pakiety są aktualizowane. Dziękuję za zaktualizowaną odpowiedź - głęboko doceniam zaktualizowane odpowiedzi, jeśli chodzi o długotrwałe pytania. Uratowałeś mi sporo frustracji. –