ProFast Computing

Software Development and Consulting Services

Specializing in Microsoft .NET and SQL Application Development

 

Message Logging Libary for .NET

Introduction

As part of my ongoing Windows and .NET programming efforts, I frequently find a requirement to provide some sort of logging or auditing functionality.

There are several scenarios where a log file is either required or simply very useful:

1.       Providing intermediate results or status messages for a long running code fragment.

2.       Providing results in a form that can be saved to an external text file.

3.       Saving messages that log both expected and unexpected events during the course of processing.

4.       Providing an audit trail for an application (when started, stopped, etc.).

The library supplants the use of Console.WriteLine, MessageBox and TextOut functionality found in Windows and .NET programming by providing finer grained control over how messages are built, formatted, displayed and saved.

The logging is packages into three sets of classes:

1.       MessageLog class provides a visual output window for your messages.

2.       TextLogFile class provides easy way to format messages written directly to a file.

3.       WindowsEventLog class encapsulates the logic needed to write to a Windows Event Log.

Visual Log Window for App Messages

MessageLog Code Library routines allow you to output messages from your application to a text window. You can search, format, print and save the messages directly from the output window. You can control whether the window is visible from your application.

<Sample Code>

public MessageLog _messageLog;
.....
       _messageLog = new MessageLog();
       _messageLog.Caption = "Application Message Log for TestprogMessageLogs";
       _messageLog.ShowDatetime = false;
       _messageLog.ShowWindow();
.....
.....
private long GetSum(long minNum, long maxNum, long outputEveryInterval, bool showDateTime)
{
       long sum = 0;

       try
       {
              _messageLog.Clear();
              _messageLog.ShowDatetime = showDateTime;
              _messageLog.WriteLine("Running GetSum routine ...");
              _messageLog.ShowWindow();
              for (long i = minNum; i <= maxNum; i++)
              {
                     sum += i;
                     if ((i % outputEveryInterval) == 0 || i == maxNum)
                     {
                           _msg.Length = 0;
                           _msg.Append("Sum calculated to " + i.ToString("#,##0"));
                           _msg.Append(" = ");
                           _msg.Append(sum.ToString("#,##0"));
                           _messageLog.WriteLine(_msg.ToString());
                     }
              }
       }
       catch (System.Exception ex)
       {
              _msg.Length = 0;
              _msg.Append(AppGlobals.AppMessages.FormatErrorMessage(ex));
              _messageLog.WriteLine(_msg.ToString());
       }
       finally
       {
              ;
       }

       return sum;
}
.....

 Message Log Output Window Example

Text File Logs

You can write formatted application messages to text log files. Output messages can be formatted to automatically include date/time, type of message (Error, Warning, Information, and Alert), name of the application sending the message and name of the computer from which the message was generated.

There is no visual UI for the text log classes. Your code writes directly to the external file.

<Sample Code>

.....
private long GetSumToOutputFile(string outputFilename, bool appendMessagesIfFileExists,
                           bool showMessageType, bool showApplicationName,
                           bool showMachineName,long minNum, long maxNum,
                            long outputEveryInterval, bool showDateTime)
{
       long sum = 0;
       TextLogFile logfile = null;

       try
       {
              logfile = new TextLogFile(outputFilename);
              logfile.ShowMessageType = showMessageType;
              if(showApplicationName)
              {
                     logfile.ApplicationName = "TestprogMessageLogs";
              }
              if(showMachineName)
              {
                     logfile.MachineName = Environment.MachineName;
              }
              if(File.Exists(outputFilename))
              {
                     if(appendMessagesIfFileExists == false)
                     {
                           logfile.TruncateFile();
                     }
              }

              logfile.ShowDatetime = showDateTime;
              for (long i = minNum; i <= maxNum; i++)
              {
                     sum += i;
                     if ((i % outputEveryInterval) == 0 || i == maxNum)
                     {
                           _msg.Length = 0;
                           _msg.Append("Sum calculated to " + i.ToString("#,##0"));
                           _msg.Append(" = ");
                           _msg.Append(sum.ToString("#,##0"));
                           logfile.WriteLine(_msg.ToString(), TextLogFile.LogMessageType.Information);
                     }
              }
              if (showMessageType)
              {
                     logfile.WriteLine("This is a test warning message.", TextLogFile.LogMessageType.Warning);
                     logfile.WriteLine("This is a test error message.", TextLogFile.LogMessageType.Error);
              }
       }
       catch (System.Exception ex)
       {
              _msg.Length = 0;
              _msg.Append(AppGlobals.AppMessages.FormatErrorMessage(ex));
              logfile.WriteLine(_msg.ToString(), TextLogFile.LogMessageType.Error);
       }
       finally
       {
              ;
       }

       return sum;
}

