Oh yes. More tracing. Push through the pain barrier. Things are actually starting to get interesting.
Tracing is only useful if you do something with the output. Clearly, we're going to get a heap load of information; we need to be able to manipulate it. Currently, we can use logging level or source to filter and route it.
This isn't enough. It makes it easy to see what's being logged for a particular component, or what errors we're getting, but that's about it. We're missing the ability to be able to trace a call end-to-end.
And that's where Activities come in.
We wanted to build something like this into the telemetry framework for Trafalgar, but couldn't decide on requirements that weren't hideously complex. We should have just waited a few years - Microsoft have built it for us.
The System.Diagnostics.Trace class has a static property called CorrelationManager. This class provides a place to store a thread local activity id.
An activity is simply a unit of work, and the id is used to correlate events logged within this unit. You can start and stop an activity, suspend and resume it. More interestingly, you can transfer from one activity to another, and propagate an activity between processes and machines via WCF or remoting.
This gives us everything we need to do end-to-end tracing. It's easiest to look at an example in the Service Trace Viewer, and that'll be the next (final) post on tracing.
It's worth pointing out that activity ids are not a stack. You don't push a new activity, do some work and then pop it - you always transfer between activities. This makes activities much more flexible in their lifetime management, meaning that activities are not limited to the same physical flow as your code. You can suspend and resume a long running activity or perform asynchronous activities (by transferring back to an existing activity and moving the current activity to another thread).
While this is all part of System.Diagnostics, only the XmlWriterTraceListener actually outputs the activity id. This listener creates xml fragments following a schema called End To End Tracing - a schema WCFs Service Trace Viewer understands.
It's a bit odd that XmlWriterTraceListener is part of .net2, but the first thing that actually makes use of it is .net3! In fact, the tracing documentation on msdn comes in two parts - the .net 2 pages cover the basics of TraceSource and TraceListener, but the only place that end to end tracing is covered is in the .net 3 docs.
(As it happens, the WCF docs on configuring tracing also provide a very useful list of what gets logged at what levels - very handy for deciding what you should log in your own code.)
Now then, I promised pictures...