Skip to main content
skill CX Codex

opentelemetry · grafana — Claude Code skill: ship traces and metrics to Grafana

A skill that walks you through instrumenting an app with OpenTelemetry and sending metrics, logs and traces to Grafana Cloud or self-hosted Mimir, Loki and Tempo.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add grafana/skills --skill opentelemetry -a claude-code
Open on GitHub

What opentelemetry does

The skill covers the whole path: your app speaks OTLP, Alloy or a direct exporter sits in between, and the far end is Grafana Cloud with Mimir for metrics, Loki for logs, Tempo for traces and Pyroscope for profiles. Auto-instrumentation is spelled out per language — Go, Java through the Grafana JVM agent, Python with opentelemetry-instrument, Node.js, .NET — plus Beyla on eBPF when you would rather not touch the code.

Auth against the Grafana Cloud OTLP gateway gets its own section: a numeric instance ID and an API token carrying MetricsPublisher, LogsPublisher and TracesPublisher roles are joined into a Basic header with base64. Configuration runs on OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_PROTOCOL, OTEL_EXPORTER_OTLP_HEADERS and OTEL_RESOURCE_ATTRIBUTES. There is a curl smoke test too — a 400 on an empty body means the credentials work, while 401 or 404 points at the ID, the token roles or the URL.

On Kubernetes the skill describes the Operator with instrumentation.opentelemetry.io/inject-java and sibling annotations, and for collection it hands you Alloy and OTel Collector configs. Sampling splits into head and tail: head is cheap but can drop rare errors, tail decides after the full trace and needs a tail_sampling processor in the collector. When spans never reach Explore, check OTEL_EXPORTER_OTLP_PROTOCOL against the transport first — the Cloud gateway wants http/protobuf, a local Alloy wants grpc.

What it helps with

  • instrument a service and see its traces in Tempo
  • build the Basic auth header from an instance ID and API token
  • migrate a service off Jaeger, Datadog or New Relic onto OTLP
  • pick between head and tail sampling
  • debug why spans never show up in Explore

Example prompts for the agent

  • Auto-instrument my Java app and send traces to Grafana Cloud
  • What env vars do I set for the OTLP endpoint?
  • Set up tail sampling in Alloy so errors are always kept

How to install opentelemetry

1Skills CLI (Vercel)

npx skills add grafana/skills --skill opentelemetry -a claude-code

2Manually: put the files in place

~/.claude/skills/opentelemetry/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/opentelemetry/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about opentelemetry

How do I install opentelemetry in Claude?

Run npx skills add grafana/skills --skill opentelemetry -a claude-code. The skill lands in ~/.claude/skills/opentelemetry/SKILL.md.

What does the opentelemetry skill do?

It guides you through instrumenting an app with OpenTelemetry and shipping metrics, logs and traces to Grafana Cloud or self-hosted Mimir, Loki, Tempo and Pyroscope. It includes examples for Go, Java, Python, Node.js and .NET, Alloy and OTel Collector configs, and the Kubernetes Operator install.

Why are my spans missing from Explore?

Usually the protocol does not match the transport: the Grafana Cloud gateway takes http/protobuf, a local Alloy takes grpc. Also confirm the endpoint ends in /otlp and the token carries the publisher roles.

Source text

SKILL.md · Apache-2.0
---
name: opentelemetry
license: Apache-2.0
description: Instrument any app with OpenTelemetry and ship metrics / logs / traces to Grafana Cloud or self-hosted Mimir / Loki / Tempo / Pyroscope. Covers SDK auto-instrumentation for Go, Java (Grafana JVM agent), Python (`opentelemetry-instrument`), Node.js, .NET (`Grafana.OpenTelemetry`), Beyla eBPF for zero-code; Grafana Cloud OTLP gateway + Basic-auth (instanceID + API key, base64); env-var config (`OTEL_EXPORTER_OTLP_*`, `OTEL_RESOURCE_ATTRIBUTES`); Alloy / OTel-Collector pipelines; Kubernetes Operator inject-annotations; and head + tail sampling. Use when instrumenting a service, pointing OTLP at Grafana Cloud, switching from Jaeger / Datadog / New Relic, choosing head- vs tail-sampling, or debugging "spans aren't showing in Explore" — even when the user says "auto-instrument my Java app", "send traces to Grafana", "what env vars do I set", "OTLP endpoint", or "Operator inject" without naming OpenTelemetry.
---

# OpenTelemetry with Grafana

> **Docs**: https://grafana.com/docs/opentelemetry/

Vendor-neutral instrumentation pipeline. Apps speak OTLP → Alloy (or direct) → Grafana Cloud (Mimir / Loki / Tempo / Pyroscope).

## Backends

