otel-instrumentation

Expert guidance for emitting high-quality, cost-efficient OpenTelemetry telemetry. Use when instrumenting applications with traces, metrics, or logs. Triggers on requests for observability, telemetry, tracing, metrics collection, logging integration, or OTel setup.

OpenTelemetry Instrumentation Guide

Expert guidance for implementing high-quality, cost-efficient OpenTelemetry telemetry.

Rules

RuleDescription
telemetryEntrypoint - signal types, correlation, and navigation
resolve-valuesResolving configuration values from the codebase
resourcesResource attributes - service identity and environment
k8sKubernetes deployment - downward API, pod spec
spansSpans - naming, kind, status, and hygiene
logsLogs - structured logging, severity, trace correlation
metricsMetrics - instrument types, naming, units, cardinality
sensitive-dataSensitive data - PII prevention, sanitization, redaction
validationTelemetry validation - post-deployment verification checklist
nodejsNode.js instrumentation setup
goGo instrumentation setup
pythonPython instrumentation setup
javaJava instrumentation setup
scalaScala instrumentation setup
dotnet.NET instrumentation setup
rubyRuby instrumentation setup
phpPHP instrumentation setup
browserBrowser instrumentation setup
nextjsNext.js full-stack instrumentation (App Router)

Official documentation

Key principles

Signal density over volume

Every telemetry item should serve one of three purposes:

  • Detect - Help identify that something is wrong
  • Localize - Help pinpoint where the problem is
  • Explain - Help understand why it happened

If it doesn't serve one of these purposes, don't emit it.

Sample in the pipeline, not the SDK

Use the AlwaysOn sampler (the default) in every SDK. Do not configure SDK-side samplers — they make irreversible decisions before the outcome of a request is known. Defer all sampling to the Collector, where policies can be changed centrally without redeploying applications.

SDK (AlwaysOn)  →  Collector (sampling)  →  Backend (retention)
     ↓                    ↓                       ↓
  All spans         Head or tail            Storage policies
  exported          sampling applied

Quick reference

Use CaseRule
Node.js backendnodejs
Go backendgo
Python backendpython
Java backendjava
Scala backendscala
.NET backenddotnet
Ruby backendruby
PHP backendphp
Browser frontendbrowser
Next.js (App Router)nextjs
Kubernetes pod speck8s
Resolve config valuesresolve-values
Resource attributesresources
Writing metricsmetrics
Cardinality managementmetrics
Span naming, kind, statusspans
Writing logslogs
Sensitive data / PIIsensitive-data
Verify telemetry reaches the backendvalidation
Signal overviewtelemetry