Browse DevX
Sign up for e-mail newsletters from DevX


Instrumenting Applications with .NET Tracing : Page 4

If you really want to know how a production application is running, try turning on .NET's tracing capabilities. You can use .NET's built-in tracing or build your own.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Custom Switches
The switches that ship with .NET will work fine for most cases. However, there are times when you may want to implement your own custom switches. Perhaps you want to migrate another system where you have a different logging strategy that worked and you want to mimic that strategy in .NET. What if the all-inclusive logic of the TraceSwitch didn't quite meet your needs?

I'll demonstrate how to create a custom switch. I designed my example to give you ideas of how you could implement your own custom switch to achieve the granularity and logic handling appropriate for your needs.

The custom switch in Listing 1, FlagSwitch, creates new switch categories: None, Enter, Exit, Info, and Exception. As opposed to the TraceSwitch where higher switch levels are all inclusive of lower levels, the FlagSwitch lets you turn categories on and off at will.

The FlagLevel enum is decorated with the [Flags] attribute, allowing you to use it in bitwise operations. You can explicitly set each element with a hex value to ensure their values don't overlap.

Notice how my example exposes each switch setting as a property. The get accessors use the SwitchSetting of the base class, Switch, and use a bit-wise AND operation to check if the bit representing that condition is set. The Switch class takes care of reading configuration file settings and ensures that the SwitchSetting property is set accordingly. The implementation also ensures that in all properties, except for None, the None bit is turned off, since this would represent an illogical condition.

Trace Configuration
The configuration files in previous examples showed how to add a single switch to an application. You can do more with configuration files including add additional switches and remove switches. The following snippet shows these additional switch configuration capabilities:

<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <switches> <add name="TraceSwitch3" value="4" /> <add name="TraceSwitch2" value="4" /> <add name="TraceSwitch1" value="4" /> <remove name="TraceSwitch2" /> </switches> </system.diagnostics> </configuration>

The configuration file adds three switches, which you can use in different parts of an application to give you more control over where you want to view debug output. The remove element essentially un-defines TraceSwitch2, making any conditional Trace statements in your code evaluate to false and not print. The remove element provides a way to turn a switch off, which is an alternative to deleting, commenting, or setting a value to 0 (assuming that 0 represents a condition that prevents trace output) of an existing switch.

Dynamic Switch Settings
Besides using configuration files, you can change switch settings dynamically in code. For example, the following code modifies the TraceLevel setting to None for a TraceSwitch:

switch1.Level = TraceLevel.Off;

If you needed to dynamically set the switch on a custom switch, you should provide a property that accepts an enum for the custom switch type. The implementation of that property can get and set base.SwitchSetting appropriately. The following property implements this for the custom switch described in the Custom Switches section of this article:

public FlagLevel Level { get { return base.SwitchSetting; } set { base.SwitchSetting = (int)value; } }

This is necessary because the Switch.SwitchSetting property has protected visibility.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date