EQUIP2 code logging

Chris Greenhalgh, 2006-05-09

Introduction

This is about logging e.g. errors from the code, rather than logging dataspace events. Plan A is to use Apache Log4j, currently stable version 1.2.13.

Coding Guidelines

Download log4j, e.g. http://logging.apache.org/site/binindex.cgi
Log4j logging levels:
Typical usage:
package my;
import org.apache.log4j.Logger;
...
class Foo {
static Logger logger = Logger.get("my.Foo"); // name = classname; note Foo.class.getName() doesn't work on CLDC1.0
...
logger.debug("...");
//or
if(l.isDebugEnabled()) {
logger.debug("...slow message generation...");
}
//or
try { ... }
catch (Exception exception) {
logger.error("...",exception);
}
...
}

Note that, although appenders can be configured to retrieve (in some cases) filename and linenumber, this is reported to be very slow. Consequently, method names if useful should be included explicitly in the log message (the class name will be implied by the Logger name, assuming the class's own logger is used).

For multi-threaded contexts, log4j uses NDC (Nested Diagnostic Context) and/or MDC (Mapped Diagnostic Context) to identify current thread/context (NDC & MDC are managed per thread), although I haven't yet decided which/how much I want to support cross-platform, so avoid these unless absolutely required for now. e.g. use:

import org.apache.log4j.NDC;
import org.apache.log4j.MDC;
public class Bar implements Runnable {
public void run() {
NDC.push("Bar thread "+Thread.currentThread()); // ?!
...
// subthread...
final Stack s = NDC.cloneStack();
new Thread() {
public void run() {
NDC.inherit(s);
...
NDC.remove();
}
}.start();
...
NDC.pop();
NDC.remove();
}
//or
public void somecontext() {
// note - inherits a copy of the calling thread's MDC
MDC.put("key", value);
...
MDC.remote("key");
}
}

Configuration


Change log

2006-05-09