Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

log4j: output file depending on source calling class

Tags:

java

log4j

suppose I have a common class with logger initialized by its name:

public class SomeCalculationLogic {
private static final Log log = LogFactory.getLog(SomeCalculationLogic .class);

public void doCalculation() {
    log.info("doing calculations...");
    ...
    }
}

This class is used by two logically different flows - say it is called from classes "BackgroundTask" and "UserRequest". How to make output of SomeCalculationLogic's logger redirected to different log files (like background.log and main.log) depending on what calling class is?

like image 691
Anton Polyakov Avatar asked Oct 14 '22 03:10

Anton Polyakov


1 Answers

I see three possible ways:

  • if it is enough to log all messages into the same file but prefix them differently depending on context, so that they become easily filterable, you could use a nested diagnostic context, as described in a previous answer of mine,
  • if you absolutely need to have separate log files, you could subclass your class with two different loggers and associated appenders, as Xavier suggested (just his solutions is unfortunately not working as it is),
  • or try this alternative solution.

A working implementation of a subclassing solution would be something like this:

public class SomeCalculationLogic {
  protected abstract Log getLog();

  public void doCalculation() {
    getLog().info("doing calculations...");
    ...
  }
}

public class BackgroundCalculationLogic extends SomeCalculationLogic {
  private static Log log = LogFactory.getLog(BackgroundCalculationLogic.class);

  protected Log getLog() {
    return log;
  }
}

public class UserRequestCalculationLogic extends SomeCalculationLogic {
  private static Log log = LogFactory.getLog(UserRequestCalculationLogic.class);

  protected Log getLog() {
    return log;
  }
}
like image 51
Péter Török Avatar answered Oct 20 '22 16:10

Péter Török