The source code method:
// First step: create the trace source object TraceSource ts = new TraceSource("myTraceSource"); // Second step: create some trace listeners TextWriterTraceListener tr = new TextWriterTraceListener("C:\\outfile.txt"); XmlWriterTraceListener xt = new XmlWriterTraceListener("C:\\outfile.xml"); DelimitedListTraceListener dt = new DelimitedListTraceListener("C:\\outfile.csv.txt"); EventLogTraceListener et = new EventLogTraceListener("myappp"); // Third step: configuring our trace source and trace listeners ts.Switch = new SourceSwitch("mySwitch", "my switch"); ts.Switch.Level = SourceLevels.Warning; // Enable only warning, error and critical events // Configuring trace listeners dt.Delimiter = "|"; dt.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Timestamp; xt.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Timestamp; tr.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Timestamp | TraceOptions.Callstack; // Adding our trace listeners ts.Listeners.Clear(); ts.Listeners.Add(et); ts.Listeners.Add(dt); ts.Listeners.Add(tr); ts.Listeners.Add(xt); // Setting autoflush to save files automatically Trace.AutoFlush = true; // Writing out some events ts.TraceEvent(TraceEventType.Warning, 0, "warning message"); ts.TraceEvent(TraceEventType.Error, 0, "error message"); ts.TraceEvent(TraceEventType.Information, 0, "information message"); ts.TraceEvent(TraceEventType.Critical, 0, "critical message");The application configuration file method:
We can achieve the same task above using the application configuration file. This allow you to change settings at runtime when you need some tracing information.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <trace autoflush="true"/> <sources> <source name="myTraceSource" switchName="mySwitch" switchType="System.Diagnostics.SourceSwitch" > <listeners> <clear/> <add name="evengloglistener" type="System.Diagnostics.EventLogTraceListener" initializeData="myApp" /> <add name="delimitedListener" type="System.Diagnostics.DelimitedListTraceListener" delimiter="|" initializeData="c:\outfile.csv.txt" traceOutputOptions="ProcessId, DateTime" /> <add name="textwriterListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\outfile.txt" traceOutputOptions="ProcessId, DateTime, Callstack" /> <add name="xmlListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\outfile.xml" traceOutputOptions="ProcessId, DateTime" /> </listeners> </source> </sources> <switches> <add name="mySwitch" value="Warning" /> </switches> </system.diagnostics> </configuration>The source code now looks simple like this:
// First step: create the trace source object TraceSource ts = new TraceSource("myTraceSource"); // Writing out some events ts.TraceEvent(TraceEventType.Warning, 0, "warning message"); ts.TraceEvent(TraceEventType.Error, 0, "error message"); ts.TraceEvent(TraceEventType.Information, 0, "information message"); ts.TraceEvent(TraceEventType.Critical, 0, "critical message");CorrelationManager
We can use the CorrelationManager to group correlated traces. The switch level must include the LogicalOperationStack option.
Using source code configuration:
tr.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Timestamp | TraceOptions.LogicalOperationStack;Or using the Application configuration file:
<add name="textwriterListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\outfile.txt" traceOutputOptions="ProcessId, DateTime, LogicalOperationStack" />And the code must looks like:
// Start the first logical operation Trace.CorrelationManager.StartLogicalOperation("first logical operation"); ts.TraceEvent(TraceEventType.Warning, 0, "warning message"); ts.TraceEvent(TraceEventType.Error, 0, "error message"); // Start a nested logical operation Trace.CorrelationManager.StartLogicalOperation("second logical"); ts.TraceEvent(TraceEventType.Information, 0, "information message"); // Stop the second logical operation Trace.CorrelationManager.StopLogicalOperation(); ts.TraceEvent(TraceEventType.Critical, 0, "critical message"); // Stop the first logical operation Trace.CorrelationManager.StopLogicalOperation();Another useful technique is filter some kind of events and redirect them to one specific listener, for example, critical errors must be logged to a file and warning events to the event log only.
tr.Filter = new EventTypeFilter(SourceLevels.Error);
Or<add name="textwriterListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\outfile.txt" traceOutputOptions="ProcessId, DateTime, LogicalOperationStack"> <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"/> </add>NOTE: you can have more than one trace source, for example, one for normal data and another for critical and private data.
By using the shareListeners setting you can add global listeners:
<sharedListeners> <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="myListener.log"> <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"/> </add>
2 comments:
nice tutorial. thanks!
Extremely helpful, simple tutorial. Thank you!
Post a Comment