Sidemark: Active Telemetry Comments for C#

OpenTelemetry has become table stakes for .NET observability. But custom instrumentation—the business-specific tags, events, and spans that make traces useful—clutters code. Sidemark is a new NuGet package that moves that instrumentation into comments, rewritten at build time by Roslyn.

The Problem: Instrumentation Overhead

Manual OpenTelemetry code obscures intent. A typical method accumulates StartActivity, SetTag, AddEvent, and SetStatus calls. Auto-instrumentation covers only infrastructure-level spans; the valuable business context still requires hand-written code.

// Before: telemetry competes with logic
var orderId = order.Id;
Activity.Current?.SetTag("orderId", orderId);

Sidemark replaces that with a single comment marker:

// After: telemetry rides alongside
var orderId = order.Id; //?

How Sidemark Works

Sidemark runs as an MSBuild task just before CoreCompile. It parses each source file with Roslyn, rewrites annotated comments into equivalent Activity calls, and writes the rewritten copy into obj/. The compiler sees only the rewritten files; your source files remain untouched. Because comments are trivia in the syntax tree, this must happen at build time, not runtime.

Comment markers are:

  • //? on a local variable → SetTag (optional custom key: //? order.total_cents)
  • //! before a statement or at method entry → AddEvent
  • //? on a method signature → wraps body in a span
  • //? on a catch block → records error status

A worked example with a few tags, a span, and an event replaces about thirty lines of hand-written OpenTelemetry with five comment markers.

Requirements and Setup

  • .NET SDK 8.0.200 or newer to build
  • Any target framework compatible with netstandard2.0 (modern .NET, .NET Framework 4.6.1+, Mono, Unity)
  • Single NuGet package: dotnet add package Sidemark

Configure with one assembly attribute:

[assembly: Sidemark(typeof(OTelConfig))]
public static class OTelConfig
{
    public static readonly ActivitySource ActivitySource = new("MyApp", "1.0.0");
}

Disable with [assembly: DisableSidemark] or true—markers revert to plain comments.

What's in the Box

The package ships three components:

  1. Runtime attributes for pointing at your ActivitySource and disabling Sidemark.
  2. A Roslyn analyzer (SDM001–SDM006) that flags misused markers in IDE and CI logs.
  3. The MSBuild rewriter that performs the build-time transformation.

It borrows the Roslyn from the .NET SDK, adding no transitive NuGet dependencies.

Is This a Good Idea?

The author acknowledges the heresy of making comments load-bearing. Comments traditionally rot, but Sidemark uses them as a write surface for instrumentation metadata—not as documentation. The design keeps the underlying logic legible while preserving full semantic equivalence to hand-written OTel calls.

Get Started

Try it on a service and see if your code reads lighter.