A bug reporting framework is a framework for reporting bugs (of course). Typical systems start with a bug reporting framework which you invoke by calling System.out.println() and Throwable.printStackTrace(). That works for very small programs, but sooner or later, as the project grows, a better system is needed. I cannot believe there is no standard for this yet! Everyone would use it!
The requirements for the bug reporting framework in order of importance are:
We have a pluggable logging system for our framework. It seemed merely cool when we invented, but I am more impressed as I use it. The user interface to it has essentially two methods, Logging.log(...) and Logging.trace(...). Calls to trace() are translated to calls to log() anyway. One of the parameters to log() is a message category. Our present categories are warning, abort, failure, error, unknown, informational and I am lobbying to have bug added. The logging code throws an exception at itself to get a stack trace, and hence finds out what package you are in. Messages can then be grouped by category and package. Things like timestamps are added. Another parameter to log is an array of objects which is useful information for sorting out what the problem is. As another parameter is a resource key for the log string, Java can substitute those objects into the string to create a log message. However I tend to put all sorts of gunk into the array to debug with.
Anyway, the cool bit is the pluggability. The logging system sends the log event to all registered loggers, which then distribute it as they see fit. The PrintStreamLogger? writes the log message to System.err. The FileLogger? writes it to a file. The PubsubLogger? publishes it on our publish and subscribe system. We could write a logger to email events with the bug category back to the developers.
To some extent, this system supports RichBugReports. It's definitely scalable - a single class can use a PrintStreamLogger?, and an enterprise system can use a PubsubLogger?. It's easy to use, but not as easy as I would like (I have plans for enhancements but no time allocated to do them.) It can't yet be linked to a testing framework, but I imagine we could write a JUnitLogger in which logged bugs were reported to JUnit as failures. It doesn't have a GUI interface yet, because I can't get that code to work :-(.
I'd love to make the logging code freely available, but my company is yet to be convinced of the wisdom of that. If I ever get time to scratch myself again, I might write a better one myself. It's only a thousand lines of code or so
-- JohnFarrell
I wrote a much simpler class called Debug which is available under LGPL from [1]. It's monolithic; although it can redirect output to console, file or a window it doesn't use subclasses for the destination. About 300 lines.
It optionally tags each message with a thread ID and a time stamp. I sometimes find that info useful for figuring out what is happening. It has a debug "level" which you can use to switch off or otherwise control the detail of reporting. It has some utilities to help print objects (for example, excluding package names (which for me always begin "CO.uk.bhresearch.pan") or hash codes).
It can throw and parse exceptions to figure out where it was called from. This is wrapped up into one of my favourite debugging aids, Debug.here(), which just prints "Here:" followed by the source filename and line number. In CeePlusPlus I use:
#define HERE Trace( "Here: %s %d", __FILE__, __LINE__ );for the same effect. The idea is to splat dozens of calls all over suspect code by using cut&paste, to see which route the program took and how far it got.
I should mention I've been doing Java servlet work, and I've never figured out how to attach a debugger to a servlet. -- DaveHarris
See http://www.iac.net/~crawford/programming/testharness.zip ; it's an adapter between JavaUnit and the Servlet interface. It should also let you connect a debugger. -- RobCrawford
I wrote a Log class for my Java frameworks that uses a Java system property to determine where to send its logging output. If the relevant property is not defined it is silent - logs are discarded. If the property is defined but has no value, log messages are sent to System.err. If the property has a value, it is treated as a filename and log messages are appended to the file.
For more flexibility, one could use ParameterClasses to load a "back-end" that defines how log messages are displayed and stored. This would allow new logging systems to be added, even after the system has been deployed!
-- NatPryce
The paper "An Input and Output Pattern Language: Lessons from Telecommunications" by Robert Hamner and Greg Stymfal, from the PatternLanguagesOfProgramDesign 4 book, describes a messaging system that is similar to Log classes. But the purpose is different, so perhaps it is not as similar as it looks to me.