Creating and Reading Application Logs in .NET

Introduction

An error-free piece of code theoretically should exist, but, in reality, it’s almost impossible to test whether an application works under every situation. When errors occur, there are different ways to handle them. As a developer, it’s best practice to detect and catch errors and log them as well. For example, performance problems may occur only when your application is dealing with a large data load. To diagnose these errors in a production environment, you need to log errors automatically so they can be reviewed and analyzed at a later time to fix the issue. The .NET Framework provides a wide range of logging options; Windows System Event Log is one of those from your .NET application. As a developer, you can write code to log an error in the Event viewer and gather information about the software problems and monitor system events.

What to Log

Application logging code written by developers should be used to track information that is valuable for tracing warnings and errors that occurred in the system for a short period of time. For example, the event logs can be used to review errors and diagnose strange behavior immediately after it occurs.

Different Windows Event Logs

Typically, there are three different types of Windows logs:

  • Application Log: Applications running under Windows OS log their events in the Application Log.

    Application Log
    Figure 1: Application Log

  • Security Log: Windows logs security-related events in the Security Log.

    Security Log
    Figure 2: Security Log

  • System Log: The Operating System logs in the System Log.

    System Log
    Figure 3: System Log

There are five types of events those can be logged under each Windows log. The Event types are classified into following categories:

  • Information: This type indicates a successful operation of an application.
  • Warning: This type indicates that there could be a potential problem in the future. The entries help in taking preventive measures.
  • Error: This type indicates a significant problem. It lets us know if there was a failure in a critical task.
  • Success Audit: This type indicates that an audited security event is successfully completed.
  • Failure Audit: This type indicates that there was a failure of an audited security event.

Writing to an Event Log

In following example, I have shown how to create event logs. I have created a Windows Forms project using Visual Studio Editor and added the EventLogger.cs class in it. After that, I have added an interface, named iEventLogger, that contains method signatures for different types of event logs mentioned earlier. Finally, I have inherited that interface in the EventLogger class and implemented each interface method. By calling the EventLog.WriteEntry method of the System.Diagnostics namespace, event logs are created. Refer to the following source code of the EventLogger.cs class.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsLog
{
   interface iEventLogger
   {
      void DebugEntry(string text);
      void WarnEntry(string text);
      void ErrorEntry(string text);
      void AuditFailure(string text);
      void AuditSuccess(string text);
      void ErrorEntry(string text, Exception ex);
   }

   class EventLogger : iEventLogger
   {
      string app;
      public string AppName
      {
         get { return app; }
         set { app = "MySampleAppName"; }
      }
      /// <summary>
      /// Debugging
      /// </summary>
      /// <param name="text"></param>
      public void DebugEntry(string text)
      {
         EventLog.WriteEntry(AppName, text,
            EventLogEntryType.Information);
      }
      /// <summary>
      /// Warning
      /// </summary>
      /// <param name="text"></param>
      public void WarnEntry(string text)
      {
         EventLog.WriteEntry(AppName, text,
            EventLogEntryType.Warning);
      }
      /// <summary>
      /// Error
      /// </summary>
      /// <param name="text"></param>
      public void ErrorEntry(string text)
      {
         EventLog.WriteEntry(AppName, text,
            EventLogEntryType.Error);
      }
      /// <summary>
      /// Audit Failure
      /// </summary>
      /// <param name="text"></param>
      public void AuditFailure(string text)
      {
         EventLog.WriteEntry(AppName, text,
            EventLogEntryType.FailureAudit);
      }
      /// <summary>
      /// Audit Success
      /// </summary>
      /// <param name="text"></param>
      public void AuditSuccess(string text)
      {
         EventLog.WriteEntry(AppName, text,
            EventLogEntryType.SuccessAudit);
      }

      /// <summary>
      /// Error with Exception
      /// </summary>
      /// <param name="text"></param>
      /// <param name="ex"></param>
      public void ErrorEntry(string text, Exception ex)
      {
         EventLog.WriteEntry(AppName, text,
            EventLogEntryType.Error);

      }
   }
}

The preceding event log function is called from the Program.cs class. If you want to send a warning or error message to the System log, an event log first must be registered. In the CreateEventSource method, you can specify which log the source will belong to. In following example, I have mentioned ‘Application’. If control flow is passed to the catch() block, the corresponding error or warning will be logged to the application event log. Refer to the following Program.cs class code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;


namespace WindowsLog
{
   static class Program
   {
      private static readonly ILogger log = new EventLogger();
      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main()
      {
         try
            {
               Application.EnableVisualStyles();
               Application.SetCompatibleTextRendering
                  Default(false);
               Application.Run(new Form1());
            }

         catch (Exception ex)
         {
            string source = "MySampleAppName";
            EventLog systemEventLog = new EventLog("Application");
            if (!EventLog.SourceExists(source))
            {
               EventLog.CreateEventSource(source, "Application");
            }
            log.Error("Exception in Main() method.", ex);
         }

      }

   }
}

Reading from an Event Log

To read an event log, I have created the ReadEventLog.cs class. I have used the Entries properties of the EventLog class to read the event log created in the previous step. The Entries property of the EventLog class is a collection of all the entries in the event log. A developer can iterate through this collection, and read all the entries in the specified log. Following is the code of the ReadEventLog.cs class.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsLog
{
   public class ReadEventLog
   {
      string app;
      public string AppName
      {
         get { return app; }
         set { app = "Application"; }
      }
      public void ReadApplicationLog()
      {
         // logType can be an Application, Security, System, or
         // any other Custom Log.
         string applicationlog = AppName;
         string mymachine = ".";   // local machine
         EventLog myapplicationLog = new EventLog(applicationlog,
            mymachine);
         EventLogEntryCollection entries =
            myapplicationLog.Entries;
         int LogCount = entries.Count;
         if (LogCount <= 0)
         Console.WriteLine("No Event Logs in the Log :" +
           applicationlog);

         Console.WriteLine("Reading " + applicationlog + "Log");
         foreach (EventLogEntry entry in entries)
         {
            Console.WriteLine("################################");
            Console.WriteLine("Log Level: {0}", entry.EntryType);
            Console.WriteLine("Log Event id: {0}",
               entry.InstanceId);
            Console.WriteLine("Log Message: {0}", entry.Message);
            Console.WriteLine("Log Source: {0}", entry.Source);
            Console.WriteLine("Entry Date: {0}",
               entry.TimeGenerated);
            Console.WriteLine("################################");

         }
         Console.WriteLine("Finished Reading " + applicationlog +
            "Log");
      }

   }
}

Conclusion

Make sure you do not store unimportant information or large data in the event log. The default Windows event log maximum file size is 20MB; once the max limit reached, it will overwrite old events. This is the default behavior.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read