Skip to content
Back to skills

Set Up Observability

ASecurity

Use when a backend service should emit traces, metrics and trace-correlated logs. Wires app-side OpenTelemetry - SDK started before app code, HTTP and DB auto-instrumentation, use-case spans, RED metrics, OTEL_* env only, flush on shutdown (Hono, Go, FastAPI).

  • 5 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 10, 2026
developmentpythongobashsqlnextjsnodefastapigitapibackend

Works with

  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 3 files and shows the line behind each finding

Scanned October 10, 2026

npx -y skills add VelimirMueller/lab-claude-skills --skill set-up-observability --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Set Up Observability?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Set Up Observability
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/velimirmueller-set-up-observability/badge)](https://www.skillsdirectory.com/skills/velimirmueller-set-up-observability)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: set-up-observability
description: Use when a backend service should emit traces, metrics and trace-correlated logs. Wires app-side OpenTelemetry - SDK started before app code, HTTP and DB auto-instrumentation, use-case spans, RED metrics, OTEL_* env only, flush on shutdown (Hono, Go, FastAPI).
---

# Set Up Observability

Rules and rationale: [otel-patterns.md](otel-patterns.md). Code per track: [otel-tracks.md](otel-tracks.md). One seam, one exporter: [observability.md](../../core/_shared/observability.md). Trace-correlated logs: [logging-contract.md](../../core/_shared/logging-contract.md). Seam paths: [service-layout.md](../_shared/service-layout.md). Env keys: [config.md](../_shared/config.md).

Bootstrap path: [observability.md](../../core/_shared/observability.md) shows `src/instrumentation.ts` as an example; the backend layout below wins — `src/platform/telemetry.ts` (TS), `internal/platform/telemetry/telemetry.go` (Go), `src/svc/platform/telemetry.py` (Python).

## 1. Audit (change nothing)

```bash
cat .claude/stack-profile.md ~/.claude/stack-profile.md 2>/dev/null    # observability.otel, observability.backend, backend.track
grep -rnE "opentelemetry" package.json go.mod pyproject.toml 2>/dev/null
grep -rnE "console\.(log|error|warn)|print\(" --include=*.ts --include=*.go --include=*.py src internal cmd 2>/dev/null | head
grep -n "OTEL_" .env.example 2>/dev/null
ls src/platform/telemetry.ts internal/platform/telemetry src/svc/platform/telemetry.py 2>/dev/null
```

Read the profile first; detect only what it leaves open ([stack-profile.md](../../core/_shared/stack-profile.md)).

## 2. Decide

- `observability.otel: false`: stop. Keep `request_id` logging per the logging contract's "When to deviate" (generate a request id and log it as `request_id`). No OTel SDK.
- No telemetry module and no OTel dependencies: full setup, steps 3 to 7.
- A telemetry module exists but misses auto-instrumentation, route templates, trace fields or shutdown flush: apply the deltas from [otel-tracks.md](otel-tracks.md) in place. Do not rewrite what works.
- Everything present and step 7 passes: report "already in place" and stop.

## 3. Detect track

| `backend.track` | Do |
|---|---|
| `hono`, `go`, `fastapi` | Continue. |
| `nextjs` | Stop. Use [build-nextjs-backend](../build-nextjs-backend/SKILL.md). |
| `supabase` | Stop. Use [set-up-supabase](../set-up-supabase/SKILL.md) for the edge-function telemetry notes. |
| `none` or unset | Run `set-up-stack-profile`, then a `scaffold-*-service` skill. |

Also read `observability.backend` (`signoz` \| `grafana-lgtm` \| `sentry` \| `none`) only to write the exporter env example in step 6. The `OTEL_*` variables are the same for all backends ([observability.md](../../core/_shared/observability.md)).

## 4. Install only what is missing

```bash
pnpm add @opentelemetry/api @opentelemetry/core @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-metrics-otlp-http @opentelemetry/sdk-metrics   # hono
go get go.opentelemetry.io/otel go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk/metric go.opentelemetry.io/contrib/exporters/autoexport go.opentelemetry.io/contrib/propagators/autoprop go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp github.com/exaring/otelpgx   # go
uv add opentelemetry-distro opentelemetry-exporter-otlp opentelemetry-instrumentation-fastapi opentelemetry-instrumentation-psycopg   # fastapi (NOT instrumentation-sqlalchemy, see tracks)
```

Use the profile's package manager. Verify each line in [stack-versions.md](../_shared/stack-versions.md) before you write it.

## 5. Generate the seams

Create from [otel-tracks.md](otel-tracks.md), skipping files that exist:

```
TS      src/platform/telemetry.ts, src/platform/tracer.ts + deltas to logger.ts, main.ts, app.ts, tsdown.config.ts, package.json, vitest.config.ts
Go      internal/platform/telemetry/telemetry.go, internal/transport/httpapi/route.go + deltas to logging.go, main.go, server.go
Python  src/svc/platform/telemetry.py + deltas to main.py, logging.py, app.py, pyproject.toml, tests/conftest.py
```

Paths follow [service-layout.md](../_shared/service-layout.md). `tracer` is the platform seam that owns the OTel SDK.

## 6. Wire

1. **Order.** Telemetry first, then config, logger, DB, app. The SDK patches modules at load; anything imported before it keeps the unpatched original ([otel-patterns.md](otel-patterns.md) rule 1).
2. **Route templates.** TS: `app.use(routeTemplate)` as the first middleware. Go: `routeTag(mux)` first in the chain. Python: the FastAPI instrumentation does it itself.
3. **Logger trace fields.** The logger seam adds `trace_id`/`span_id` from the active span (pino `mixin`, slog `traceHandler`, structlog `add_trace_context`), per [logging-contract.md](../../core/_shared/logging-contract.md).
4. **Shutdown order.** Drain server → close pool → flush telemetry, with a hard timeout so a rollout never hangs.
5. **Tests disable the SDK.** `OTEL_SDK_DISABLED=true` (vitest `test.env`, pytest conftest before any `svc` import; Go: `Setup` is only called from `main`).
6. **`.env.example`** (plus `DEPLOYMENT_ENVIRONMENT` and `OTEL_SERVICE_NAME`, already read by [config.md](../_shared/config.md)):

```bash
OTEL_SERVICE_NAME=svc
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=1.0
OTEL_RESOURCE_ATTRIBUTES=service.version=dev
```

`deployment.environment.name` comes from `DEPLOYMENT_ENVIRONMENT` ([config.md](../_shared/config.md)): in the deploy config, append `deployment.environment.name=$DEPLOYMENT_ENVIRONMENT` to `OTEL_RESOURCE_ATTRIBUTES` — not in `.env.example`.

## 7. Verify

```bash
OTEL_TRACES_EXPORTER=console pnpm dev                            # hono
OTEL_TRACES_EXPORTER=console go run ./cmd/svc                    # go
OTEL_TRACES_EXPORTER=console uv run fastapi run                  # fastapi
```

Curl one route and expect:

- span name TS `GET /notes/:id` with attribute `http.route`; Go `GET /notes/{id}` with `http.route`; Python `GET /notes/{note_id}`;
- DB spans appear when the DB is used — Go: `otelpgx` spans; TS: `pg.query:SELECT postgres` with attribute `db.system.name=postgresql`; Python: psycopg spans with `db.system=postgresql`;
- the structured log line of the same request carries the same `trace_id`;
- send `SIGTERM` right after a request: the spans still appear (flush on shutdown).

Then finish with the four-step Verify in [observability.md](../../core/_shared/observability.md).

## References

- [otel-patterns.md](otel-patterns.md): the rules and the verified pitfalls behind each decision.
- [otel-tracks.md](otel-tracks.md): files for Hono, Go and FastAPI, with wiring deltas and span examples.

Files in this skill

  • SKILL.md6.7 KB
  • otel-patterns.md10.6 KB
  • otel-tracks.md16.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.