Przejdź do głównej zawartości

Konfiguracja obserwowalności z Claude Code

Konfiguracja obserwowalności z Claude Code polega na tym, że agent dodaje do istniejącej usługi tracing OpenTelemetry, logi strukturalne skorelowane ze śladami, reguły alertów Prometheus i dashboardy Grafana, a hooki, reguła deny, subagent weryfikujący i serwer MCP Grafany sprawdzają każdy wygenerowany plik. Nikt nie czyta YAML-a linijka po linijce; dowodem są testy promtool i zapytania na żywo.

Jest druga w nocy i odzywa się pager: „wysoki odsetek błędów na API”. Dashboard pokazuje skok odpowiedzi 5xx, ale bez trace ID, bez korelacji z logami i bez śladu, które wywołanie zewnętrzne pada. Przez 40 minut grepujesz niestrukturalne logi, żeby znaleźć timeout u dostawcy płatności, którego naprawa zajmuje dwie minuty. Ta strona jest dla developera, który odpowiada za taką usługę, i dla tech leada, który zatwierdza jej alerty.

Ta strona opisuje warstwę Claude Code wokół samej pracy: tryb planowania, CLAUDE.md, hooki, reguły uprawnień, subagentów i uruchomienie headless (bez interakcji). Sam stos (kolektor, Loki, Tempo, nazwy metryk i kontrole w CI) opisuje niezależnie od narzędzia strona monitoring i obserwowalność z agentami AI. Obserwowanie samego Claude Code, czyli jego sesji, kosztów i wywołań narzędzi, opisuje strona obserwowalność agentów.

Co zyskujesz, konfigurując obserwowalność z Claude Code

Dział zatytułowany „Co zyskujesz, konfigurując obserwowalność z Claude Code”
  • Prompt dla trybu planowania, który inwentaryzuje usługę, zanim powstanie jakakolwiek instrumentacja.
  • Blok w CLAUDE.md, który utrwala konwencje obserwowalności dla każdej kolejnej sesji.
  • Hook PostToolUse, który po każdej edycji uruchamia promtool i amtool, oraz regułę deny, która trzyma testy alertów poza zasięgiem agenta.
  • Gotowe prompty: OpenTelemetry ze skorelowanymi logami, alerty burn-rate z testami jednostkowymi i sprawdzenie dashboardu przez serwer MCP Grafany.
  • Subagenta weryfikującego i uruchomienie headless, które wytwarzają dowody dołączane do pull requesta.

W jakiej kolejności Claude Code powinien budować obserwowalność?

Dział zatytułowany „W jakiej kolejności Claude Code powinien budować obserwowalność?”

Każda warstwa jest tak dobra jak ta pod nią. Alert na metrykę, której usługa nigdy nie emituje, milczy zawsze, i nic nie zgłasza, że milczy. Buduj w tej kolejności i nie pozwól Claude przeskakiwać etapów.

KrokCo robi Claude CodeMechanizm Claude CodeCo to udowadnia bez czytania
1. MapaInwentaryzuje punkty wejścia, klienty, kolejki i logowanieTryb planowania (tylko odczyt)Tabela inwentaryzacji, którą zatwierdzasz
2. InstrumentacjaDodaje SDK OpenTelemetry i logger strukturalnyKonwencje w CLAUDE.mdTrace ID jednego żądania w kolektorze i w linii logu
3. AlertyPisze reguły i testy promtoolHook PostToolUse, reguła deny na testyZielone promtool test rules z przypadkami „musi odpalić” i „musi milczeć”
4. DashboardPisze JSON dashboarduSerwer MCP Grafany, tylko odczytTabela, w której każdy panel zwraca serie
5. DowodyPonownie uruchamia wszystkie kontrole i raportujeSubagent weryfikujący, claude -pRaport JSON dołączony do pull requesta

Zmapuj usługę, zanim Claude napisze jakąkolwiek instrumentację

Dział zatytułowany „Zmapuj usługę, zanim Claude napisze jakąkolwiek instrumentację”

Zacznij w trybie planowania: Claude czyta kod i proponuje plan, niczego nie edytując. Oceniasz inwentaryzację, czyli 20 linijek zamiast diffu na 600.

Okno terminala
# Terminal, w katalogu głównym repozytorium
claude --permission-mode plan

Najważniejszy jest wiersz 6. Automatyczna instrumentacja obejmuje standardowe serwery HTTP i sterowniki baz danych, a pomija konsumentów kolejek i ręcznie pisane klienty. W tej luce ślady później urywają się na granicy usług.

Każda kolejna sesja, także ta, która za pół roku poprawi alert, powinna trzymać się tych samych zasad. Zapisz je w projektowym CLAUDE.md, a nie w każdym prompcie.

