Saturday, April 4, 2009

Got a bug? Who ya gonna call?

No one!

Seriously, this is the problem we face all the time when users run into a problem with our software. They don't call, they figure out an inefficient work around, they get frustrated, or stop using the software. It's counter intuitive but I've seen it over and over again. The reasons and excuses are endless but it all boils down to the fact that few problems are ever going to make it back to you.

Have you read Joel Spolsky's The Joel Test: 12 Steps to Better Code? You should. I like it enough to add a thirteenth step, log all error messages. Logging errors to a file that no one reads doesn't count. You need to track the errors so that you can be proactive in finding solutions.

We took Manoel Marques's Plugging in a logging framework for Eclipse plug-ins and extended it so all errors are logged in a database, emailed to our user support group and appropriate software developers. We've even gone as far as having wiki pages that shows the latest trends in real time.

This doesn't mean we're being constantly interrupted during our work day. But it does give us the flexibility to monitor users and jump in to solve either a usability, training, or software bug issue.

Eclipse is robust. I've been amazed at how well it handles nasty NullPointerExceptions without crashing. Don't get me wrong, it is a good thing but it can hide problems from the user. In alot of cases our users don't know they are in trouble until we burst into their office like Murray, Aykroyd, and Ramis looking to bust up a few ghosts.

We found it a great help to extend Marques's code to allow us to customize the logging properties. We allow log properties in the following order.

Load from the users home account
We can drop a custom logging properties file in the users account, restart our application and we can monitor whats happening in greater detail.
Load from command line
Customize logging from the run configuration dialog. Developers use this to avoid inundating the group with errors.
Load from bundle
This is what is shipped to our clients. Thanks to Eclipse plugin fragments each client gets to setup their own settings.
Load from default
In case the log properties file is broken, we have a default setup. Paranoid you say. Yep!

We have a set of standard logging tags. When you playback the log file, think airplane black boxes, it makes it easier to figure out what the user was doing leading up to their problem.

public interface ILoggingTag {
    public static final String DELIMITER = ":";
    public static final String SPACE = " ";
    public static final String CREATE = "CREATE";
    public static final String OPEN = "OPEN";
    public static final String CLOSE = "CLOSE";
    public static final String START = "START";
    public static final String STOP = "STOP";
    public static final String FINISH = "FINISH";
    public static final String DELETE = "DELETE";
    public static final String CANCEL = "CANCEL";
    //......
    public static final String PLUGIN_START = PLUGIN + DELIMITER + START + SPACE;
    public static final String PLUGIN_STOP = PLUGIN + DELIMITER + STOP + SPACE;
    public static final String RESOURCE_OPEN = RESOURCE + DELIMITER + OPEN + SPACE;
    public static final String RESOURCE_CLOSE = RESOURCE + DELIMITER + CLOSE + SPACE;
}

Our code looks like this.

    @Override
    public void init(IEditorSite site, IEditorInput input) {
        //...
        logger.info(ILoggingTag.EDITOR_CREATE + input.getName());
    }

    @Override
    public void dispose() {
        log.debug(ILoggingTag.RESOURCE_CLOSE + getEditorInput().getName());
        //...
    }

We log messages to the users log file, to a PostgreSQL database, and send emails. Having errors stored in a database allows use to generate wiki reports showing the latest trends in usage, bugs, etc.

The payback; obviously fewer bugs but what was really important was a more relaxed user community willing to help use improve the software. In many cases we're not tracking down software bugs but working to improve software usability. Users want to use our software, I have more time to spend writing new code, and tracking down bugs takes less time.