Search code examples
c#signalropen-telemetryjaeger

Activity Opentelemetry tracing .Net Core remote service


I have multiple web services which connect via SignalR to a set of remote .Net Core applications, which allows them to receive messages via the SignalR channel. The messages contain a data structure which contains a Trace ID which is set on the web services. I have Jaeger setup and the remote and web service report in ok and the Traces look good, from the web service to DB etc.

However on receiving a SignalR message I am not able to trace it from the remote services. However if I make a request to the Web API the Traces can be seen in Jaeger.

The current flow:

  1. A request to the web service - E.g HTTP POST
  2. The web service send a message over SignalR via Hub
  3. The remote service recieve the message
  4. Remove service actions the message
  5. The remote service may send information to a web service.

From Jaeger I can see the the initial HTTP POST and some DB requests but that is ultimately where it ends.

At the remote service side I read the message and then create a new Activity with the TraceId.

private ActivitySource CurrentSource { get; set; }
private Activity CurrentActivity { get; set; }

 public void StartWithParentId(string name, string parentTraceId)
 {
        if (string.IsNullOrWhiteSpace(parentTraceId))
        {
            Start(name);
            return;
        }

        Debug.WriteLine($"TRACE INFORMATION Name:{name.GetLogQuoteString()} " +
                        $"TraceID:{parentTraceId.GetLogQuoteString()}");
        CurrentSource = _accSourcesService.Get();

        CurrentActivity = CurrentSource?.StartActivity(name);
        CurrentActivity?.SetParentId(parentTraceId);
        CurrentActivity?.SetIdFormat(ActivityIdFormat.W3C);

 }

I then add some tagging and baggage to the activity

 public static void CreateTaggingAndBaggageFromJob(IActivityService activityService, 
        ISignalRBaseJob job)
    {
        activityService.AddBaggage("job.id", job.Id);
        activityService.AddTag("job.id", job.Id);
        activityService.AddBaggage("RId", job.RID);
        activityService.AddTag("RId", job.RID);
    }

Then once all the job is completed:

 public void Stop()
 {
    CurrentActivity?.Stop();
    CurrentActivity?.Dispose();
    CurrentActivity = null;
 }

Solution

  • From the documentation of SetParentId:

    This method is only intended for use with Activities created from the Activity constructor. Activities created by calling CreateActivity or StartActivity already have the parent ID set, and invoking this method has no effect.

    In your case, the call to SetParentId has no effect, because StartActivity already sets a parent context, which cannot be overwritten later on.

    If using StartActivity, one needs to specify the parent activity context as part of this call, e. g. with this overload of StartActivity.

    One can use ActivityContext.TryParse to create an ActivityContext from W3C Trace Context headers.