2011-08-19 24 views
49

Quiero agregar algunas sentencias log.debug a una clase en la que estoy trabajando, y me gustaría ver eso en el resultado al ejecutar la prueba. Me gustaría para invalidar las propiedades de log4j en la línea de comandos, con algo como esto:¿Cómo configuro el nivel log4j en la línea de comando?

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

hago este tipo de cosas con frecuencia. Específicamente, solo estoy interesado en una forma de pasar esto en la línea de comando. Sé cómo hacerlo con un archivo de configuración, y eso no se ajusta a mi flujo de trabajo.

Respuesta

12

log4j no es compatible con esto directamente.

Como no desea un archivo de configuración, lo más probable es que utilice la configuración de programación. Sugeriría que analice todas las propiedades del sistema y, explícitamente, programe lo que desee basándose en esto.

41

Como parte de sus argumentos jvm, puede establecer -Dlog4j.configuration=file:"<FILE_PATH>". Donde FILE_PATH es la ruta de su archivo log4j.properties.

Tenga en cuenta que a partir del log4j2, la nueva variable de sistema a utilizar es log4j.configurationFile y se puso en el camino real para el archivo (es decir, sin la file: prefijo) y se cargará automáticamente la fábrica sobre la base de la extensión de la configuración archivo:

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

FILE_PATH se busca realmente en CLASSPATH, incluidos los archivos jar internos. –

+12

Debe colocar "file:" delante de la ruta si se trata de un archivo en el disco. En otras palabras ... -Dlog4j.configuración = archivo: http://stackoverflow.com/questions/778933/log4j-configuration-via-jvm-arguments – crowmagnumb

+0

Esto funciona como se anuncia; sin embargo, estoy tratando de anular una configuración de un archivo de propiedades en el jar, y este último parece establecerse después. ¿Algún consejo? –

6

Basado en Thorbjørn Ravn Andersen sugerencia que escribió un código que hace que este trabajo

Añadir la siguiente temprano en el método principal y ahora es posible ajustar el nivel de registro desde la línea de comand. Esto ha sido probado en un proyecto mío, pero soy nuevo en log4j y podría haber cometido algún error. Si es así, por favor corrígeme.

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

Basado en @lijat, aquí hay una implementación simplificada. En mi aplicación basada en primavera simplemente cargo esto como un frijol.

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

¡Estas respuestas realmente me disuadieron de intentar lo más simple posible! Sólo tiene que especificar un umbral para una appender (por ejemplo, "consola") en su log4j.configuration así:

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

A continuación, en la línea de comandos, incluye la propiedad del sistema -Dlog4j.info -Dmy.logging.threshold=INFO. Supongo que cualquier otra propiedad se puede parametrizar de esta manera, pero esta es la forma más fácil de subir o bajar el nivel de registro globalmente.

+0

¡Estoy bastante seguro de que esta es la solución más simple a la pregunta original! – Droj

+0

@Droj Quizás sea así, pero OP quería hacer todo esto en código. Chacun un hijo gout. –

+0

En mi caso, quería configurarlo desde la línea de comandos también, pero ya tenía una configuración. Simplemente no quería tener que editar el archivo para obtener un registro diferente. No lo leí como "todo en código", pero tal vez sea así ... – Droj

7

Con Log4j2, esto se puede lograr utilizando el siguiente método de utilidad agregado a su código.

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

necesita estos importaciones

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

Ahora invocan el método setLogLevel en su main() o dondequiera apropiado y pasan la línea de comando Parámetros -Dlog4j.logger=com.mypackage.Thingie y -Dlog4j.debug=true.

+1

Esta debería ser la respuesta aceptada ahora que se actualizan los paquetes. Gracias por una respuesta actualizada. Agradezco profundamente las respuestas actualizadas cuando se trata de preguntas de larga data. Me salvaste un poco de frustración. –

Cuestiones relacionadas