Dear Miss O11y,
I use .NET and I keep seeing something called `Activity` but in OpenTelemetry there is only talk about “Span” and “Trace,” why? And what should I be using?
Kthxbye
This is understandable, and has caused confusion since that decision was made by Microsoft back in 2018/19 (I believe). I’ll do my best to provide some guidance on what the distinction is, and also when each is useful.
What is Activity?
Activity is a class in theSystem.Diagnostics
namespace, and therefore part of the .NET BCL. It’s been there since .NET Core 2.0 which was released in 2017. This was part of Microsoft’s strategy for providing monitoring capabilities in their cross-platform stacks, as their performance metrics were heavily embedded into Windows.
ActivitySource is the parent to Activity, and provides the grouping of Activity instances.
ActivitySource source = new ActivitySource("Frontend Service"); using (var activity = source.StartActivity("Get Account Info")) { // Do stuff to get Account Info await Task.Delay(500); return "Hello world"; }
Why aren’t we using OpenTelemetry Terms in .NET?
Activity pre-dates OpenTelemetry (OTel), so you can understand that Microsoft needed something in the framework to provide access to Telemetry information. But now it’s clear why having an additional method could be confusing for implementers today (which is where we’re at, but hey-ho).
The other part to this is that Activity is built into the .NET BCL (Base Class Library) and is therefore available pretty much out of the box. This is desirable, especially in the .NET community, as things provided by Microsoft in the BCL are generally considered easier to adopt.
What is the OpenTelemetry .NET Shim?
The OpenTelmetry Tracing Shim was created by the community to address the lack of consistent terminology for OpenTelemetry into the .NET development world. It provides a proxy that allows you to useTracer
andSpan
in your code, while under the hood it’s creating ActivitySource and Activity instances, allowing you to use consistent terminology throughout your ecosystem.
This can be especially useful if you’re coming from another language, or if you’re constantly switching between .NET and other languages. Largely because you can maintain the same mental model across those languages. But, it’s less useful if you’re solely programming in .NET.
It also has the added benefit that you don’t need to constantly check for nulls (/me gives dirty looks to.StartActivity()
and its null object response).
using (var span = tracer.StartActiveSpan("Get Account Info")) { // Do stuff to get Account span.SetAttribute("account_id", 123); span.AddEvent("Something Happened", DateTimeOffset.UtcNow, new SpanAttributes( new List<KeyValuePair<string, object>> { new("some_attribute", "Some Value") })); await Task.Delay(500); return "Hello world"; }
Understanding the differences in .Net and OpenTelemetry terminology
ActivitySource is analogous to a Tracer. It’s what we create our spans from.
Activity is analogous to a Span. It has metadata, and can be considered Active or not.
Tags on a Span are the equivalent of adding attributes to a Span.
Be careful of Baggage. The semantics of Baggage in Activity do not map to the Baggage used for propagation of context in OpenTelemetry. If you need this, then do not use Activity. You can also use Baggage from OpenTelemetry, and Activity together.
When should I use Activity over OpenTelemetry directly?
My advice here is that if you’re writing a Library that you’re going to distribute beyond your immediate team, use Activity. The reason being that there will be less hurdles for things like compliance departments in the other teams/organizations to consider when approving the use of your library without losing the instrumentation you’ll write. They can leave that debate for when they want to bring in a full observability provider like Honeycomb.
If you’re in full control of everything in your application, use the Tracer from OpenTelemetry as you’ll have less messy code, and can take full advantage of things like Baggage propagation as well as the wide variety of plugins and processors available for OpenTelemetry.
What does the future hold for OpenTelemetry and Activity?
While I can’t predict the future and do not have insider knowledge, I can at least share what I’d like to see and vice versa.
I’d like to see the BCL adopt the same pattern for tracing as they have Logs with Logger Interface, and to a certain extent, Metrics. That means having an abstraction that is part of the BCL and plugs OpenTelemetry into it. I don’t want to see Microsoft, and the core team behind the BCL, try to build more OpenTelemetry features into the framework, and instead rely more on the open source solutions for providing features like Tracing, Metrics, and Logs.
Want to chat more about Activity and OpenTelemetry? I encourage you to join our Pollinators Slack community (all you need is an account with our free tier) or simply sign up for 1:1 office hours with me to discuss.