I have been working around multi threaded services for quite a while now. And as you may know, multi threading services are very hard to debug. When debugging multi threaded applications one must collect run-time information without disturbing the threads and introducing delays that would ultimately cripple the service or render the debug effort meaningless. Clearly, I needed to have the program send real-time messages.

I tried using the Windows event log as a target but found the Windows Event Viewer to be at least irritating to use. I then switched to using the Windows method OutputDebugString to send messages about the program’s state. I used Delphi’s Event Log facilities when possible to receive the messages. Otherwise, I used  Sysinternals’ Debugview to receiver the messages.

This was indeed a better solution but not perfect  as some of the systems that I inherited grew in complexity and services became distributed across multiple computers. I currently maintain a Windows service that has six threads that interact with as many as 132 devices over a network and stores collected data on a SQL database. This caused bugs to get trickier to resolve. I decided to change my debugging strategy to include an IP component.

I chose UDP/IP for the lower overhead and the “send it and forget it” operation – that meant that the debugged programs would not be affected by the debug message recipient not being on-line. I also chose the destination address to always be 127.0.0.1.  That way I could ship products with some debugging enabled without affecting the users’ network at all.

I know, this may not seem much different that using OutputDebugString. But the twist was that I created a “forwarder service” that forwarded all the UDP/IP messages to an external computer where an UDP/IP client was up and running.  That allowed me to control when debug traffic got outside the host and where it went.

The UDP/IP client is able to display messages received in real time as well as automatically store messages in text files that can be easily imported to Microsoft’s Excel or OpenOffice’s SpreadSheet where you can filter and sort messages to your heart’s content.

The UDP/Client is also able to receive messages from multiple sources and that give one the ability of seeing how different components interact and contribute to create an issue. This becomes an advantage in solving issues generated by concurrent programs running on a system.

My current solution has the following parts:

  • LibEventLog.pas – This unit contains the TMsgLogger object declaration as well as an initialization section that instantiates the Object. This object is responsible for sending the messages either through  OutputDebugString and/or UDP/IP. It also has the ability to redirect assertions. In order to use the the EventLog object all one has to do is to include this unit in the use clause of the units that need to send messages.
  • UDPFwrdr.exe – This is a Windows service that intercepts and forwards the UDP/IP messages.
  • UDPConfig.cpl –  This is a Control Panel applet that allows the Forwarder’s destination address to be changed.
  • UDPMonitor.exe – This is the UDP/IP client that receives messages generated by the application using LibEventLog and forwarded by UDPFwrdr. UDPMonitor receives, displays and saves all messages received.

LibEventLog is currently using Indy 10 and I tested it in Delphi 7, 2006 and 2007.

I have included the source code here so you can download it and use it. Please let me know what you think.

If you make any improvements I would ask you to submit those back to me.

5 Responses to My Event logger – a poor man’s debugger

  • Lex Y. Li says:

    This reminds me of how CodeSite evolves to what it is today. Nice tool.

  • Bruce McGee says:

    I’m a fan of open source (and/or free) software, but I won’t let any GPL code anywhere near anything that I might use in production. You might get more interest with a different license.

  • Fletch says:

    @Bruce,

    The GPLv3 license was left there from a previous project where I had parts of the LibEventLog used. If that really bothers you I can remove the license parts and republish it under a BSD or a Beerware license.

  • Bruce McGee says:

    Either one of those would be fine and will at least keep people from even trying the code.

    Again, I don’t dislike the GPL. It just isn’t suitable for most of the software I write.

  • Bruce McGee says:

    I didn’t phrase that well. I meant to write that using a different license may prevent at least scaring developers away from the code.

Leave a Reply

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

Login with Facebook