Nikolai Savenko
Altenar
This talk will cover how to build modern distributed tracing in .NET — from basic platform diagnostic tools to a full-fledged observability architecture based on OpenTelemetry.
We'll begin by examining EventSource, DiagnosticSource, and ActivitySource to understand how the approach to telemetry in .NET has evolved and why ActivitySource became the foundation for distributed tracing.
We'll then explore context propagation: how to pass trace context between services, brokers, and asynchronous processes, including using transactional outboxes as an example. A separate section will be devoted to OpenTelemetry as a way to avoid vendor lock-in and maintain freedom of choice between different backends.
In the practical section, I'll demonstrate how to make decisions about instrumenting infrastructure libraries: what to do if a component already uses ActivitySource, if only DiagnosticSource is available, if only EventSource is available, or if there is no instrumentation at all. We'll also consider auto-instrumentation and IL injection, their strengths, limitations, and impact on performance.
This talk will cover best practices: which parts of the system should be separated into separate ActivitySources, which operations should be converted into Activities, and how to avoid overloading the system with unnecessary spans. For local development, I'll show how to use the Aspire Dashboard separately from the rest of Aspire, and also briefly touch on IDE tools, such as OpenTelemetry support in Rider.
Finally, we'll discuss trace and log correlation, as well as advanced features like baggage, linked spans, exemplars, and sampling, to demonstrate how to build tracing that will be useful not only for developers but also for operations.
Altenar