Skip to main content

Gooey Logger

Posted by evanx on November 20, 2006 at 6:09 AM PST

href="http://aptframework.dev.java.net/gooey/logger.html">
align="left" hspace="8"/>

href='http://aptframework.dev.java.net/gooey/logger.html'>






Spoiler Warning! The following pitch is a spoiler for the actual um, article...


Stairwell Pitch

Logging is a fundamental tool of software development. But using System.out.println() is
for monitoring is um, not very convenient. So we rather implement a logger which
can accept variable arguments, infer the class and method by default, and format
our objects nicely for us.


Demos

You can see this type of logger in service in the CookieJar, its Address Form demo, and other true stories.

href='http://aptframework.dev.java.net/jnlp/cookiejar.jnlp'>






Implementation

I like the Java Logging API. So we implement a logger in the spirit of java.util.logging.Logger.

public class QLogger {
    protected static QLoggerProperties properties = new QLoggerProperties();
    protected static QLoggerFormatter formatter = new QLoggerFormatter();
    ...
    protected String loggerName;
    protected Level level;

    protected Logger delegateFileLogger;

    public QLogger(String loggerName) {
        this.loggerName = loggerName;
        String levelKey = loggerName + ".level";
        String levelValue = System.getProperty(levelKey, "INFO");
        setLevel(Level.parse(levelValue));
        ...
    }

    public void entering(Object ... args) {
        logp(Level.FINER, "entering:" + formatter.formatArgs(args));
    }
    ...
}

We get the desired verbosity level for this logger from the command-line
system properties, eg. -Dlogger.level=FINEST.

We implement the following method to log if the message has a sufficient level.

    public void logp(Level level, String string) {
        if (!isLoggable(level)) return;
        StackTraceElement frame = getStackFrame();
        String className = getSimpleClassName(frame.getClassName());
        QLogRecord record = new QLogRecord(level, string);
        record.setSourceClassName(className);
        record.setSourceMethodName(frame.getMethodName());
        record.setLoggerName(loggerName);
        record.setLineNumber(frame.getLineNumber());
        if (delegateFileLogger != null) delegateFileLogger.log(record);
        log(record);
    }

where by default we get the stack frame, if it's loggable, and pay the performance price.
Hopefully we can afford it.





Related Topics >>