Service Map not linking services

Hi @jhai,

Below I answer your questions, but before I do so: You can do manual instrumentation for most part and still enable auto instrumentation for outgoing HTTP.

For that, you can simply do this:

Elastic.Apm.Agent.Subscribe(new HttpDiagnosticsSubscriber());

The HttpDiagnosticsSubscriber will turn on auto instrumentation for outgoing HTTP calls. This means each time an outgoing HTTP call happens, the agent will capture it as a span IF there is an active transaction. This means you’ll still need to start your transactions manually (with Tracer.StartTransaction or Tracer.CaptureTransaction), but within a transaction HTTP calls will be automatically captured – so you don’t need any of the span related code (no t.StartSpan, etc.)

The good part about this is that you don’t need to take care of the traceparent header and the whole service map thing will also work – the agent will take care of it automatically.

If you still want to do this manually, you need to do more work. Let me answer your questions, with that it will be hopefully clear what you need to do. But again, I’d rather suggest using HttpDiagnosticsSubscriber and let the agent take care of this.

Its not very clear from the documentation what makes Service Maps work, whether the flow is determined from Services/Transactions/Spans.

Yeah, I agree, we don’t really document this. Service map uses the destination field on spans. These fields are reflected on the public API in C# like this:

transaction.CaptureSpan("foo", "bar", span =>
{
	span.Context.Destination = ...
});

But you don’t really need it – the agent deduces it from other fields. Specifically for HTTP calls it uses the span.Context.Http field to fill the destination field, so span.Context.Http must be set and the agent will do its job to fill necessary fields for the service map.

Is it correct that I need to manually include Traceparent in the header of the request or should this be added automatically?

For the service map you don’t really need that, it only uses the fields I mentioned above. But you’ll still need to manually include the traceparent header in order to make sure the whole thing ends up in a single trace.

But Elastic.Apm.Agent.Subscribe(new HttpDiagnosticsSubscriber()); takes care of both of these things (the destination field and the traceparent header).

I hope this helps.
Greg