Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

slf4j without toString()

Tags:

slf4j

When you do something like LOG.debug("Exported {}.", product) in slf4j it will eventually call toString() on the arguments, e.g. product.

For certain reasons, I can't override toString() on all the classes I want to use as arguments. Some classes come from third party jars, others will have their toString() called in other contexts, too, where the information I want to print in my log statement isn't available.

However, I have a class for debugging purposes which has a method DebugFormatter.format(Object) that has a long cascade of instanceofs that selects the routine to find some useful debugging information about that object.

My question is: Is it possible to configure slf4j so that it calls such a static method instead of toString()?

Of course, I could call my format method on the object before passing it as a parameter to Logger.debug() but then it would be executed even when the respective logger is not enabled. So I had to surround it with if (LOG.isDebugEnabled()) which means that the whole point of having arguments in debug() was missed.

like image 779
Wolfgang Avatar asked Jul 02 '12 14:07

Wolfgang


People also ask

Does SLF4J call toString?

debug("Exported {}.", product) in slf4j it will eventually call toString() on the arguments, e.g. product .

Is toString required?

There is no set requirement for what a toString() method should do.

Can we override toString method?

We can override the toString() method in our class to print proper output. For example, in the following code toString() is overridden to print the “Real + i Imag” form.


1 Answers

You could create a shim, taking your object and calling DebugFormatter.format() from its toString() function. Something like this:

class DebugFormatObject {
  private final Object o;

  public static DebugFormatObject forDebug(Object o) {
    return new DebugFormatObject(o);
  }

  private DebugFormatObject(Object o) {
    this.o = o;
  }

  @Override
  public String toString() {
    return DebugFormatter.format(o);
  }
}

With the appropriate static import, your logging statement becomes this:

LOG.debug("Exported {}.", forDebug(product));

This does have slightly more overhead than passing the object in straight, but it's a small, constant overhead -- and the object created will be very short-lived.

like image 100
Andrew Aylett Avatar answered Oct 05 '22 11:10

Andrew Aylett