static void

ASP Errors To Text File With Health Monitoring

See health monitoring, also log4net and more

Web.config (health monitoring)

<healthMonitoring enabled="true">
        <add name="TextLogProvider" type="Martin.TextLogProvider" buffer="true" bufferMode="Logging" />
        <add name="All Errors To TextLog" eventName="All Errors" provider="TextLogProvider"/>

Error Logging class

Uses the following in a referenced assembly (must be in bin folder or GAC- cannot use App_Code). Original is MSDN, minor refactoring.

using System;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Text;
using System.Web.Management;
namespace Martin
    /// <summary>
    /// Implements a custom event provider.
    /// </summary>
    public class TextLogProvider : BufferedWebEventProvider
        // The local path of the file where to store event information.
        private string buffer, bufferMode;
        private StringBuilder customInfo = new StringBuilder();
        private string logFilePath = string.Empty;
        private string providerName;
        // Initializes the provider.
        public override void Initialize(string name, NameValueCollection config)
            base.Initialize(name, config);
            //this will use the web.config appsettings
            logFilePath = ConfigurationManager.AppSettings["TextLogFilePath"];
                logFilePath = @"c:\TextLogFile.log";
            customInfo = new StringBuilder();
            providerName = name;
            buffer = config.Get("buffer");
            bufferMode = config.Get("bufferMode");
                                      "Provider name: {0}", providerName));
                                      "Buffering: {0}", buffer));
                                      "Buffering modality: {0}", bufferMode));
        // Processes the incoming events.
        // This method performs custom processing and, if
        // buffering is enabled, it calls the base.ProcessEvent
        // to buffer the event information.
        public override void ProcessEvent(WebBaseEvent eventRaised)
            if (UseBuffering)
                // Buffering enabled, call the base event to buffer event information.
                // Buffering disabled, store event info immediately.
                                          "{0}", eventRaised.Message));
                // Store the information in the specified file.
                StoreToFile(customInfo, logFilePath, FileMode.Append);
        // Processes the messages that have been buffered.
        // It is called by the ASP.NET when the flushing of
        // the buffer is required according to the parameters
        // defined in the <bufferModes> element of the
        // <healthMonitoring> configuration section.
        public override void ProcessEventFlush(WebEventBufferFlushInfo flushInfo)
            // Customize event information to be logged.
                "TextLogProvider buffer flush.");
                string.Format("NotificationType: {0}",
                string.Format("EventsInBuffer: {0}",
                string.Format("EventsDiscardedSinceLastNotification: {0}",
            // Read each buffered event and send it to the Log.
            foreach (WebBaseEvent eventRaised in flushInfo.Events)
            // Store the information in the specified file.
            StoreToFile(customInfo, logFilePath, FileMode.Append);
        // Performs standard shutdown.
        public override void Shutdown()
            // Here you need the code that performs
            // those tasks required before shutting
            // down the provider.
            // Flush the buffer, if needed.
        // Store event information in a local file.
        private static void StoreToFile(StringBuilder text, string filePath, FileMode mode)
                int writeBlock = 256;
                int startIndex = 0;
                // Open or create the local file
                // to store the event information.
                FileStream fs = new FileStream(filePath, mode, FileAccess.Write);
                // Lock the file for writing.
                fs.Lock(startIndex, writeBlock);
                // Create a stream writer
                StreamWriter writer = new StreamWriter(fs);
                // Set the file pointer to the current
                // position to keep adding data to it.
                // If you want to rewrite the file use
                // the following statement instead.
                // writer.BaseStream.Seek (0, SeekOrigin.Begin);
                writer.BaseStream.Seek(0, SeekOrigin.Current);
                //If the file already exists it must not
                // be write protected otherwise 
                // the following write operation fails silently.
                // Update the underlying file
                // Unlock the file for other processes.
                fs.Unlock(startIndex, writeBlock);
                // Close the stream writer and the underlying file   
            catch (Exception e)
                throw new Exception("TextLogProvider.StoreToFile: " + e);