log4j – Grey Panthers Savannah https://grey-panther.net Just another WordPress site Thu, 03 Feb 2011 16:07:00 +0000 en-US hourly 1 https://wordpress.org/?v=6.7.1 206299117 Augmenting Log4J stack traces with class versions https://grey-panther.net/2011/02/augmenting-log4j-stack-traces-with-class-versions.html https://grey-panther.net/2011/02/augmenting-log4j-stack-traces-with-class-versions.html#comments Thu, 03 Feb 2011 16:07:00 +0000 https://grey-panther.net/?p=84 If you have multiple versions of your code in production, it is extremely useful for the log to include the version of the classes when producing a stacktrace, otherwise it is very hard to match the lines in the stacktrace with the lines of the source code (sidenote: there is an optimization in the Sun JVM where – if an exception is thrown “too much” – the JVM stops providing stacktrace – see this article about it and to learn how to disable this feature).

If you are using Log4J as your logging framework, with a little magic you can turn the following stacktrace:

17:47:40,208 ERROR [main] [TestLog4jExtendedStacktrace] An exception has occurred!
java.lang.IllegalArgumentException: Test exception
 at ...Callee.called(TestLog4jExtendedStacktrace.java:144)
 at ...Caller.call(TestLog4jExtendedStacktrace.java:136)
 ...

Into this (note the class versions at the bottom):

java.lang.IllegalArgumentException: Test exception
 at ...Callee.called(TestLog4jExtendedStacktrace.java:144)
 at ...Caller.call(TestLog4jExtendedStacktrace.java:136)
 ...

Callee: $Revision: 56 $
Caller: $Revision: 56 $

The main mechanism is as follows:

  • Each class contains a static String field called “VCS_VERSION”. This field is set (trough the magic keyword substitution – see the documentation for SVN, CVS) to the last version when the file was committed to your VCS.
  • When a stacktrace is sent to the logger, it will look at the classes and if they have the “VCS_VERSION” field, it will output it at the end (it doesn’t annotate the stacktrace itself, because some tools – like IDEs – depend on the stacktrace having a certain format for them to be able to process it – like adding one-click “go-to-line” shortcuts)

As usual, the source can be found in the repository.

Some more implementation details: the current way of modifying the stacktrace is quite hackish (adding a filter and trough reflection modifying the passed in LoggingEvent object). However it has the advantage of being usable without modifying your config files (ie. if you have many config files, but can modify it in only one place in the code, this is a good solution. More “proper” alternatives would be to implement a “wrapper” appender (like AsyncAppender) or a wrapper around Layout, however both of these require you to modify your configuration files.

]]>
https://grey-panther.net/2011/02/augmenting-log4j-stack-traces-with-class-versions.html/feed 1 84
Why can’t I see the stacktrace under Java? https://grey-panther.net/2009/07/why-cant-i-see-the-stacktrace-under-java.html https://grey-panther.net/2009/07/why-cant-i-see-the-stacktrace-under-java.html#respond Fri, 24 Jul 2009 14:56:00 +0000 https://grey-panther.net/?p=255 3089163372_f5e0e4afc8_b I recently had a situation where Log4j wasn’t outputting the stacktrace of the logged exceptions. While I’m not sure that the following is the actual explanation, it seems very plausible (since the program was running Java 5). Quote from the Java 5 release notes:

The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow

(Credit goes to Stackoverflow.com for pointing me in the right direction). Small rant here: I do realize that all the guys and gals working on the Hotspot VM are exceptionally smart and there is some incredibly wicked cool technology in it (just one example: the code is instrumented using the performance counters from the CPU – so there is virtually no performance impact – and if it observed that too many jumps are taken, the code is re-JIT-ed using the opposite jump direction. If you are interested in the topic, just take a listen to episode #174 of the JavaPosse). Still, don’t mess with our exceptions! They are called such, because they are exceptional. If some programmer is using throwing exceptions as a control structure at every second statement, it is his or her problem! But for the rest of us, please don’t optimize away our stacktraces, since debugging complex multi-threaded applications is hard-enough even when you know where exactly the exception occurred!

Picture taken from Wonderlane’s photostream with permission/

]]>
https://grey-panther.net/2009/07/why-cant-i-see-the-stacktrace-under-java.html/feed 0 255