Skip to content
Development
Skill

/opentelementry-dotnet-instrumentation

Provides guidance for implementing OpenTelemetry instrumentation in .NET codebases, covering tracing (Activities/Spans), metrics, logs, naming conventions, error handling, performance, SDK setup, resources, context propagation, and API design best practices.

From plugin
dotnet-skills
1.1k36 skills6 agents
Install
$ npx -y skills add aaronontheweb/dotnet-skills --skill opentelementry-dotnet-instrumentation --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/opentelementry-dotnet-instrumentation

Context preview

The summary Claude sees to decide when to auto-load this skill.

Provides guidance for implementing OpenTelemetry instrumentation in .NET codebases, covering tracing (Activities/Spans), metrics, logs, naming conventions, error handling, performance, SDK setup, resources, context propagation, and API design best practices.

SKILL.md

opentelementry-dotnet-instrumentation.SKILL.md
name: opentelemetry-net-instrumentation
description: Provides guidance for implementing OpenTelemetry instrumentation in .NET codebases, covering tracing (Activities/Spans), metrics, logs, naming conventions, error handling, performance, SDK setup, resources, context propagation, and API design best practices.
version: 2.0.0
tags:
  - opentelemetry
  - dotnet
  - observability
  - tracing
  - metrics
  - logs
  - performance

OpenTelemetry .NET Instrumentation Skill

When to Use

  • Adding OpenTelemetry instrumentation to .NET code (traces, metrics, logs)
  • Creating or modifying ActivitySources, Meters, or ILogger usage
  • Setting up the OpenTelemetry SDK, resources, exporters, or sampling
  • Reviewing telemetry implementations for spec compliance
  • Optimizing instrumentation performance
  • Designing telemetry APIs that become part of the public surface
  • Implementing context propagation across service boundaries

Architecture: .NET Is Different

**CRITICAL**: The .NET OpenTelemetry implementation is fundamentally different from other platforms. .NET provides tracing, metrics, and logging APIs **in the framework itself**. That means **OTel does not provide a separate instrumentation API** — it uses the built-in .NET APIs and acts as the collection/export layer.

The Three Built-in .NET APIs (Primary — Zero Dependencies)

| Signal | .NET Framework API | Namespace | |--------|-------------------|-----------| | **Tracing** | `ActivitySource` / `Activity` | `System.Diagnostics` | | **Metrics** | `Meter` / `Counter<T>` / `Histogram<T>` / etc. | `System.Diagnostics.Metrics` | | **Logging** | `ILogger<T>` | `Microsoft.Extensions.Logging` |

These are **the primary and only APIs** library authors should use for instrumentation. They ship with the .NET runtime — **no NuGet packages required**.

The OTel Collection/Export Layer (Secondary — Application Root Only)

OTel NuGet packages are the **collection and export layer**, added only at the application composition root (not in libraries):

| Package | Purpose | When to add | |---------|---------|-------------| | `OpenTelemetry.Extensions.Hosting` | DI integration for ASP.NET Core / generic host | Application only | | `OpenTelemetry.Exporter.Console` | Console exporter (dev/testing) | Application only | | `OpenTelemetry.Exporter.OpenTelemetryProtocol` | OTLP exporter (production) | Application only | | `OpenTelemetry.Exporter.Prometheus*` | Prometheus metrics endpoint | Application only | | `OpenTelemetry.Instrumentation.AspNetCore` | Auto-instrument ASP.NET Core requests | Application only | | `OpenTelemetry.Instrumentation.Http` | Auto-instrument HttpClient calls | Application only | | `OpenTelemetry.Instrumentation.SqlClient` | Auto-instrument SQL calls | Application only |

Package Decision Guide

**Before adding ANY OpenTelemetry NuGet package, discuss the trade-off with the user:**

> "You're about to add an OTel NuGet package. Is this an application where you need to > export telemetry to an observability backend (Jaeger, Prometheus, OTLP collector)? > If you're writing a library, you likely need **zero** OTel packages — just use > `System.Diagnostics.ActivitySource` / `System.Diagnostics.Metrics.Meter` and let the > consuming application configure the export pipeline. Do you want to proceed?"

**Library authors**: Add **nothing**. Use only `System.Diagnostics.*` and `ILogger`. The consuming application wires up the SDK and exporters.

**Application authors**: Add `OpenTelemetry.Extensions.Hosting` + the exporters and instrumentation libraries you need. See [sdk-resources-and-logs-reference.md](sdk-resources-and-logs-reference.md) for full setup patterns.

**Never add** `OpenTelemetry.Api` to a library — `System.Diagnostics.*` IS the API.

For SDK setup, resource configuration, exporters, sampling, and logs integration, see [sdk-resources-and-logs-reference.md](sdk-resources-and-logs-reference.md).

Core Principles

Resiliency First

**CRITICAL**: Exceptions in diagnostic/tracing/metrics logic MUST NEVER impact application processing.

  • Assume Activity instances can be null. Always protect against null Activity references except in Activity extension methods (use `activity?.ExtensionMethod()`)
  • Guard all instrumentation code with appropriate null checks

API Surface Awareness

  • Any telemetry emitted becomes part of the public API surface
  • Changes are subject to breaking changes guidelines
  • Telemetry should be emitted by default (users opt-in to collection via OpenTelemetry extensions)
  • Exception: High-cardinality metric dimensions may require explicit opt-in

Standards Compliance

  • Follow Microsoft best practices for [distributed tracing instrumentation](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-instrumentation-walkthroughs)
  • Follow [OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/)
  • Attribute values support: **string, boolean, double (IEEE 754), int64, byte arrays, and homogeneous arrays** of these primitive types. Null/empty values are valid and meaningful per the [OTel AnyValue spec](https://opentelemetry.io/docs/specs/otel/common/#anyvalue) — they MUST be stored and passed to exporters.
  • Attribute **keys** must be non-null, non-empty strings

Traces / Spans (Activities)

ActivitySource Setup

// ✅ CORRECT: Use ActivitySource, not DiagnosticSource
public class MyFeature
{
    // Primary ActivitySource - name typically matches the component or NuGet package name
    private static readonly ActivitySource ActivitySource = new("MyApp.MyComponent", "1.0.0");

    // Specialized ActivitySource for opt-in scenarios
    private static readonly ActivitySource DetailedActivitySource = new("MyApp.MyComponent.Detailed", "1.0.0");
}

**Rules**:

  • Every component defines a primary `ActivitySource` for mainstream activities
  • Name typically matches the component or NuGet package (e.g., `"MyCompany.MyLibrary"`)
  • Version
Read more
Ships withdotnet-skills

A comprehensive AI coding plugin with 30 skills and 5 specialized agents for professional .NET development. Battle-tested patterns from production systems covering C#, Akka.NET, Aspire, EF Core, testing, and performance optimization.

Get the whole plugin