How to configure Log4j (1 or 2) to use custom log file name while code against Slf4j

970 views Asked by At

I know there has been a lot of question related to this, but i couldn't find one that matches on the scenario that i'm looking at, so here's the question.

Current logging setup: logger coded using Slf4j with Log4j 1.2 bindings. DailyRollingAppender used.

The program: A multi-threading backend Java program processing data from a table and call relevant web services.

A new request came in to have the log file name be based on a certain data, lets call it match_code. With this, whenever a thread is processing say MatchA, then the log file the thread use should be set as MatchA.log

I'd googled for a while and understand that i will need to programmatically configure the Log4j configuration whenever the processes starts, the question is how should i change the log file name settings while not affecting others setting such as the Patterns.

I'm open to switch to Log4j 2.x if it means that can solve my problem, so far have no luck in finding samples for this.

Any suggestion is appreciated. Thank you.

UPDATE on what's tried

Tried using the System.setProperty way to dynamically set the log file. Here's the properties setting:

log4j.appender.file.File=/log/${logfile.name}.log

In main class, added these two lines before anything else:

    static{
        System.setProperty("logfile.name","output");
    }

    private static Logger logger = LoggerFactory.getLogger(Engine.class);

Added this right after the process found data to be process:

System.setProperty("logfile.name",match_code+"_output");

where match_code is a value from database such as 'MatchA'

The result is, the main class DID have the log named as output.log. However if i put in data to test, the log will still goes to output.log and there's no new log file created based on the data.

1

There are 1 answers

3
Adrian Shum On BEST ANSWER

Dunno if I understand your problem: you want your same log message goes to different log file, depending on the data you are processing?

if you use LogBack, you can do it by combination of MDC + SiftingAppender. For example, in your code, you can do:

(in code)

MDC.put("match_code", "MatchA");
logger.debug("whatever message");  // just log it normally

(in logback.xml)

  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
    <discriminator>
      <key>match_code</key>
      <defaultValue>unknown</defaultValue>
    </discriminator>
    <sift>
      <appender name="FILE-${match_code}" class="ch.qos.logback.core.FileAppender">
        <file>${match_code}.log</file>
        <layout class="ch.qos.logback.classic.PatternLayout">
          <pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
        </layout>
      </appender>
    </sift>
  </appender>

Please note, here I am using LogBack as logging backend. There is no official sifting appender for Log4j 1. I kind of remember something similar in Log4j 2. Wish this can serve as your starting point of searching if you really insist to use Log4j