C#C
C#8mo ago
Ainz

OpenTelemetry and Method Boundaries

Probably a dumb question, but does ActivitySource (within the context of OpenTelemetry-Dotnet and Application Insights) track context across a method boundary or an async method boundary? From what I've read, it internally tracks Activity.Current and should track context across method boundaries further down in the application, but I guess I don't understand entirely how that works internally.

From what I've seen elsewhere, you have to set the parent context when you have multiple nexted Activities within the same scope, for setting an Outer activity and then small Inner activities if you wanted to track things within the same method. Outside of that, I know you need to pass parent context across thread boundaries if you using producer / consumer patterns and pushing things onto a queue (from what I understand)

I guess my confusion lies where I don't understand how the Span and TraceId propagate across method boundaries into child method calls and how those subsequent child methods are instrumented and measured. In application insights, I see a Gantt chart with processing times for methods and I'm just wondering how that chart is created with the top level method calls propagating through all of the child method calls, and whether I have to pass the context down through those methods with each of their own activities for each method to be measured. Or if ActivitySources / OpenTelemetry-Dotnet does that for you

ActivitySource Source = new("Program");

using var ignore = Source.StartActivity("User Interface");
await UserInterface();

return;

static async Task UserInterface()
{
    await ServiceLayer();
}

static async Task ServiceLayer()
{
    await DataAccessLayer();
}

static async Task DataAccessLayer()
{
    // Make a HTTP Call or access a database
}


Or do I need to explicitly pass parent context down into each layer of the application

ActivitySource Source = new("Program");

using var x = Source.StartActivity("Program.Main");
await UserInterface(x.Context);

return;

static async Task UserInterface(ActivityContext parent)
{
    using var a = Source.StartActivity("User Interface", ActivityKind.Internal, parent);
    await ServiceLayer(a.Context);
}

static async Task ServiceLayer(ActivityContext parent)
{
    using var b = Source.StartActivity("Service Layer", ActivityKind.Internal, parent);
    await DataAccessLayer(b.Context);
}

static async Task DataAccessLayer(ActivityContext parent)
{
    using var _ = Source.StartActivity("Data Layer", ActivityKind.Internal, parent);
    // Make a HTTP Call or access a database
}
Was this page helpful?