Fork me on GitHub jcabi

24-Oct-2013 0.12

Logging Java method executions

Annotate your methods with @Loggable annotation and every time they are called your SLF4J logging facility will receive a message with the details of execution and total execution time:

public class Resource {
  @Loggable(Loggable.DEBUG)
  public String load(URL url) {
    return url.openConnection().getContent();
  }
}

Something like this will appear in the log:

[DEBUG] #load('http://www.google.com'): returned "<html ..." in 23ms

If a method throws an exception it is also logged.

Method toString() of your method arguments and its return value is used to compose a log line. Too long texts are trimmed to 100 characters, in order to make log lines compact. Since version 0.7.13 it's possible to disable this trimming mechanism with an extra trim argument of the annotation.

Since version 0.7.13 an entire class can be annotated. In this case all methods will be logged (except toString(), hashCode(), and equals(Object)):

public class Resource {
  @Loggable(Loggable.DEBUG)
  public class Foo {
    // all methods of the class will be logged
  }
}

If both a class and a method are annotated, method annotation has a higher priority.

Since version 0.7.6 you can specify a time limit in seconds, as a maximum execution time of a method. If this limit is reached a logging level is increased to WARN and method slowness is reported. Since version 0.7.14 you can change time unit as well:

public class Resource {
  @Loggable(limit = 200, unit = TimeUnit.MILLISECONDS)
  public void run() {
    // something that should not take more than 200 msec
  }
}

Since version 0.7.16 you can get log lines not only when method execution is done, but also when it is just started:

public class Resource {
  @Loggable(prepend = true)
  public void run() {
    // something that takes too long
  }
}

In this case two log lines will be recorded, one when the method is just started and another one when it returns the output.

Since version 0.7.18 you can ignore certain exception types. They won't be logged when thrown and won't polute the log. Sometimes exceptions don't mean fatal errors and should not be visible in logs, for example in JAX-RS applications where WebApplicationException is used to redirect a user to another page and is not an indicator of an application error:

@Path("/")
public class JaxRsResource {
  @GET
  @Loggable(ignore = WebApplicationException.class)
  public String get() {
    if (/* not a logged in user */) {
      throw new WebApplicationException(Response.seeOther(/* URI */));
    }
  }
}

Since version 0.7.19 it is possible to skip either arguments or result part of the log message, in order to make it more compact, using skipArgs and skipResult arguments of @Loggable annotation:

public class VerboseClass {
  @Loggable(skipResult = true)
  public List<String> get(String name) {
    // Returns a long list of texts, which are not
    // important and should not polute the log
  }
}

The mechanism is implemented with AOP/AspectJ. Read how to integrate it into your pom.xml.

Copyright © 2012-2013 jcabi.com, All Rights Reserved. Privacy Policy.

site is built by Apache Maven