5 Java logging frameworks for building automation software

Back in 2005, when I was writing Java software for an embedded home automation controller, we ran into a little unforeseen problem. The embedded virtual machine we were using implemented only the Java 1.3 API, and so did not offer any logging facilities (which only Java 1.4 started having).

We ended up using the logging implementation from the GNU Classpath project, but choosing a good logging framework in future projects will make a crucial difference for embedded applications that will run for months, if not years, unattended.

Here I recap the most popular Java logging frameworks of the day, and their relevance to the field of building automation.

Java Logging API
The default logging framework, a default implementation of which comes with the JRE. Expect this to be available on any platform that implements at least Java 1.4. A good, default choice for many applications, but very limited in its functionalities. Probably the best choice when memory and/or disk space is a critical issue.
Log4j
Arguably the most popular logging framework for Java, with equivalent implementations for many other languages. Extremely flexible and easy to configure. If your application runs on a “real” machine then you would be wise to choose this framework, or the more recent Logback (see below). If you run on an embedded platform, the choice will be more difficult and require careful thought. You can also use Chainsaw, a graphical tool for parsing Log4j logfiles if they are formatted in XML, which should probably never be done on an embedded system. The development of Log4j seems, however, to be stuck on version 1.2.
Logback
Intended as the successor of Log4j, and written by the same author. I don’t have much experience with it but it’s probably a smart move to get to know it.
Jakarta Commons Logging
Not a logging framework per se, but a logging framework wrapper. Certain kinds of applications, such as libraries, should avoid any tight coupling with any particular logging framework and instead use a framework wrapper such as JCL. There will, however, be a (small) memory penalty, which should be evaluated if the application runs on an embedded platform.
SLF4J
The author of Logback and Log4j wrote also the Simple Logging Facade for Java, another logging framework wrapper that solves several issues and problems with JCL. I cannot see how a building automation application could be concerned with these kinds of classloading problems, but I like the idea of statically binding the wrapper with the logging framework, something which JCL did not do. Also, it sort of lazily evaluates the log strings, so you avoid the little performance hit when debugging is turned off (an important factor for embedded systems). You should probably prefer this wrapper over JCL, especially if Logback takes off and eventually replaces Log4j.

Spring for structure, property files for parameters

Spring is a great framework for externalizing the object graph of your application. Typically you write an XML config file that defines a number of Java objects (or “beans“) and how they are supposed to relate to each others.

For example, suppose you have a class ThermalNode whose instances need to hold a reference to, say, an instance of a TimeProvider class. The way you usually do this in vanilla Java is you define this relationship somewhere close to the program’s start:

ThermalNode node = new ThermalNode();
node.setTimeProvider(new TimeProvider());

But in Spring you define this structure outside of your main program, and the above would be written somewhat like this:

<bean class="ThermalNode">
  <property name="timeProvider" ref="timeProvider"/>
</bean>
<bean id="timeProvider" class="TimeProvider"/>

And thus the structure of your object graph has been moved away from your compiled code.

Where this got really interesting for me was when I started introducing parameters for the thermal nodes, e.g. thermal capacicities. I would have for instance this sort of structure:

+---------------+
|  ThermalNode  |
|---------------|
|  capacity1    |
+---------------+
       |
       \
       /
       \ conductance
       /
       \
       |
+---------------+
|  ThermalNode  |
|---------------|
|  capacity2    |
+---------------+

What you then start having are beans whose properties (or constructor arguments, which is the way I prefer doing it) are not only references to other beans but also values.

Now a requirement for this project of mine is that it should be easily customizable by the end user. And that means not having the poor user coming and manually edit Spring config files.

Instead, Spring lets you define properties in plain property files, e.g.

# A property file
capacity1=300
capacity2=250

Then these properties are available to your main Spring config file through this kind of incantation:

<context:property-placeholder
    location="classpath:my.properties"/>

And your beans can then refer to these properties like this:

<bean class="ThermalNode">
  <contructor-arg ref="timeProvider"/>
  <constructor-arg value="${capacity1}"/>
</bean>

I have found this way particularly useful, namely put the structural data in the Spring config file, and put the parameter data in its properties file. Doing so not only makes it easy for the user to run the program with different parameters. It also lets you stash away the Spring config file in your application’s jarfile, putting it out of the way of the user. And that, I believe, is a very good thing, because you typically do not want to confuse the user with Spring’s syntax.

Reblog this post [with Zemanta]