Wednesday, November 26, 2008

Configure Logback from your Web Application at Runtime

As mentioned in one of my earlier blog posts, I migrated my OSS project from Apache Commons Logging and Log4j to Simple Logging Facade for Java and Logback. One piece however that was left open was my web logging component. It gives you access to your log files from within the administrative area of your web application. Not only can you download the current logfile, but you can also change the log levels at runtime. Just in case some of your app's users hit an issue and you can't SSH into the server that very moment but have web access - at least you can gain an overview of the situation quickly.

Here is a screen-shot of my application's logging component:



The tables are rendered using the JMesa data grid, which works very nicely. The tables are paginated and the columns are sortable as well as filterable. Furthermore, the table is refreshed via AJAX using the jQuery JavaScript library.

On this page you can:
  • View your log files
  • Download the logfile as text file
  • View the configured loggers
  • View all available logger
  • Set logging levels for any of the available loggers
The backend is implemented using Struts 2 but you should be just as simply be able to switch the code over to Spring MVC 2.5+. There was however a minor hiccup with posting collection data back to the server using JMesa. Only the latest trunk version (As of Nov 26, 2008) allows for getting the row count for each row, which is used to map the collection data back on the server.

Although I originally used Log4j to retrieve the required logging data, the conversion over to Logback has been fairly straightforward. Here is one of the methods that interacts with logback and returns a collection of loggers:
 public static List  <ch.qos.logback.classic.logger> getLoggers(boolean showAll) {

final LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
final List loggers = CollectionUtils.getArrayList();

for (ch.qos.logback.classic.Logger log : lc.getLoggerList()) {
if(showAll == false) {
if(log.getLevel() != null || LoggingUtil.hasAppenders(log)) {
loggers.add(log);
}
} else {
loggers.add(log);
}
}

return loggers;
}
Anyway if you look for something similar for your own application, you can download all the relevant source code here. Please be aware that the archive is not a full demo application but rather a couple of source files cobbled together. If you rather like to see an entire buildable demo application, just let me know.

3 comments:

Adam said...

Thanks for this! I used to do the exact same thing with log4j, but was having trouble figuring it out for SLF4J/logback. Very helpful.

Gunnar Hillert said...

Thanks for the feedback!

Anonymous said...

Thanks for the example. I wrote my own version from the ground up using Spring MVC but borrowed the idea from you.