Logback – Set log file name programmatically

In Logback, it is easy to set a log file name programmatically :

  1. In logback.xml, declares a variable like ${log.name}
  2. In Java, set the variable via System.setProperty("log.name", "abc")

1. Full example

1.1 A logback file, we will set the ${log.name} variable later.

src/main/resources/logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

	<property name="PRO_HOME" value="/home/mkyong/ant/logs" />
	<property name="USER_HOME" value="${PRO_HOME}" />

	<timestamp key="bySecond" datePattern="yyyyMMdd.HHmmss" />

	<appender name="FILE-ENGINE-ERROR" class="ch.qos.logback.core.FileAppender">
		<file>${USER_HOME}/${log.name}.error</file>
		<encoder>
			<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>
	
	<appender name="FILE-ENGINE" class="ch.qos.logback.core.FileAppender">
		<file>${USER_HOME}/${log.name}-${bySecond}.log</file>
		<encoder>
			<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} - %msg%n</pattern>
		</encoder>
	</appender>

	<logger name="com.mkyong.core" level="debug" additivity="false">
		<appender-ref ref="FILE-ENGINE" />
	</logger>

	<logger name="org.springframework" level="error" additivity="false">
		<appender-ref ref="FILE-ENGINE-ERROR" />
	</logger>

	<root level="error">
		<appender-ref ref="FILE-ENGINE-ERROR" />
	</root>

</configuration>

1.2 In Java, just set the file name via System.setProperty

AntRunApp.java

package com.mkyong.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AntRunApp {

    private final Logger logger = LoggerFactory.getLogger(AntRunApp.class);

	public static void main(String[] args) {

		//Set this before the logger start.
		System.setProperty("log.name", "mkyong");

		AntRunApp obj = new AntRunApp();
		obj.start();

	}

	private void start() {

        logger.debug("------ Starting Ant------");

     	//...
	}

}

Output

Debug log file path
/home/mkyong/ant/logs/mkyong-20150323.221959.log

Error log file path
/home/mkyong/ant/logs/mkyong.error

2. log.name.rir_IS_UNDEFINED.log

2.1 A common error, normally it is caused by the static logger. For example.

AntRunApp.java

package com.mkyong.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AntRunApp {

	// static, this logger will be initialized before the program is run.
	// All logs will be redirected to log.name.rir_IS_UNDEFINED.log
    private static final Logger logger = LoggerFactory.getLogger(AntRunApp.class);

	private void start() {

		System.setProperty("log.name", "mkyong");
		
        logger.debug("------ Starting Ant------");

     	//...
	}

}

To fix it, just delete the static type.

2.2 If you logs before the System.setProperty, this will also cause the common Logback variable UNDEFINED error.

AntRunApp.java

package com.mkyong.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AntRunApp {

    private final Logger logger = LoggerFactory.getLogger(AntRunApp.class);

	private void start() {

		//Please set the log name first!
		logger.debug("------ Starting Ant------");
		
		System.setProperty("log.name", "mkyong");
		
	}

}

References

  1. Logback.xml examples
  2. Logback – different log file for each thread
  3. Logback – MDC documentation

4 comments on “Logback – Set log file name programmatically

  1. trying to pass a variable like this
    app.${bySecond}.log

    <timestamp key=”bySecond” datePattern=”yyyy-MM-dd’T’HH:mm:ss.SSSZZ”/>

    Getting error

    at java.io.FileNotFoundException: logs\app.2020-08-20T14:52:43.911-0500.log (The filename, directory name, or volume label syntax is incorrect)

    Reply
  2. Hello,
    I am trying to implement your method but it’s now working for me, and I was wondering if that would be because I have log4j.properties instead of .xml? My code seems to replace the variable I created with an empty string.

    Here is the content of my file

    log4j.rootLogger=TRACE, STDOUT, file
    log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
    log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
    log4j.appender.STDOUT.layout.ConversionPattern=%c{1} – %m%n
    log4j.appender.STDOUT.Threshold=INFO
    log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.file.File=${basedir}/${log.file}.log
    log4j.appender.file.DatePattern=’-‘yyyy-MM-dd-HH’.log’
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%-5p %d{yyyy-MM-dd HH:mm:ss} %C:%L – %m%n

    Reply
  3. if it’s happened in the Servlet Container (tomcat, jboss), using log4j2 usually it need to reconfigure the logger using LoggerContext.
    What will happen if we’re doing that using Logback?

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *