2

I am using Log4j in a project that redirects it's logs to multiple different files depending on the package the calling class resides in. However, my project has some util classes which are used throughout the project and I would like their logs to be appended to the appropriate log depending on the calling class. In case of errors I can throw exceptions but in case of warnings this is not a good idea. Is there a way to do "redirect" the util classes' logs depending on the calling class?

Samantha Catania
  • 5,116
  • 5
  • 39
  • 69

3 Answers3

0

You can use the stacktrace to get the caller (see How do I find the caller of a method using stacktrace or reflection?) but it will probably impair the performances of your application.

Another option would be to use thread local storage to set the currently used logger - but again that is a bit of overkill in my opinion.

I don't know of any "standard" way of doing this...

Community
  • 1
  • 1
GdR
  • 313
  • 1
  • 8
0

I would like to suggest you couple of solution:

  1. first is to to log all messages into the same file but prefix them differently depending on context so it can be filtered easily.One way to filter is using org.apache.log4j.NDC.

  2. Second is try something like this. It has a simplest solution to log output of a specific class to a specific appender :-)

Community
  • 1
  • 1
Viraj Nalawade
  • 3,137
  • 3
  • 28
  • 44
0

If your project isn't big and refactoring won't be a big problem I would get rid of the static methods. That way, you can use injection to pass the Logger to the utility class wherever you need it:

public class MyUtils {
  private final Logger logger;

  public MyUtils (Logger logger) {
     this.logger = logger;
  }

  public void doSomething(...) {
     // use the logger
  }
}

Then you would instantiate the utility class in top-most parent class(es) and use the same utility class in child classes; something like

public abstract class BaseClass {

   // You can use log4j to log in different files; 
   // e.g. you would probably want all child classes of BaseClass to use the same log
   private static final Logger LOGGER = Logger.getLogger("some_log");

   // Doesn't have to be static, but one instance would be enough in this case
   private static final MyUtils UTILS = new MyUtils(LOGGER);

}

Then in a child class you would use the utility class like this:

getUtils().doSomething();
Egemen
  • 2,178
  • 5
  • 22
  • 32