You want your application to output trace information to the event log and, at the same time, control what level of information is output.
Create your own trace listener that inherits from the
TraceListener
class and overrides the
Write
and WriteLine
methods to
write
their output to
the event log. A sample trace listener we’ve written
to demonstrate this solution is shown in Example 10-20
(VB) and Example 10-21 (C#).
Next, modify your web.config
file to add the
custom TraceListener
and
TraceSwitch
, as shown in Example 10-22.
In the classes you want to output trace information, create a
TraceSwitch
object using the name of the
TraceSwitch
you added to the web.config file, and then use the
WriteIf
and WriteLineIf
methods
of the Trace
class to output the required
messages, as we demonstrate in our class in Example 10-23 (VB) and Example 10-24 (C#).
The technique we advocate for writing trace information to the event
log involves creating your own custom trace listener that overrides
the Write
and WriteLine
methods
and directs their output to the event log. We also find it useful to
control the level of messages that are output to the event log, such
as outputting only error messages or outputting error and warning
messages. Controlling the level of messages that are output involves
the use of switches (more about this in a minute).
As discussed in Recipe 10.5, you can
add additional listeners to the TraceListeners
collection via the web.config
file. When a
Trace.Write
or Trace.WriteLine
is executed, all listeners in the TraceListeners
collection receive and process their output.
The support that the .NET Framework provides for the writing of
custom TraceListeners
, as shown here and in other
recipes in this chapter, is even more powerful when coupled with
switches. Switches provide the ability to
control when trace information is sent to the
TraceListeners
configured for your application.
Two switch types are provided in the .NET Framework:
BooleanSwitch
and TraceSwitch
.
The BooleanSwitch
class supports two states (on
and off) that literally turn the trace output on and off. The
TraceSwitch
class supports five levels (off,
error, warning, info, and verbose) to provide the ability to output
messages only for the configured levels.
In our example, we created a custom TraceListener
similar to the one created in Recipe 10.5, except that the messages are written
to the event log rather than the current page, as shown in Example 10-20 (VB) and Example 10-21 (C#).
For additional information on writing to the event log, refer to Recipe 7.3.
You must first add the switch and listener information to your web.config file, as shown in Example 10-22. The switch data includes the name of the switch and the value for the switch. The switch name is the name used in your code to access the switch configuration. The value defines the message level to output, as shown in Table 10-1.
Table 10-1. Switch level values
Value |
Meaning |
---|---|
0 |
Output no messages |
1 |
Output only error messages |
2 |
Output error and warning messages |
3 |
Output error, warning, and informational messages |
4 |
Output all messages |
To output trace messages that use the switch information, you first
need to create a TraceSwitch
object passing the
name of the switch and a general description of the switch. After
creating the TraceSwitch
, you use it with the
WriteIf
and WriteLineIf
methods
of the Trace
class to output your messages. The
first parameter of either method defines the level for which the
message should be output. In other words, if you only want the
message to be output when the switch is configured for
“warnings,” set the first parameter
to the TraceWarning
property of the switch you
created. The second parameter should be set to the message you want
to output.
We are not outputting the trace information to the web form, as we
have in other examples in this chapter, so it is not necessary to add
the trace="true
" statement to the
@
Page
directive in the
.aspx
page or to turn on application-level
tracing in the web.config file.
The name used in the constructor of the
TraceSwitch
must match the name of the switch in
the web.config file. Failing to
use the exact name defined in the web.config file can cause you to spend a
significant amount of time trying to determine why your messages are
not being output as expected.
In a web application, referencing the Trace
class
without further qualifying the namespace will actually reference the
System.Web.Trace
class, which does not support the
WriteIf
and WriteLineIf
methods. To access the Trace
class in the
System.Diagnostics
namespace that provides the
WriteIf
and WriteLineIf
methods, fully qualify the reference:
System.Diagnostics.Trace.WriteIf(level, Message)
Recipe 7.3; for a discussion of trace listeners, see Recipe 10.5
Example 10-20. Custom TraceListener for writing to the event log (.vb)
Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH10EventLogListenerVB.vb ' ' Description: This class provides a trace listener that outputs messages ' to the application event log. ' '******************************************************************************* Imports System Imports System.Diagnostics Namespace ASPNetCookbook.VBExamples Public Class CH10EventLogListenerVB Inherits TraceListener 'the following constant defines the event log to which messages are 'written Const EVENT_LOG_NAME As String = "Application" '************************************************************************* ' ' ROUTINE: Write ' ' DESCRIPTION: This routine writes the passed message to the ' HttpContext Trace object '------------------------------------------------------------------------- Public Overloads Overrides Sub Write(ByVal message As String) writeLogEntry(message) End Sub 'Write '************************************************************************* ' ' ROUTINE: Write ' ' DESCRIPTION: This routine writes the passed message to the ' HttpContext Trace object '------------------------------------------------------------------------- Public Overloads Overrides Sub Write(ByVal category As String, _ ByVal message As String) writeLogEntry(category & ": " & message) End Sub 'Write '************************************************************************* ' ' ROUTINE: WriteLine ' ' DESCRIPTION: This routine writes the passed message to the ' HttpContext Trace object with a CR/LF '------------------------------------------------------------------------- Public Overloads Overrides Sub WriteLine(ByVal message As String) writeLogEntry(message) End Sub 'WriteLine '************************************************************************* ' ' ROUTINE: WriteLine ' ' DESCRIPTION: This routine writes the passed message to the ' HttpContext Trace object '------------------------------------------------------------------------- Public Overloads Overrides Sub WriteLine(ByVal category As String, _ ByVal message As String) writeLogEntry(category & ": " & message) End Sub 'WriteLine '************************************************************************* ' ' ROUTINE: writeLogEntry ' ' DESCRIPTION: This routine writes the passed message to the event log '-------------------------------------------------------------------------Private Sub writeLogEntry(ByVal message As String)
Dim log As EventLog
'Insert error information into the event log
log = New EventLog
log.Source = EVENT_LOG_NAME
log.WriteEntry(message, _
EventLogEntryType.Error)
End Sub 'writeLogEntry
End Class 'CH10EventLogListenerVB End Namespace
Example 10-21. Custom TraceListener for writing to the event log (.cs)
//---------------------------------------------------------------------------- // // Module Name: CH10EventLogListenerCS.cs // // Description: This class provides a trace listener that outputs messages // to the application event log. // //**************************************************************************** using System; using System.Diagnostics; namespace ASPNetCookbook.CSExamples { public class CH10EventLogListenerCS : TraceListener { // the following constant defines the event log to which messages are // written const String EVENT_LOG_NAME = "Application"; //************************************************************************ // // ROUTINE: Write // // DESCRIPTION: This routine writes the passed message to the // HttpContext Trace object //------------------------------------------------------------------------ public override void Write(String message) { writeLogEntry(message); } // Write //************************************************************************ // // ROUTINE: Write // // DESCRIPTION: This routine writes the passed message to the // HttpContext Trace object //------------------------------------------------------------------------ public override void Write(String category, String message) { writeLogEntry(category + ": " + message); } // Write //************************************************************************ // // ROUTINE: WriteLine // // DESCRIPTION: This routine writes the passed message to the // HttpContext Trace object //------------------------------------------------------------------------ public override void WriteLine(String message) { writeLogEntry(message); } // WriteLine //************************************************************************ // // ROUTINE: WriteLine // // DESCRIPTION: This routine writes the passed message to the // HttpContext Trace object //------------------------------------------------------------------------ public override void WriteLine(String category, String message) { writeLogEntry(category + ": " + message); } // WriteLine //************************************************************************ // // ROUTINE: writeLogEntry // // DESCRIPTION: This routine writes the passed message to the event log //------------------------------------------------------------------------private void writeLogEntry(String message)
{
EventLog log;
// Insert error information into the event log
log = new EventLog( );
log.Source = EVENT_LOG_NAME;
log.WriteEntry(message,
EventLogEntryType.Error);
} // writeLogEntry
} // CH10EventLogListenerCS }
Example 10-22. web.config settings for adding the trace listener and trace switch
<system.diagnostics><switches>
<!-- This switch controls messages written to the event log.
To control the level of message written to the log set
the value attribute as follows:
"0" - output no messages
"1" - output only error messages
"2" - output error and warning messages
"3" - output error, warning, and informational messages
"4" - output all messages
-->
<add name="EventLogSwitch" value="0" />
</switches>
<trace autoflush="true" indentsize="0"><listeners>
<add name="CookbookEventLogListener"
type="ASPNetCookbook.VBExamples.CH10EventLogListenerVB,
ASPNetCookbookVB" />
</listeners>
</trace> </system.diagnostics>
Example 10-23. Writing trace information as a function of trace level (.vb)
Dim generalTraceSwitch As TraceSwitch 'create the trace switch generalTraceSwitch = New TraceSwitch("EventLogSwitch", _ "Used throughout the application") 'write trace data if error level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceError, _ "This is an error message") 'write trace data if warning level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceWarning, _ "This is an warning message") 'write trace data if info level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceInfo, _ "This is an info message") 'write trace data if verbose level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceVerbose, _ "This is an verbose message")
Example 10-24. Writing trace information as a function of trace level (.cs)
TraceSwitch generalTraceSwitch = null; // create the trace switch generalTraceSwitch = new TraceSwitch("EventLogSwitch", "Used throughout the application"); // write trace data if error level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceError, "This is an error message"); // write trace data if warning level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceWarning, "This is an warning message"); // write trace data if info level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceInfo, "This is an info message"); // write trace data if verbose level is enabled System.Diagnostics.Trace.WriteIf(generalTraceSwitch.TraceVerbose, "This is an verbose message");