Example of Text File Log

Windows Event Logs

You can write formatted application messages to any of the Windows built-in Event Logs (Application, System, Security and Setup).

<Sample Code>

public MessageLog _messageLog;
.....
       _messageLog = new MessageLog();
       _messageLog.Caption = "Application Message Log for TestprogMessageLogs";
       _messageLog.ShowDatetime = false;
       _messageLog.ShowWindow();
.....
.....
public void OutputMessagesToWindowsApplicationEventLog(string eventSourceName,
                                                       int numInformationMessagesToWrite,
                                                       int numWarningMessagesToWrite,
                                                       int numErrorMessagesToWrite)
{
       WindowsEventLog eventLog = null;

       try
       {
              if (WindowsEventLog.SourceExists(eventSourceName) == false)
              {
                     WindowsEventLog.CreateEventSource(eventSourceName);
                     if (WindowsEventLog.SourceExists(eventSourceName))
                     {
                           _msg.Length = 0;
                           _msg.Append("Event Source ");
                           _msg.Append(eventSourceName);
                           _msg.Append(" create succeeded.");
                           WriteMessageToLog(_msg.ToString());
                     }
                     else
                     {
                           _msg.Length = 0;
                           _msg.Append("Event Source ");
                           _msg.Append(eventSourceName);
                           _msg.Append(" create failed.");
                           WriteMessageToLog(_msg.ToString());
                     }
              }
              else
              {
                     _msg.Length = 0;
                     _msg.Append("Event Source ");
                     _msg.Append(eventSourceName);
                     _msg.Append(" exists.");
                     WriteMessageToLog(_msg.ToString());
              }
             
              eventLog = new WindowsEventLog(WindowsEventLog.EventLogName.Application, ".", eventSourceName);

              for (int i = 1; i <= numInformationMessagesToWrite; i++)
              {
                     _msg.Length = 0;
                     _msg.Append("Message ");
                     _msg.Append(i.ToString());
                     _msg.Append(" from test program.");
                     eventLog.WriteEntry(_msg.ToString(), WindowsEventLog.WindowsEventLogEntryType.Information);
              }

              for (int i = 1; i <= numWarningMessagesToWrite; i++)
              {
                     _msg.Length = 0;
                     _msg.Append("Warning message ");
                     _msg.Append(i.ToString());
                     _msg.Append(" from test program.");
                     eventLog.WriteEntry(_msg.ToString(), WindowsEventLog.WindowsEventLogEntryType.Warning);
              }

              for (int i = 1; i <= numErrorMessagesToWrite; i++)
              {
                     _msg.Length = 0;
                     _msg.Append("Error message ");
                     _msg.Append(i.ToString());
                     _msg.Append(" from test program.");
                     eventLog.WriteEntry(_msg.ToString(), WindowsEventLog.WindowsEventLogEntryType.Error);
              }

              _msg.Length = 0;
              _msg.Append("Number of event log messages written = ");
              _msg.Append((numInformationMessagesToWrite + numWarningMessagesToWrite + numErrorMessagesToWrite).ToString("#,##0"));
              WriteMessageToLog(_msg.ToString());
       }
       catch (System.Exception ex)
       {
              _msg.Length = 0;
              _msg.Append(AppGlobals.AppMessages.FormatErrorMessage(ex));
              _msg.Append(Environment.NewLine);
              _msg.Append("Caller must have elevated security permissions (e.g. use Run As Administrator) to create and delete event sources and event logs.");
              WriteMessageToLog(_msg.ToString());
       }
       finally
       {
              ;
       }
               

}
.....
//calling module must set MessageLog property to a valid instance of the MessageLog class for messages to be displayed
public void WriteMessageToLog(string msg)
{
       if (_messageLog != null)
              _messageLog.WriteLine(msg);
}

Example Showing Messages Written to Application Event Log

Points of Interest

The MessageLog class allows you to easily build visual log output windows. This class is especially useful when testing program code but is also very useful for providing a shipping application with an easy to implement status/output window.

There are additional libraries included in the sample code. The additional libraries are used by the test program that demonstrates how to use the various library routines. These additional libraries are part of a general pfCodeLibrary project. Documentation and code samples for these helper classes can be found in the pfCodeLibrary project on CodePlex at https://pfcodelibrary.codeplex.com/.

Download Sample Code

Dowload pfMessageLogsProjectVS2010.zip

Download pfMessageLogsHelpFile.zip

Download pfMessageLogsSource.zip

Download pfMessageLogsBinaries.zip