| Signal | Backend |
|--------|---------|
| Metrics | Grafana Mimir |
| Logs | Grafana Loki |
| Traces | Grafana Tempo |
| Profiles | Grafana Pyroscope |

## Prerequisites

- Grafana Cloud stack OR self-hosted Mimir / Loki / Tempo
- Cloud OTLP endpoint: `https://otlp-gateway-<region>.grafana.net/otlp`
- Basic-auth credentials: numeric instance ID + API token with `MetricsPublisher` + `LogsPublisher` + `TracesPublisher`
- An app to instrument

## Common Workflows

### 1. Authenticate to the Grafana Cloud OTLP endpoint

```bash
# 1. Build the auth header
INSTANCE_ID=123456
API_KEY="glc_eyJ..."
export OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-us-east-0.grafana.net/otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic $(echo -n "${INSTANCE_ID}:${API_KEY}" | base64)"
export OTEL_RESOURCE_ATTRIBUTES="service.name=myapp,service.namespace=myteam,deployment.environment=prod"

# 2. Smoke-test creds with a curl POST against the OTLP traces endpoint (empty body)
curl -s -o /dev/null -w "%{http_code}\n" \
  -X POST -H "Content-Type: application/x-protobuf" \
  -H "Authorization: Basic $(echo -n "${INSTANCE_ID}:${API_KEY}" | base64)" \
  "$OTEL_EXPORTER_OTLP_ENDPOINT/v1/traces" --data-binary '\n'
# Expect 400 (malformed payload) — NOT 401 (auth) or 404 (wrong endpoint).
```

### 2. Auto-instrument a Java app + verify

```bash
# 1. Download the Grafana JVM agent (single jar)
curl -sLO https://github.com/grafana/grafana-opentelemetry-java/releases/latest/download/grafana-opentelemetry-java.jar

# 2. Run with the agent + env from step 1
java -javaagent:./grafana-opentelemetry-java.jar -jar myapp.jar

# 3. Generate traffic, then verify in Grafana → Explore → Tempo:
#    TraceQL: { resource.service.name = "myapp" }
#    Expect spans within ~30s. Also verify metrics:
#    PromQL: count by (service_name)({service_name="myapp"})
```

### 3. Auto-instrument a Python app

```bash
pip install "opentelemetry-distro[otlp]"
opentelemetry-bootstrap -a install

# Same env vars as step 1, then:
opentelemetry-instrument python app.py

# Verify the same way — Explore → Traces filter service.name=myapp.
```

### 4. Add Alloy as a buffering / sampling collector

```bash
# Application points at local Alloy (gRPC fastest)
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc

# Alloy environment for forwarding to Cloud
export GRAFANA_CLOUD_OTLP_ENDPOINT=https://otlp-gateway-prod-us-east-0.grafana.net/otlp
export GRAFANA_CLOUD_INSTANCE_ID=$INSTANCE_ID
export GRAFANA_CLOUD_API_KEY=$API_KEY
alloy run /etc/alloy/config.alloy

# Verify Alloy received and forwarded
curl -s http://localhost:12345/metrics | grep otelcol_exporter_sent_spans
```

Full Alloy config + tail-sampling block + OTel Collector YAML + K8s Operator install: [`references/collector-config.md`](references/collector-config.md).

SDK-by-language details (Go full code, Node manual setup, .NET ASP.NET Core, all the env-var quirks): [`references/instrumentation.md`](references/instrumentation.md).

### 5. Kubernetes — auto-inject via the Operator

```yaml
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata: { name: my-instrumentation }
spec:
  exporter: { endpoint: http://otelcol:4317 }
  propagators: [tracecontext, baggage]
  java:
    image: us-docker.pkg.dev/grafanalabs-global/docker-grafana-opentelemetry-java-prod/grafana-opentelemetry-java:2.3.0-beta.1
  nodejs: {}
  python: {}
```

Then annotate pods:

```yaml
metadata:
  annotations:
    instrumentation.opentelemetry.io/inject-java: "true"
    # or: inject-nodejs, inject-python, inject-dotnet
```

```bash
# Verify the operator injected the agent
kubectl describe pod <pod> | grep -A2 'opentelemetry-auto-instrumentation'
# Then run the same Grafana Explore checks.
```

## Sampling — when to pick which

```bash
# Head sampling (cheap, decided at start; may lose rare errors)
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1   # 10%
```

Tail sampling (decides after seeing the whole trace — keep errors + sample the rest) requires an Alloy / OTel-Collector `tail_sampling` processor; full block in [`references/collector-config.md`](references/collector-config.md).

## Key environment variables

