[osgi logging] part 7 – configure your logging framework the dynamic way

This is part 7 of my blogseries about ‘Logging in OSGI Enterprise Applications‘ – you’ll find all parts here.

Using classic Logging Frameworks like Log4J or Apache Commons Logging in OSGI environments sometime causes pain where to place the configuration file or to understand why a specific configuration wasn’t used. In my blogs from 2008 I used Fragments to ‘attach’ the configuration files to Logback classic, which works in production – but while development log configurations must be flexible and easy-to-change while running an application. The good news: all this can be done.

Where to place and how to get the Configuration

How does Logback get the configuration ?

  • Logback can be configured programmatically – then all is under your control (how to get Logback early to start I wrote in Part 6)
  • Logback can be configured using a configuration file in XML format
    • At first Logback is looking for a logback-test.xml in the classpath
    • If none found, Logback checks for the file logback.xml in the classpath
    • If nothing found, Logback configures itself and logging goes to console.

How can the Location of Logback configuration file (xml) be specified ?

  • Put the Logback configuration file on the classpath (as I did before using a Fragment)
  • Specify a System Property:
-Dlogback.configurationFile=/path/to/config.xml

Which format can be used to specify the location:

  • URL
  • a Resource on Classpath
  • a Path to a File extern to your Application

What’s the recommended way in OSGI environments ?

My recommended way is using a System Property pointing to a File extern to the Application. In complex environments there can be more then one bundle containing a config file and to be sure that the right one is used, its the best to use a System property – this works well in RCP Products, OSGI Launch Configuration, Eclipse Application Launch Configurations tested in different scenarios. Some examples will be demonstrated at the end of this blog series.

Status Messages and dynamic Log Configurations

Logbacks Status Printer

Logback includes a StatusPrinter: please add debug=”true”:

<configuration debug="true">
...
</configuration>

debug = “true” causes Logback at Startup to dump the Status of the configuration file – very handy.

Logback scans Configuration (automagically re-configuration)

another very useful attribute is Scan=”true”

<configuration scan="true">
...
</configuration>

scan=”true” allows you to change the Configuration File while your application is running – so its very easy to add a Class with Debug Level while testing a running application. If scan=”true” Logback scans for changes (default: every 60 seconds) and if Logback founds changes, Logback reconfigures itself 🙂 I really like this feature.

You can even register a status listener to supervise logbacks internal state.

Logback Configuration Files

A configuration file can look like:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>myApp.log</file>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</Pattern>
        </layout>
    </appender>
    <appender name="STDOUT"
        class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%msg%n</Pattern>
        </layout>
    </appender>
    <root level="debug">
        <appender-ref ref="FILE" />
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

You have Appender, Layout, Level, Filter, TurboFilter – there should be nothing real new if you used Logging Frameworks like Log4J before. But its really worth to take a look at the detailed documentation because Logback provides much more then usual expected. Logback Configuration also supports:

  • variable substitution like ${user.home}
  • JNDI variables
  • include Files (so its easy to compose different config files)

…and of course the whole configuration can be done programmatically.

Logback is so flexible and powerful – in my workshops normaly I spent a half day to train people – in this blog I only can give you some hints – read the docs and see what you need to successfully logging in the enterprise.

JMX Configuration

There’s another cool way to modify or inspect Configuration files in a running system: JMX.

<configuration>
<jmxConfigurator />
...
</configuration>

simply add the attribute jmxConfigurator and use jconsole (part of JDK6) to inspect and change the configuration:

  • Reload logback from default configuration file
  • Reload from a specific URL or Path to a File
  • Set the Level of a specific Logger
  • Get the (effective) Level of a specific Logger

I tested Logbacks JMXConfiguration and jconsole under OSX and managed to change Configuration of a Eclipse RCP App, an Equinox OSGI Server – all works perfect.
(Read more in the docs, esp. if you like to use it in WebApps with Jetty or so, which isn’t part of my blog series)

Quickstarting JMX Configuration of Logback:

A) add jmxConfigurator to your config file (see example above)

B) Start your application (in this example I launched an Ecplise Application: Riena redView – RCP- App)

C) Look for the PID of your application

jmx found the pid osx

Our RCP Product runs under PID 395

D) Open the Java Console and start jconsole

jmx start jconsole

E) Select your remote Process and connect

jmx connect to your PID

F) Got to MBeans and select logback.classic

jmx mbeans logback classic

G) The LoggerList gives you a list of all Loggers known to Logback

jmx mbeans list of logers

H) Get the Logback internal Status

jmx mbeans status

I) Get the effective Level of a specific Logger

jmx get effective level

its up to you to play around, reload configurations, set level, load another configuration….

Summary

  • Use -Dlogback.configurationFile System Property to have full control which config file should be used
  • Monitor the status using “debug
  • Add dynamic and allow to “scan” and include “JMX

From my POV Logback fits very well into the world of OSGI Enterprise Applications.

you’ll find the overview of this blog series here. stay tuned… part8 follows…

2 responses

  1. Hi Ekke,

    great article, keep up the good work.

    In this particular post you mention the scan property of the logback XML configuration. I wonder if you’ve ever experienced any trouble with this feature when using the system property approach and changing the logging configuration during runtime? I set scan to true and scanPeriod to 10000 but most of the time it takes logback more than 10 seconds (or the defined period of time) to recognize changes in the configuration file. Even worse in case of a misconfiguration (e.g. not closing a ) from this moment on it doesn’t recognize any change (fix) until I refresh the logback bundle and stops logging completely.

    Unfortunately I need a reliable way of logging information inside an OSGi container (as it’s not only technical but also business related information I need to log) and I must be able to change the logging configuration in a dynamic way during runtime. Considering these requirements logback doesn’t look like a good pick to me.

    Frieder

  2. hi frieder,

    I’ll do some tests next weeks – I’m just upgrading to newest logback, building the bundles etc.

    ekke

Leave a comment