« NerdDinner | Main | SO principles of 2003 »
Thursday
23Apr2009

Simple logging for Integration Server

Integrations hosted within IS often need to write to log files. The typical approaches include using the pub.flow:debugLog service or incorporating a logging library such as log4j.

The debugLog service is simple to use but reading the log can be a chore as your logging entries are mixed in with entries from IS operations. Wading through entries you're not interested in can make it hard to find what you're looking for or to identify patterns of behavior.

Using log4j provides a very powerful and flexible facility. There is a range of appenders that can be used to create text logs, rolling logs (logs that roll to a new file after a certain size has been reached or after a particular time period has elapsed such as daily), logs written to a database and more. Mark Carlson provides an IS package with IS services to manage logging and write entries using log4j. It can be downloaded from the wMUsers Shareware pages.

Another option is available which uses facilities within IS. The sample package, ReLog.zip, can be downloaded via the link below. This may be a good option if you want to separate your logging from the IS server log but don't need the power and flexibility (and another library loaded) of log4j. The features of this package include:

  • Use different log files for different integration solutions/applications.
  • Automatic daily rolling of the log files.

It doesn't provide logging levels or writing to various appenders like sockets or databases, etc. Just a simple writing of entries to a text file.

Download ReLog.zip

The rest of the article reviews the compnents of this package.

Helper Services

The IS Java API provides a static method, ServerAPI.getLogStream(), that "opens a log file in the server's default logs directory." It returns a com.wm.app.b2b.server.LogOutputStream object. This object provides methods to log messages and its associated file is automatically rolled daily.

We need a way to manage the LogOutputStream object so that multiple logging calls use the same object. We also want to allow multiple LogOutputStream objects, one for each log file we want to manage.

A wrapper service, getLogStream, manages open log streams. It maintains a hashtable of open log streams keyed by the logfile name. If the log is opened for the first time a new stream is returned. If the log has been previously opened, the existing stream is returned.

Here is the source for getLogStream.

// IS Java service
// 
//
IDataCursor idc = pipeline.getCursor();
String logfile = IDataUtil.getString(idc, "logfile");

boolean newLog = false;
com.wm.app.b2b.server.LogOutputStream os = 
  (com.wm.app.b2b.server.LogOutputStream)openLogFiles.get(logfile);

if(os == null)
{
  os = com.wm.app.b2b.server.ServerAPI.getLogStream(logfile);
  openLogFiles.put(logfile, os);
  newLog = true;
}

IDataUtil.put(idc, "logStream", os);
IDataUtil.put(idc, "newLog", (newLog?"true":"false"));
idc.destroy();

// Source from the Shared tab
//
// Track open log files
private static final java.util.Hashtable openLogFiles = new java.util.Hashtable();

Now we need a service that can write to the log stream. Nothing sophisticated here. Given a log stream write the message to it. Here is the source for a writeLogStream service.

// IS Java service
// 
//
IDataCursor idc = pipeline.getCursor();
com.wm.app.b2b.server.LogOutputStream os = (com.wm.app.b2b.server.LogOutputStream)IDataUtil.get(idc, "logStream");
String message = IDataUtil.getString(idc, "message");
idc.destroy();

os.write(message);

You can place these helper services within your own utilities package and then use them from your various packages that need separate log files. With these two helper services in place, we can now create solution-specific log services that write to a particular log file.

Solution/app-specific Log Service

When writing to a log file we don't want to have the logfile name scattered all over the place. Nor do we want our functional services having to deal with a log stream object. A convenience service that manages these details will do the trick.

Let's assume we have an initiative called Anaconda. All integrations components are to log activity to an initiative-specific log file. We can create a service named logAnaconda to write entries to anaconda.log within the IS/logs directory. It accepts a single input named message.

Helper service to write a message to a log output stream.

Here is a test service (doStuff) that calls logAnaconda a few times.

Calling logAnaconda from a functional service.

And here is the log output from those calls (lines clipped to avoid wrapping).

2009-04-23 13:28:40 MDT ---( Start )---
2009-04-23 13:28:40 MDT The current date/time is: 2009.04.23 ...
2009-04-23 13:28:40 MDT Logging a server property: watt.serve...
2009-04-23 13:28:40 MDT 0.1353494799715752

With very little work you can get isolated, daily rolling log files for your integrations.

Download ReLog.zip

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>