## Observability conventions
- Tracing: OpenTelemetry via src/instrumentation.ts, loaded with node --require before the app.
Build resources with resourceFromAttributes(); the Resource class is gone in resources 2.x.
- Logging: pino only. JSON in production. Every entry carries trace_id and span_id from the
active span. Redact password, token, secret, authorization, cookie and card fields.
- Metric names: read them from the running Prometheus before writing any query
(curl -s localhost:9090/api/v1/label/__name__/values). Never write a metric name from memory.
- Alerts live in observability/alerts.yml. observability/alerts_test.yml is the oracle:
never edit it. If a test fails, fix the rule or explain why the test is wrong.
- Every alert has severity, summary and runbook_url labels or annotations.
- Dashboards live in observability/dashboards/*.json and use a $service template variable.

Po zatwierdzeniu planu przełącz się na zwykły tryb i uruchom prompt startowy. Przypina on aktualne API OpenTelemetry, bo modele uczone na starszych tutorialach sięgają po usuniętą klasę Resource. Wersje pakietów aktualne na 2026-09-26 (odczytane przez npm view): @opentelemetry/sdk-node 0.222.0, @opentelemetry/auto-instrumentations-node 0.80.0, @opentelemetry/resources 2.11.0 i pino 10.3.1.

Krok 6 sprawdź sam na prawdziwym kolektorze, zamiast ufać transkryptowi. Jednorazowy kolektor z eksporterem debug wypisuje każdy odebrany span:

# otel-debug.yaml: lokalny kolektor, który tylko wypisuje to, co odebrał
receivers:
otlp:
protocols:
grpc: { endpoint: 0.0.0.0:4317 }
http: { endpoint: 0.0.0.0:4318 }
exporters:
debug: { verbosity: detailed }
service:
pipelines:
traces: { receivers: [otlp], exporters: [debug] }
Okno terminala
# Terminal 1: uruchom kolektor
docker run --rm -p 4317:4317 -p 4318:4318 \
-v "$PWD/otel-debug.yaml:/etc/otelcol-contrib/config.yaml" otel/opentelemetry-collector-contrib
# Terminal 2: wyślij żądanie, potem wyszukaj w wyjściu kolektora trace ID wypisane przez Claude
curl -s localhost:3000/health

Instrumentacja jest udowodniona, gdy ten sam trace ID pojawia się w wyjściu kolektora i w jednej linii logu JSON. Jeśli pojawia się tylko w jednym miejscu, korelacja nie działa i żaden późniejszy krok tego nie naprawi.

Niech każda edycja alertu sama się sprawdza dzięki hookowi

Dział zatytułowany „Niech każda edycja alertu sama się sprawdza dzięki hookowi”

Reguły alertów to małe programy, a promtool test rules to narzędzie, które je testuje. Specyfika Claude Code polega na tym, że kontrola dzieje się automatycznie: hook PostToolUse uruchamia walidator po każdej edycji w observability/, a kod wyjścia 2 zwraca błąd prosto do Claude, który poprawia go w następnym kroku. Mechanikę opisuje strona automatyzacja z hookami.

#!/usr/bin/env bash
# .claude/hooks/check-observability.sh (PostToolUse, matcher "Edit|Write")
set -uo pipefail
file=$(jq -r '.tool_input.file_path // empty')
dir=$CLAUDE_PROJECT_DIR/observability
case "$file" in
"$dir"/alerts*.yml)
if ! out=$(cd "$dir" && promtool check rules alerts.yml 2>&1 && promtool test rules alerts_test.yml 2>&1); then
echo "Alert rules fail their checks. Fix alerts.yml, not the test file:" >&2
tail -n 30 <<<"$out" >&2
exit 2
fi ;;
"$dir"/alertmanager.yml)
if ! out=$(amtool check-config "$file" 2>&1); then
echo "Alertmanager config is invalid:" >&2; tail -n 20 <<<"$out" >&2; exit 2
fi ;;
"$dir"/dashboards/*.json)
jq empty "$file" 2>/dev/null || { echo "Dashboard JSON does not parse: $file" >&2; exit 2; } ;;
esac
exit 0

Zarejestruj hook i regułę deny w .claude/settings.json. Reguła deny powstrzymuje agenta, któremu kazano „sprawić, by testy przechodziły”, przed osłabieniem asercji zamiast poprawienia reguły; uzasadnienie znajdziesz na stronie ochrona wyroczni testowej.

{
"permissions": {
"deny": ["Edit(./observability/alerts_test.yml)"]
},
"hooks": {
"PostToolUse": [
{ "matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check-observability.sh", "args": [], "timeout": 60 }] }
]
}
}

alerts_test.yml pisze człowiek albo Claude szkicuje go w osobnej sesji, zanim zacznie obowiązywać reguła deny, a tech lead go przegląda. Plik jest krótki: kilka syntetycznych serii i momenty, w których alert musi i nie może odpalić. To w nim zapisana jest intencja, więc to jedyny plik, który warto przeczytać.

Spodziewaj się tu jednej pułapki z nazwami. W wersji 0.222.0 pakietu @opentelemetry/instrumentation-http (sprawdzone 2026-09-26) instrumentacja HTTP dla Node emituje wyłącznie stabilny histogram http.server.request.duration, w sekundach. Większość danych treningowych używa starszego http.server.duration albo http_requests_total. Właśnie dlatego istnieje krok 1 promptu; szczegóły opisuje strona monitoring i obserwowalność z agentami AI.

Sprawdź każdy panel dashboardu przez serwer MCP Grafany

Dział zatytułowany „Sprawdź każdy panel dashboardu przez serwer MCP Grafany”

Dashboard z błędną nazwą metryki wyświetla „No data”, co wygląda jak spokojny system. Daj Claude dostęp do Grafany tylko do odczytu i każ mu uruchomić zapytanie każdego panelu, zamiast klikać po nich samodzielnie. Dodaj serwer w zakresie projektu, żeby ładował się tylko w tym repozytorium. mcp-grafana 1.6.0 z PyPI to oficjalny serwer Grafana Labs (sprawdzone 2026-09-26); szerszy katalog jest na stronie serwery MCP do obserwowalności.

Okno terminala
# Terminal: token konta serwisowego z rolą Viewer, zapisy wyłączone
claude mcp add grafana --scope project \
-e GRAFANA_URL=https://grafana.example.com \
-e 'GRAFANA_SERVICE_ACCOUNT_TOKEN=${GRAFANA_SERVICE_ACCOUNT_TOKEN}' \
-- uvx mcp-grafana --disable-write

--scope project zapisuje .mcp.json, który trafia do repozytorium. Pojedyncze cudzysłowy są tu istotne: zapisują dosłowne ${GRAFANA_SERVICE_ACCOUNT_TOKEN}, które Claude Code przy starcie rozwija ze środowiska każdego developera. Przy podwójnych cudzysłowach powłoka najpierw podstawi token i trafi on jawnym tekstem do commitowanego pliku.

Sesja, która napisała konfiguracje, słabo nadaje się do ich oceny. Własny subagent bez narzędzi edycji uruchamia wszystkie kontrole od nowa, w czystym kontekście, i raportuje wynik. Zapisz go jako .claude/agents/observability-verifier.md:

---
name: observability-verifier
description: Verifies observability changes. Use before opening a pull request that touches observability/, src/instrumentation.ts or src/logger.ts.
tools: Read, Grep, Glob, Bash
---
You verify, you never edit. Run and report, each with its exit code:
1. promtool check rules and promtool test rules in observability/.
2. amtool check-config observability/alertmanager.yml.
3. jq empty on every observability/dashboards/*.json.
4. A grep for console.log/warn/error under src/ (expect zero outside tests).
5. A grep for logger calls that pass req, req.body, req.headers or a whole user object.
6. git diff --exit-code origin/HEAD -- observability/alerts_test.yml (expect no diff).
Finish with a PASS or FAIL line per check and nothing else.

Ten sam raport uzyskasz bez sesji interaktywnej: uruchom go w trybie headless i dołącz JSON do pull requesta. dontAsk odrzuca wszystko, czego nie dopuszczają twoje reguły uprawnień, więc przebieg nie zboczy w stronę edycji.

Okno terminala
# Terminal, w katalogu głównym repozytorium (nie w jobie CI z sekretami produkcyjnymi)
claude -p "Use the observability-verifier subagent on this branch, wait for it to finish, and print its report." \
--permission-mode dontAsk \
--allowedTools "Bash(promtool *)" "Bash(amtool *)" "Bash(jq *)" "Bash(grep *)" "Bash(git diff *)" \
--output-format json > observability-evidence.json

Kontrole deterministyczne (promtool, amtool) powinny też działać w CI jako wymagane kroki; strona międzynarzędziowa ma gotowy job CI dla testów alertów. Subagent dokłada oceny, których linter nie zrobi, na przykład wywołanie loggera, przez które wycieka treść żądania.

Kto zatwierdza obserwowalność zbudowaną przez Claude Code?

Dział zatytułowany „Kto zatwierdza obserwowalność zbudowaną przez Claude Code?”

Właściciel usługi zatwierdza na podstawie dowodów; tech lead odpowiada za progi i routing. Żaden z nich nie czyta wygenerowanych konfiguracji od deski do deski. Pull request zawiera:

  • Zatwierdzoną inwentaryzację z trybu planowania, łącznie z wierszem ścieżek, które pomija automatyczna instrumentacja.
  • Jeden trace ID widoczny w wyjściu kolektora i w linii logu JSON.
  • Raport observability-evidence.json z każdą kontrolą na PASS.
  • Tabelę paneli z promptu dashboardu, bez pustych paneli.
  • Diff, który nie dotyka alerts_test.yml, albo osobny, przejrzany commit, który go zmienia.

Tech lead czyta alerts_test.yml, cel SLO i trasy Alertmanagera, bo to one kodują intencję: co uznajemy za awarię i kogo budzimy.

Claude Code eksportuje własne metryki i zdarzenia OpenTelemetry. W wersji 2.1.283 nazwy metryk obejmują claude_code.session.count, claude_code.token.usage, claude_code.cost.usage, claude_code.lines_of_code.count, claude_code.commit.count, claude_code.pull_request.count i claude_code.code_edit_tool.decision. Żeby sprawdzić, czy eksport działa na twojej maszynie, najpierw wypisz metryki w terminalu:

Okno terminala
# Terminal: punkt danych session.count powinien pojawić się po około 10 sekundach
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=10000
claude

Następnie zmień OTEL_METRICS_EXPORTER na otlp i ustaw OTEL_EXPORTER_OTLP_PROTOCOL oraz OTEL_EXPORTER_OTLP_ENDPOINT tak, by wskazywały twój kolektor. Zmienna nazywa się CLAUDE_CODE_ENABLE_TELEMETRY; CLAUDE_CODE_TELEMETRY nie jest odczytywana (sprawdzone na 2.1.283). Wdrożenie dla całego zespołu przez ustawienia zarządzane, łączenie sesji z pull requestami i dashboard kosztu na zmianę opisuje strona obserwowalność agentów. Kontrolę wydatków opisuje kontrola kosztów.

Co się psuje, gdy Claude Code buduje obserwowalność?

Dział zatytułowany „Co się psuje, gdy Claude Code buduje obserwowalność?”

Zapytania i alerty używają nazw metryk, które nie istnieją. Panele pokazują „No data”, a promtool przechodzi, bo serie testowe używają tych samych zmyślonych nazw. Naprawa: wklej do sesji wynik curl -s localhost:9090/api/v1/label/__name__/values | jq -r '.data[]' | grep '^http_server' i poproś Claude o przepisanie każdego zapytania i serii testowej w observability/ na te nazwy, z listą wszystkich zmian.

Hook nigdy się nie uruchamia. Claude edytuje alerts.yml i nic się nie dzieje. Otwórz /hooks w sesji, żeby zobaczyć, które hooki się załadowały i z którego pliku ustawień. Typowe przyczyny to skrypt bez bitu wykonywalności, brak promtool w PATH albo exit 1 tam, gdzie powinno być exit 2: tylko kod 2 zwraca wynik do Claude.

Claude obchodzi chroniony plik testów. Gdy edycja jest zablokowana, może skopiować testy do nowego pliku albo poluzować regułę tak, że stare testy przechodzą trywialnie. Naprawa: zapytaj „List every file you created or changed under observability/ and explain each change to alerts.yml in terms of which test it fixed.” Odrzuć każdą zmianę progów, której tech lead nie zatwierdził. Reguła deny obejmuje tylko narzędzia edycji plików: polecenie Bash, takie jak sed -i albo cp, nadal może nadpisać alerts_test.yml, dlatego kontrola 6 subagenta weryfikującego porównuje ten plik z gałęzią bazową.

Po migracji logowania rośnie wolumen albo koszt logów. Linie JSON są dłuższe, a health check logujący przy każdej próbie mnoży ich liczbę. Poproś: „Drop logging for GET /health and GET /ready, sample other 2xx request logs at 10%, and keep every warn and error. Show the change in log lines per minute on a local load run of 60 seconds.”

W logach pojawiają się dane osobowe. Logger zapisuje całe obiekty żądań w miejscach wskazanych przez inwentaryzację. Naprawa: uruchom kontrolę 5 subagenta weryfikującego, a potem poproś Claude o zastąpienie każdego wskazanego wywołania jawną listą pól i o rozszerzenie ścieżek redakcji. Logi już wysłane traktuj jako incydent w procesie ochrony danych, a nie jako poprawkę w kodzie.

Ślady urywają się na kolejce albo własnym kliencie. Automatyczna instrumentacja nie objęła wiersza 6 inwentaryzacji. Poproś: „For each consumer and client in row 6, show where the traceparent is injected on send and extracted on receive, add what is missing, and prove it with one trace that spans producer and consumer in the collector output.”