Pregunta Log4J2 - asignación de nombre de archivo del appendador en tiempo de ejecución


Tengo un archivo de configuración log4j2.xml en la ruta de clase. Uno de los appenders es un apéndice de archivo, y me gustaría establecer el nombre del archivo de destino en tiempo de ejecución en la aplicación Java.

De acuerdo con la documentos Debería poder usar un doble "$" y un prefijo de contexto en el archivo log4j2.xml:

<appenders>
    <File name="MyFile" fileName="$${sys:logFilename}">
        <PatternLayout pattern="%-4r %d{${datestamp}} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>

donde el prefijo "sys" indica que el Configurador buscará la propiedad "logFilename" en las propiedades del sistema. Entonces, en la aplicación, llamo (más temprano):

System.setProperty("logFilename", filename);

También he activado la reconfiguración automática para log4j2 en el archivo xml:

<configuration status="debug" monitorInterval="5">>

Lamentablemente, esto no tiene ningún efecto y el archivo de registro nunca se crea. Parte del resultado del estado de log4j2 es el siguiente:

2013-02-13 15: 36: 37,574 DEPURACIÓN Llamar a createAppender en la clase org.apache.logging.log4j.core.appender.FileAppender para el elemento File with params (fileName = "$ {sys: logFilename}", append = "null" , locking = "null", name = "MyFile", immediateFlush = "null", suppressExceptions = "null", bufferedIO = "null", PatternLayout (% - 4r% d {aaaa-MM-dd / HH: mm: ss .SSS / zzz} [% t]% -5level% logger {36} -% msg% n), null)

2013-02-13 15: 36: 37,576 DEBUG Inicio de FileManager $ {sys: logFilename}

¿Cómo puedo hacer que el valor de "fileName" en File Appender se configure en tiempo de ejecución?  Alternativamente, ¿cómo puedo simplemente agregar un nuevo apéndice de archivo al registrador de raíz en tiempo de ejecución? En Log4j 2.0, la mayor parte de la API para cambiar la configuración está oculta.


32
2018-02-13 20:45


origen


Respuestas:


h / t rgoers FileAppender no admite dos signos de dólar en el nombre del archivo ya que el archivo se abre cuando se inicia el appender. Lo que está indicando con dos signos de dólar es que quiere, potencialmente, un nombre de archivo diferente para cada evento.

Con un solo $ (como en ${sys:logFilename}), el sistema buscará la propiedad "logFilename" en las propiedades del sistema.

Por lo tanto, log4j2.xml debería tener:

<appenders>
    <File name="MyFile" fileName="${sys:logFilename}">
        <PatternLayout pattern="%-4r %d{${datestamp}} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>

La aplicación Java debe establecer la propiedad del sistema:

System.setProperty("logFilename", filename);

y reconfigurar el registrador:

org.apache.logging.log4j.core.LoggerContext ctx =
    (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
ctx.reconfigure();

Esto produce el comportamiento deseado.


33
2018-02-14 15:01



A partir de la versión log4j2 2.5 aquí está la manera más simple de lograr esto:

En tus log4j2.xml:

<Appenders>
   <File name="MyFile" filename="${sys:logFilename}">
   ...

En ti principal MyApp.java archivo:

public class MyApp {

    Logger log;

    static {
          System.setProperty("logFilename", ...);
          log = LogManager.getLogger();
    }

    public static void main(String... args) {...}
}

CAPTURA: Debes establecer logFilename propiedad del sistema antes de que se cargue log4j2. En este ejemplo antes de llamar LogManager.getLogger.


7
2017-12-21 21:12



Sé que este tema es antiguo, pero las respuestas realmente no me sentaron bien. Aquí hay una función que le permite reconfigurar un Appender existente en tiempo de ejecución:

static void updateLogger(String file_name, String appender_name, String package_name){
LoggerContext context = (LoggerContext) LogManager.getContext(false);
    Configuration configuration = context.getConfiguration();
    Layout<? extends Serializable> old_layout = configuration.getAppender(appender_name).getLayout();

    //delete old appender/logger
    configuration.getAppender(appender_name).stop();
    configuration.removeLogger(package_name);

    //create new appender/logger
    LoggerConfig loggerConfig = new LoggerConfig(package_name, Level.INFO, false);
    FileAppender appender = FileAppender.createAppender(file_name, "false", "false", appender_name, "true", "true", "true",
            "8192", old_layout, null, "false", "", configuration);
    appender.start();
    loggerConfig.addAppender(appender, Level.INFO, null);
    configuration.addLogger(package_name, loggerConfig);

    context.updateLoggers();
}

Puede especificar un nombre de archivo, el nombre de su appender y el nombre del paquete que desea registrar.

Registrador de ejemplo:

<File name="fileWriter_api" fileName="${LOG_DIR}/api.log" append="false">
  <PatternLayout pattern="${PATTERN}"/>
</File>

Se puede reconfigurar llamando así:

updateLogger("log/api_new.log", "fileWriter_api", "my.package");

6
2018-06-29 09:55