Two routes. Automatic instrumentation needs no code changes and suits an app you would
rather not rebuild. The SDK route is a few lines in Program.cs and gives finer control.
Both send the same OTLP data.
Option A — automatic, no code changes
Option B — the SDK
AddOtlpExporter() with no arguments reads OTEL_EXPORTER_OTLP_ENDPOINT, _HEADERS and
_PROTOCOL from the environment, so the same build works in every deployment.
Custom spans
.NET uses System.Diagnostics.Activity as its span type. An ActivitySource whose name
is not registered with AddSource() produces null activities and no data — the usual
reason custom spans go missing.