1

I'm trying to log the methods call chain of some classes instances of a Java program using Log4j2. Each instance will behave differently based on the inputs they will recive (obviously).

The problem I'm facing is differentiating the logging messages of each instances for easly reconstructing the methods call chains I was talking about. In addition to logging the entering and the leaving of each method, which is the default logging schema I'm using, I've tried to:

  1. add method call parameters to the log: too few informations and not very readable;
  2. add more informations about the method behaviour: too verbose and not very readable;
  3. adding instance hash code to all the logging messages, which will become something like LOG.trace("{} - Leaving constructor(index:{})", System.identityHashCode(this), index);: good solution, but I've to add some boilerplate code to all the logging methods, which makes the code a little less readable;
  4. using per-instance loggers (so not the per-class/static one) and adding the instance hash code in the logger name (so the logger name will be Classname@hashcode): seems the best solution in clean code terms, but I didn't found any way for declaring logger settings (like logging threshold) for multiple loggere, i.e. for all the loggers which name starts with Classname.

Which one do you think will be the best solution, or do you have any other way to suggest?

el.Quero
  • 25
  • 5
  • 1
    If you make it `Classname.hashcode` instead of `Classname@hashcode`, log4j will take it the same way as `package.class`, so you should be able to set the logging properties on `Classname` an let the instances inherit them. – Jiri Tousek Aug 16 '18 at 07:31
  • Although this is a workaround, it works like a charm! Thank you! Just to know: I'm using logger names like `ClassName.@hashCode`. – el.Quero Aug 16 '18 at 13:20

1 Answers1

1

For this requirement, you can easily use an nested thread context: Look at "Fish Tagging" in https://logging.apache.org/log4j/2.x/manual/thread-context.html .

Excerpt:

ThreadContext.push(UUID.randomUUID().toString()); // Add the fishtag;

logger.debug("Message 1");
.
.
.
logger.debug("Message 2");
.
.
ThreadContext.pop();
jokster
  • 577
  • 5
  • 14
  • Can you explain better your solution? I wasn't aware about this feature, so I've read the link you've provided but the `ThreadContext` information are chained to the running thread and not to the single object instances. Maybe I could add a `ThreadContext.push` before and a `ThreadContext.pop()` after the logging statements of each method, but it's not a big deal over the third solution explained in the question. – el.Quero Aug 16 '18 at 13:12
  • 1
    Usually, you would push at the start of the processing and pop afterwards. You could push the hashcode of the current instance on entry of the method and pop on exit. The ThreadContext contains all the pushed entries, since it's a stack. – jokster Aug 17 '18 at 06:55