I ran into a problem recently when working with the logging functionality built into .NET 2.0 inside the System.Diagnostics namespace. Everything's mostly very simple in here.
System.Diagnostics.Trace.TraceError("Oh no! Something happened");
As you can see, we've logged two messages one at an Information level and another at Error level. You may remember that I've discussed logging levels
If you're using System.Diagnostics seriously, you're probably using a TraceSource
instance, which lets you do similar things to the above and you can specify the level from the TraceEventType enumeration.
TraceSource mySource = new TraceSource("mySource");
mySource.TraceEvent(TraceEventType.Error, 0, "Oh no! Something happened");
Now that you have access to the TraceEventType enumeration you may notice that there are quite a few values here:
public enum TraceEventType
Critical = 1,
Error = 2,
Warning = 4,
Information = 8,
Verbose = 16,
Start = 256,
Stop = 512,
Suspend = 1024,
Resume = 2048,
Transfer = 4096,
Controlling the level
Similar to the main subject of the previous post
I mentioned, you can control the output of the logging in System.Diagnostics by modifying a 'switch' against the TraceEventType of each event.
The configuration looks like this...
<source name="mySource" switchName="SourceSwitch">
initializeData= "Test.log" />
<!-- this is the part we're interested in -->
<add name="SourceSwitch" value="Warning" />
Here, we configure a Source and wire it up to the XmlWriterTraceListener (which will dump logging events into a test.log file nicely marked up in Xml). We also point our Source at a switch with a value of Warning. This means that we will only 'dump' events of TraceEventType.Warning or above. Easy peasy.
MSDN has an article on the various settings you can use in the switch value
. In summary, it shows these:
- Off (0)
- Error (1)
- Warning (2)
- Info (3)
- Verbose (4)
... which map exactly to the TraceLevel
enumeration. You can even use the numbers instead of the stringified
Having said that, when using a TraceSource you'll find little correlation between the TraceEventType and the TraceLevel. In fact, I couldn't get any of these to write out Start, Stop, Suspend, Resume or Transfer level events.
This had me baffled for sometime but some digging in reflector shows that this is because TraceSource actually uses a SourceSwitch
, not a TraceSwitch
The SourceSwitch uses a totally different enum called SourceLevels:
public enum SourceLevels
All = -1,
Off = 0,
Critical = 1,
Error = 3,
Warning = 7,
Information = 15,
Verbose = 31,
ActivityTracing = 65280,
Fortunately, we can use these values (stringified or numeric) in our switches... exactly what's going to happen might not be clear so I've created the following grid to help you out. The Items down the left are the SourceLevels you specify in the config. And the items across the top represent the TraceEventType values tied to a particular event. A tick indicates that this level event will log against this SourceLevel.
Next, we'll be looking at how I generated this chart using only Xaml (via WPF) and a simple MultiValueBinding!
See you then.
02 Jul 2007
» Next Post:
Sortable ListView in WPF
« Previous Post:
Compiled and checked in
Comments are closed for this post.
16 Sep 2008
You sir, are the man. This has been bothering me for awhile. Everything I have read indicates that you can combine the source levels using bitwise operations, but I couldn't get the list of what those trace levels were. (I was trying to filter out the verbose messages from log files.) That's because, as you pointed out, they are really source levels. Thanks a ton for your excellent post !!
06 Oct 2008
Thanks for the post - one minor comment: The ActivityTracing bits are the high order bits (decimal 65280 is 1111111100000000 binary) so the columns should be flipped around.