I'm nearing closer to implementing a correlation id through an entire WCF call chain. It was working for single threaded calls. Then my parallel calls test executed and the result was not what I needed.
Here's what I mean by all of this:
Suppose we have three services - Sa, Sb, and Sc. And a single client - Ca.
When Ca calls Sa and Sa calls Sb and Sc in the same call, then responds to Ca I want to be able to trace all of those related calls in a call log so that I know which calls contributed to an event (perhaps an error or a specific data update).
Currently, we have all calls being logged in a database via a custom operation invoker which implements IOperationInvoker. That implementation sends a one-way call to a singleton logger service which logs the pre- and post-invoke including operation, call time, who called, etc.
I'm adding messageId from the IncomingMessage built in header property "MessageId" (only the Guid part though). I'm also adding a CorrelationId to the header and this is where I'm currently sort of in the weeds.
CorrelationId is a custom header value that will be logged to the call log for each call in all services. For all calls related to a single origin call, it will have the same value. For each origin call, it will have a different value. An origin call is a call to a service which begins a call-chain. It would originate from outside the system (collection of services), typically from a UI or a service outside the system.
The service context that handles the first incoming call would need to create the Guid before the call is logged. It would need to be passed via a message header before the call is made to the service. Each service would need a way to know if it is the first service in the call chain. The absence of the correlation id in the header should suffice.
Implementing an IClientMessageInspector should be perfect for this. The BeforeSendRequest method has the message and adding the header value is trivial.
I created a correlationId member on the class that implements this interface. The only thing left is initializing this Guid when the CorrelationId messgaeheader is missing and add it to the headers. Hopefully that will wrap up the implementation. Then its just a matter of adding the extension to each service.