Logging: New Feature in the ProM Widgets Package

If you need more information about my Widgets package, I made an overview of (most of) the features in it here.

Today, I was working on something completely different, and decided that a general logging facility was a neat idea.  ProM already has some features for logging (logging to the PluginContext or by using System.out.println and Boot.VERBOSE), but I’d prefer something that doesn’t spam the console, something where I get logging just for my package, and something I don’t have to switch off all the time.  Furthermore, logging to a PluginContext only works during execution of a plug-in, not for logging access to objects that have already been created.

As programmers know, you have to implement your own vector class when dealing with graphics and your own logging when you outgrow System.out.println.  I decided to take another approach, as Java already has a decent logging infrastructure (tutorial and API).  I therefore added an interface for leveraging this:
[java] public interface Loggable {
Logger getLogger();
}
[/java] The Logger mentioned is the java.util.logging.Logger and can be instantiated using something like this (example from org.processmining.operationalsupport.embedder.OSProvider):
[java] log = Logger.getLogger(“OSProvider – ” + myName + ” @ ” + hashCode());
[/java] Now, we can log using all the normal logging methods of the Logger class. For simple logging, we just use:
[java] log.log(Level.FINE, “Setting ” + channelName(channel) + ” to ” + value);
[/java] Make use of the logging level as appropriate. If you are constructing complicated strings, make sure to compare to the level of the Logger using isLoggable for efficiency, e.g.:
[java] if (log.isLoggable(Level.FINE))
log.log(Level.FINE, “Setting ” + channelName(channel) + ” to ” + value);
[/java] and make sure to take a look at the heaps of useful helper methods of the Logger.

By doing this, you no longer have to switch on logging for all of ProM to see logging (using Boot.VERBOSE) nor do you have to comment out System.out.println lines (or completely remove them, making logging in the future much more cumbersome).

Instead, you just go to the Workspace in ProM and select to show your provided object:

This takes you directly to the log view for just your plug-in ((It’s actually even just for this one instance of your plug-in unless you explicitly share the Logging object.)):

The log shows your registered name at the top, allows you to select the levels to display in the log (using the combo box at the top) and to clear the log (using the button at the bottom).  The main log is shown in the center area, e.g.:

By changing the logging level, you ensure that only messages with a more important logging level are shown.  You can select among all the default logging levels in Java’s logging framework:

The level is applied to all subsequent messages; if you wish to remove old messages, just clear the entire log.  If you do not open the log view on your object, logging is never activated and impose virtually no overhead.  You can switch on logging for your plug-in at runtime, without recompiling your code simply by showing the Logging view.  Note that this also means that no logging will be performed until you open the logging view for your objects, but as soon as you have opened it once, it will be updated, even if you switch away from the view.

Two notices: You may have to select the Show Log visualization manually from the Create new dropdown:

Furthermore, you also need the exported and declared type of your object to implement the Loggable interface, i.e., this will work:
[java] MyLog implements XLog, Loggable {

}

@Plugin(name = “XYZ”, parameterLabels = {}, returnLabels = { “My Log” }, returnTypes = { MyLog.class })
public static MyLog plugin(final PluginContext context) {
return new MyLog();
}
[/java] but this will not:
[java] MyLog implements XLog, Loggable {

}

@Plugin(name = “XYZ”, parameterLabels = {}, returnLabels = { “My Log” }, returnTypes = { XLog.class })
public static XLog plugin(final PluginContext context) {
return new MyLog();
}
[/java] This is a limitation of ProM and is partially addressed in issue #218, which is unfixed at the time of writing.

I am thinking of extending this to make it possible to save logs and also to publish logs for running plug-ins (instead of just publishing to the PluginContext, which is not suitable for detailed tracing).  Let me know in the comments if this is useful for you, and also if you have other wishes to add to the list.

Edit: Just added ability to save logs, which makes the Clear button area look slightly different.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.