Logging and Debugging using the Event Viewer and DebugView

From Dolphin Map

Jump to: navigation, search

This tutorial explains how to use Dolphin Smalltalk to create Events shown in the Windows Event Viewer. In additon Dolphin's capability of using generic Windows Debug APIs is shown.

Contents

Windows Event Viewer

Dolphin Smalltalk Events in EventViewer
Enlarge
Dolphin Smalltalk Events in EventViewer

The Windows Event Viewer knows four types of events:

  • General (Success)
  • Information
  • Warning
  • Error

Dolphin Smalltalk allows you to generate such events from your application. SessionManager implements four methods to achieve this:

  • SessionManager>>logSuccessEvent:
  • SessionMananer>>logInformationEvent:
  • SessionManager>>logWarningEvent:
  • SessionManager>>logErrorEvent:

Using these four methods your application is able to create Event entries. For example:

 SessionManager current logErrorEvent: 'An Error'.
 SessionManager current logInformationEvent: 'Information'.
 SessionManager current logSuccessEvent: 'Success'.
 SessionManager current logWarningEvent: 'Warning'.

Windows Debug Output

Windows offers various APIs for applications to generate debug output. One of these functions is OutputDebugString.

DebugTraceStream and Trace

Dolphin Smalltalk provides a nice wrapper around this function in class DebugTraceStream. As the name suggests the interface use to create debug messages is that of a Stream. So you can use most of the Stream methods for DebugTraceStream as well. The sole instance of DebugTraceStream is Trace. There is no need to instantiate another DebugTraceStream

DebugView

Dolphin Smalltalk Debug Output in DebugViewer
Enlarge
Dolphin Smalltalk Debug Output in DebugViewer

Although there are many ways of viewing Debug Output my preferred way to do so is DebugView from sysinternals.com.

DebugView shows Debug Output from various sources (applications, kernelrneven remote machines) and provides powerful featues like filtering and highlighting to not get lost in Debug Date.

Dolphin Integration

Generating Debug output is simple. Just use stream methods on Trace. For example:

Trace nextPutAll: 'Simple Debug Output';flush.

Please note that a message will not be sent until you send #flush or #cr (#cr is sending #flush behind the scenes).

Making it nice

You may notice that - unlike the event viewer - Debug Output does not contain application names (PIDs are possible though). You have to provide them on your own. For example:

Trace nextPutAll: SessionManager current applicationName;
  nextPut: $:;
  space;
  nextPutAll: 'Verbose Debug Output';
  flush

Encapsulate

If we use this once this maybe allright. If we use the same code over and over again we are "violating" Kent Beck's Once and Only Once Law.

So we have to encapsulate the code above. I'm using a method #verboseLog: in DebugTraceStream to do so:

DebugTraceStream>>verboseLog: aString
  self nextPutAll: SessionManager current applicationName;
    nextPut: $:;
    space;
    nextPutAll: aString;
    flush

This allows you to simply use Trace>>verboseLog: within your code:

Trace verboseLog: 'Encapsulated verbose Debug Output'.

Conditional Debugging

The "C"-way of defining something like "#define TRACE(x)" to output the debug string in a debug build and to do nothing in other builds is not possible in Smalltalk.

Smalltalk does not offer something like "conditional" compiling of a method. This means there will always be a reference to Trace in the method.

However you can replace Tracewith a different object: You could implement something like NullTraceStream which has the same methods as DebugTraceStream(at least the methods you are using in your app) ...but these methods do nothing (just return self).

Replace the Trace instance with your own (Trace := NullTraceStream new) and you're done. You could even do this conditionally during runtime/startup (e.g. only replace if no commandline parameter "-d" was found).

Personal tools