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;
}
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