Configuring Message Flow Tracing

When Windows Communication Foundation (WCF) activity tracing is enabled, End-To-End Activity IDs are assigned to logical activities throughout the WCF stack. In .NET Framework 4.6.1, there is now a higher performance version of this feature that works with Event Tracing for Windows (ETW) called message flow tracing. When enabled, End-To-End activity IDs are taken from (or assigned to if empty) incoming messages and are propagated to all tracing events that are emitted after the message has been decoded by the channel. Customers can use this feature to reconstruct message flows with trace logs from different services after decoding.

Tracing can be enabled after a problem is detected with the application and then disabled once the problem is resolved.

Enabling Tracing

You can enable message flow tracing by setting the .NET Framework 4 messageFlowTracing configuration element to true, as shown in the following example.

<system.servicemodel>  
  <diagnostics>  
    <endToEndTracing propagateActivity="true" messageFlowTracing="true" />  
  </diagnostics>  
</system.servicemodel>  

Note

Because the endToEndTracing configuration element resides in a Web.config file, it cannot be dynamically configured in the same way as ETW. For the endToEndTracing configuration element to take effect, the application must be recycled.

Activities are correlated by the interchange of an identifier called the activity ID. This identifier is a GUID, and is generated by the System.Diagnostics.CorrelationManager class. If you manipulate System.Diagnostics.Trace.CorrelationManager.ActivityID, ensure that the value is set to original when execution control transfers back to WCF code. Also, if you use an asynchronous WCF programming model ensure that System.Diagnostics.Trace.CorrelationManager.ActivityID is transferred between the threads.

Message Flow Tracing and REST Services

Message flow tracing allows you to trace a request end to end. With SOAP-based services an Activity ID is sent in a SOAP message header. REST requests do not contain this header so a special HTTP event header is used instead. The following code snippet shows how you can programmatically retrieve the Activity ID value:

Object output = null;
if (OperationContext.Current.IncomingMessageProperties.TryGetValue(HttpRequestMessageProperty.Name, out output))
{
   HttpRequestMessageProperty httpHeaders = output as HttpRequestMessageProperty;
   // Retrieve the Activity Id from the HTTP header    string e2eId = httpHeaders.Headers["E2EActivity"];
   // ...
}

You can programmatically add the header using the following code:

HttpContent content = new StreamContent(contentStream);  
Guid correlation = Guid.NewGuid();  
content.Headers.Add("E2EActivity", Convert.ToBase64String(correlation.ToByteArray()));