Skip to content

Managing Activity & Correlation IDs

Bill Wilder edited this page Aug 21, 2013 · 4 revisions

Managing Activity & Correlation IDs

One of the most valuable features of ETW is built-in support for Activity IDs. An Activity ID is a GUID assigned to a particular operation. If you set an Activity ID, ETW will automatically log the Activity ID for each of the events that are logged. It is a thread-local variable, so you don't have to pass the Activity ID around.

This is one of the most valuable debugging and tracing features. Use it. You will thank me later.

Once you add an Activity ID, all of the events for an operation are grouped together. You can find the entire causal chain of events. Unfortunately, .NET 4.5 EventSource doesn't expose Activity ID and the EventProvider class in .NET is actually broken.

The ESP library includes the EventActivityScope class. EventActivityScope makes it trivial to add Activity IDs to your code:

using (EventActivityScope scope = new EventActivityScope())
{
	// anything logged within this scope will automatically have the same Activity ID		
}

By default, EventActivityScope will create a new ActivityID, but sometimes you want it to "ensure there is an Activity ID". If there is an ID assigned, use it, otherwise create one. You can do this with the reuseExistingActivityId parameter:

using (EventActivityScope scope = new EventActivityScope(reuseExistingActivityID: true))
{
	// if an ActivityID exists, all logs will use that Activity ID
	// if no ActivityID exists, a new Activity ID is used
}

You can also nest scopes:

using (EventActivityScope scope1 = new EventActivityScope())
{
	// events are logged under scope1

	using (EventActivityScope scope2 = new EventActivityScope(reuseExistingActivityID: true))
	{
		// events are still logged under scope1
	}

	using (EventActivityScope scope3 = new EventActivityScope(reuseExistingActivityID: false))
	{
		// events are logged under scope3
	}
}

You can get the current activityID by calling EventActivityScope.CurrentActivityId.

HINT: Activity IDs are GUIDs. When graphically displaying Activity IDs in a log, we convert the first 3 bytes to an RGB value and display a colored block. GUIDs are random enough that it's pretty easy to tell which events go together.

EventActivityScope and TracingProxy

If you create a TracingProxy with TracingProxy.CreateWithActivityScope, the proxy will automatically create an EventActivityScope around all calls to the proxy. This is helpful when the proxy will be called from a context that does not automatically generate a scope, such as in an executable or MVC application. WCF will automatically create a scope for you when it activates a service.

You should generally use CreateWithActivityScope all the time, but if you want to avoid the overhead of creating a scope (it's small), then use the Create method, which skips creating an ActivityScope.