Friday, October 13, 2006

Repated configuration with Joran

Developers have frequently express the need to output log files based on arbitrary runtime criteria such as by client, by task, etc.

Given all the flexibility offered by logback, writing such an appender should be easy. Let us call this new appender, MultiAppender. In principle, all MultiAppender needs to do is to create a new file as necessary according to the evaluation of incoming logging events. A configuration snippet might look like:
 <appender class="ch.qos.logback.core.MultiAppender">
<fileNameCalculator class="ch.qos.logback.core.Calculator">
<expression name="userid">mdc.get("userid")</expression>
Thanks to Joran, logback's powerful configuration API, we can deal with unknown configuration elements such as fileNameCalculator, expression and so forth. It's a slam dunk for logback, or is it?

Although Joran can deal with arbitrary configuration instructions, it can do so only once. Assume we changed the requirements, so that MultiAppender acted like a multiplexer of appenders. Thus, instead of writing to different files, it delegated to a fully-fledged appender, according to various criteria, then MultiFileAppender would need to configure a complete appender repeatedly.

We are in the process of refactoring Joran so that it can be invoked repeatedly on parts of a configuration file. To my knowledge Joran is the only configuration system offering this capability (but I might be wrong.)

In a completely unrelated project, the same need of repeatedly configuring components came up. In this other project, we need to configure a tester, an object performing one or more tests. We create a tester, configure it, invoke its test methods, collect the results, and when done, throw the tester away to start all over again a few minutes later. We leveraged the unique capabilities of Joran to provide this particular lifecycle. Joran, part of logback-core, is a generic configuration system that you can use in your own projects to great effect.

Do ping me if you need further info,


Anonymous said...

I'd be delighted to see Joran in action.
A short demo would be too much to ask ?

s t

Ceki said...

An in depth overview of Joran is in the works. You can fetch it somewhere from our project site.

Anonymous said...

Hi Ceki,

In your example, what is "mdc"? Where do you instantiate it?


Do you mind giving or showing a more complete example?

thanks a lot!

Ceki said...
This comment has been removed by the author.
Ceki said...

You can learn more about MDC at

Anonymous said...

Hi Ceki,

Could you help me what's wrong with my code?

My goal is to have the log filename set by the StartupServlet.

But what happens is the file is not created. Instead a file with name "%exp{logFileName}" is created on my web server's bin directory.

In my StartupServlet, I have this init method that calls MDC.put().

public void init() throws ServletException {
MDC.put("logFileName", "c:\\testlogs\\test.log");
Logger log = LoggerFactory.getLogger(StartupServlet.class);"This should be logged");

In my logback.xml, I have a MDC.get(). Please replace all [ ] with < >.

[appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"]
[expression name="logFileName"]MDC.get("logFileName")[/expression]

I'm new with logback, thanks in advance for your help!

Also I noticed that logback doesn't create the log file if directory doesn't exists, unlike log4j it does.


Ceki said...


Please post your question on the logback user list.