| Variable | Example |
|----------|---------|
| `OTEL_EXPORTER_OTLP_ENDPOINT` | `https://otlp-gateway-prod-us-east-0.grafana.net/otlp` |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `grpc` or `http/protobuf` |
| `OTEL_EXPORTER_OTLP_HEADERS` | `Authorization=Basic <base64>` |
| `OTEL_RESOURCE_ATTRIBUTES` | `service.name=app,service.namespace=team,deployment.environment=prod` |
| `OTEL_SERVICE_NAME` | shorthand for `service.name` |
| `OTEL_TRACES_SAMPLER` / `_ARG` | `parentbased_traceidratio` / `0.1` |

## Troubleshooting

- 401 from OTLP gateway → instance ID is not numeric, or API key missing publisher roles
- 404 → endpoint URL wrong (must end with `/otlp`)
- Spans missing → check `OTEL_EXPORTER_OTLP_PROTOCOL` matches transport (Cloud OTLP gateway = `http/protobuf`, Alloy local = `grpc`)
- Node.js auto-instrumentation broken after bundling → bundlers like `@vercel/ncc` defeat the require hooks
- Python under Gunicorn / uWSGI shows no spans → reinit OTel providers in a post-fork hook

## Resources

- [Grafana OTel docs](https://grafana.com/docs/opentelemetry/)
- [Grafana Cloud OTLP](https://grafana.com/docs/grafana-cloud/send-data/otlp/)
- [Grafana JVM agent](https://github.com/grafana/grafana-opentelemetry-java)
- [Grafana .NET SDK](https://github.com/grafana/grafana-opentelemetry-dotnet)
- [OTel Operator](https://opentelemetry.io/docs/kubernetes/operator/)

© grafana · Apache-2.0 · grafana/skills

Similar skills

Everything for DevOps and infrastructure →

opentelemetry by other authors comes first.

opentelemetry codewithmukesh Configures OpenTelemetry traces, metrics, and logs in .NET 10 applications using OTLP export and IMeterFactory. CX Codex +1 2,800installs opentelemetry devops-skills A skill that wires OpenTelemetry into your services so traces, metrics and logs share one format and one backend. CX Codex +1 339installs opentelemetry Claude MPM Team A skill with OpenTelemetry patterns: traces, metrics, logs, context propagation and Collector pipelines. Useful when a service needs instrumenting instead of guesswork. CX Codex +1 635installs opentelemetry-net-instrumentation Aaronontheweb A skill that guides OpenTelemetry instrumentation in .NET code: traces, metrics and logs. Useful when you add telemetry to a library or an app. CX Codex +1 408installs loki-logging devops-skills A skill that walks your agent through Grafana Loki, Promtail and LogQL setup without leaving the editor. CX Codex +1 330installs groundcover-cli paymog A skill that drives the groundcover Go CLI from your agent: pull logs, traces, metrics and k8s events, and manage monitors or silences. CX Codex +1 8,900installs golang-observability-opentelemetry Claude MPM Team A skill for instrumenting Go services: OpenTelemetry for distributed tracing, Prometheus for metrics, slog for structured logging. CX Codex +1 409installs monitor-setup Seth Hobson A slash command that scaffolds Prometheus metrics, Grafana dashboards, distributed tracing and log aggregation for your service. CX Codex ★ 41,729repo stars monitoring-observability ahmedasmar A skill for building monitoring and observability: metrics strategy, alerts, dashboards, SLOs and incident troubleshooting. CX Codex +1 493installs

From the same set47

dashboarding This skill writes and edits Grafana dashboard JSON, then pushes it through the HTTP API. Useful when panels should live in code instead of being clicked together in the UI. CX Codex +1 8,500installs promql Writes and validates PromQL against Prometheus, Mimir and Grafana Cloud Metrics. Useful when a p95 looks wrong or a query drags. CX Codex +1 8,000installs loki Grafana's loki skill gives your coding agent a LogQL reference and Loki setup notes. It covers stream selectors, parsers, metric queries, ingestion through Alloy, Promtail and Fluent Bit. CX Codex +1 7,500installs loki-label-analyzer Walks through a Grafana Loki label schema: where cardinality grows, which labels slow queries down, and what to do with them. CX Codex +1 6,300installs grafana-oss A skill that walks your agent through provisioning Grafana OSS dashboards and data sources from YAML, writing panel JSON, and verifying each step over the API. CX Codex +1 5,600installs prometheus PromQL reference, Prometheus alerting rules, and Alertmanager routing patterns. Guides AI agents in writing metrics queries and recording rules. CX Codex +1 5,200installs alerting-irm Configures Grafana Alerting, IRM, and SLOs from rules and routing to on-call schedules. Useful for YAML or API-based alert setup and debugging. CX Codex +1 5,100installs assistant-mcp Connects AI coding agents to Grafana Cloud via the mcp-grafana server. Useful for running metric queries, listing dashboards, and checking alerts in chat. CX Codex +1 5,000installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor