Przejdź do głównej zawartości

Wzorce monitorowania i logowania to gotowe receptury, dzięki którym Claude Code, Codex lub Cursor piszą konfigurację obserwowalności: kod startowy OpenTelemetry, alerty złotych sygnałów i burn-rate dla SLO, routing Alertmanagera, pipeline’y logów z polem trace_id i tail sampling w kolektorze. Każda receptura kończy się automatycznym sprawdzeniem (promtool, amtool albo test konfiguracji), więc nikt nie musi czytać PromQL linijka po linijce.

Ta strona jest dla programistów i tech leadów, którzy odpowiadają za alerty swojej usługi. Wczoraj w nocy API koszyka przez godzinę zwracało błędy 500, a wszystkie dashboardy świeciły na zielono, bo alerty patrzyły na CPU, a nie na odsetek błędów. Jedyny ślad, który by to wyjaśnił, odrzuciło próbkowanie, a logi z tej minuty nie mają trace_id.

Pełną budowę od zera (instrumentacja, stos z kolektorem, dashboardy i akceptacja) opisuje strona monitorowanie i obserwowalność. Tutaj są pojedyncze receptury, po które sięgasz, gdy ten stos już działa.

  • Prompt dla złotych sygnałów, który zamienia czterolinijkową specyfikację w reguły opóźnienia, błędów, ruchu i nasycenia, każdą z testem promtool
  • Prompt, który zamienia cel SLO w reguły nagrywające i parę wielookienkowych alertów burn-rate, razem z testami promtool dowodzącymi, kiedy każdy alert się odpala
  • Prompt do routingu Alertmanagera oraz polecenia amtool, które pokazują, do którego odbiorcy trafia dany alert
  • Prompt do pipeline’u logów, który wynosi trace_id na najwyższy poziom i maskuje dane osobowe, sprawdzony przez --config.test_and_exit
  • Recepturę tail samplingu w kolektorze, która zachowuje każdy ślad z błędem i próbkuje resztę
  • Dwa prompty audytowe tylko do odczytu: jeden szuka antywzorców zmęczenia alertami w regułach Prometheusa lub alarmach CloudWatch, drugi nieograniczonej kardynalności etykiet
  • Prompt migracyjny dla kodu monitorującego, który wciąż używa AWS SDK v2 albo starego pakietu metryk OpenTelemetry

Agenci piszą konfigurację obserwowalności szybko i myląc się w subtelny sposób: nazwa metryki ze starych danych treningowych, etykieta, która eksploduje kardynalnością, stała burn-rate przepisana z innego SLO. Czytanie YAML-a tego nie wyłapie. Wyłapie to walidator i test zachowania. Daj agentowi sprawdzenie razem z zadaniem i poproś, żeby wkleił wynik.

Co pisze agentSprawdzenie składniSprawdzenie zachowania
Reguły nagrywające i alerty Prometheusapromtool check rules rules.ymlpromtool test rules rules_test.yml: syntetyczne serie, „odpala przy X, milczy przy Y”
alertmanager.ymlamtool check-config alertmanager.ymlamtool config routes test --config.file=alertmanager.yml severity=critical wypisuje odbiorcę
Konfiguracja OpenTelemetry Collectoraotelcol-contrib validate --config=collector.yamleksporter debug z verbosity: detailed pokazuje przychodzące spany
Pipeline Logstashabin/logstash -f logstash.conf --config.test_and_exitprzepuść jedną prawdziwą linię logu i obejrzyj zdarzenie wyjściowe
Kod instrumentacjisprawdzenie typów i testy jednostkowenazwy metryk istnieją w Prometheusie: curl -s localhost:9090/api/v1/label/__name__/values

Przeglądasz test zachowania, nie konfigurację. „Alert szybkiego spalania odpala przy 10% błędów i milczy przy 0,3%” to dwie linijki intencji; PromQL pod spodem to zadanie agenta.

Agent, który nie widzi twoich metryk, wymyśla progi i nazwy metryk. Z podłączonymi oficjalnymi serwerami MCP Sentry i Grafany agent czyta prawdziwą listę metryk, p95 z ostatniego tygodnia i stack trace skoku błędów, zanim napisze regułę. Adresy i pakiety są te same w każdym agencie; różni się tylko polecenie.

Okno terminala
# Terminal, repo root. Sentry: hosted server, OAuth on first use (or /mcp in a session)
claude mcp add -s project --transport http sentry https://mcp.sentry.dev/mcp
# Grafana Labs' server from PyPI, read-only; the token file lives outside the repo
claude mcp add -s project grafana \
-e GRAFANA_URL=https://grafana.example.com \
-e 'GRAFANA_SERVICE_ACCOUNT_TOKEN_FILE=${HOME}/.config/grafana/mcp-token' \
-- uvx mcp-grafana --disable-write

Gdy Grafana jest podłączona, poproś agenta, żeby przed zaproponowaniem panelu wypisał istniejące dashboardy i źródła danych; wtedy rozbudowuje to, co już masz, zamiast tworzyć duplikaty. Kontu serwisowemu Grafany nadaj rolę Viewer. GRAFANA_API_KEY jest w mcp-grafana przestarzałe (1.6.0 na PyPI, sprawdzone 2026-09-26); używaj GRAFANA_SERVICE_ACCOUNT_TOKEN albo wariantu _FILE. Omijaj podobnie nazwane pakiety, na przykład @leval/mcp-grafana (port społeczności) czy przestarzały pakiet npm @elastic/mcp-server-elasticsearch; aktualny serwer Elastica opisuje repozytorium elastic/mcp-server-elasticsearch. Zakresy uprawnień, nagłówki tokenów i koszt kontekstu każdego serwera znajdziesz na stronie serwery MCP do obserwowalności.

Skill jest lżejszą opcją, gdy agent ma wiedzieć, jak pisać dobrą konfigurację monitorowania, a nie co właśnie się pali. Repozytorium wshobson/agents Setha Hobsona zawiera w pluginie observability-monitoring skille prometheus-configuration, slo-implementation, grafana-dashboards i distributed-tracing:

Okno terminala
# Any skills-compatible agent (Claude Code, Codex, Cursor, and others)
npx skills add wshobson/agents --skill slo-implementation
# Claude Code, inside a session: the whole plugin
/plugin marketplace add wshobson/agents
/plugin install observability-monitoring@claude-code-workflows

Skill wystarczy do pisania reguł od zera, serwer MCP jest potrzebny do strojenia progów na danych produkcyjnych. Dla skali, stan na 2026-09-26: wshobson/agents miało około 40,0 tys. gwiazdek na GitHubie, a grafana/mcp-grafana około 3,5 tys. Zanim zainstalujesz cudzy skill, przeczytaj go; zobacz instalowanie i zarządzanie skillami.

Jak zamienić specyfikację złotych sygnałów w reguły alertów

Dział zatytułowany „Jak zamienić specyfikację złotych sygnałów w reguły alertów”

Alertuj na to, co odczuwa użytkownik. Z czterech złotych sygnałów (opóźnienie, ruch, błędy i nasycenie) budź dyżurnego przy błędach i opóźnieniu, a nasycenie kieruj do zgłoszenia. Najszybsza droga do rozsądnego pierwszego zestawu reguł to czterolinijkowa specyfikacja zwykłym językiem: agent pisze PromQL i test, a ty przeglądasz specyfikację i wynik testu.

Agenci najczęściej mylą się w regułach opóźnienia i ruchu, więc to na nie patrzysz w wyniku:

# monitoring/rules/checkout-golden-signals.yml (excerpt)
groups:
- name: checkout-golden-signals
rules:
- alert: CheckoutLatencyP95High
expr: |
histogram_quantile(0.95,
sum by (le) (rate(http_server_request_duration_seconds_bucket{job="checkout-api"}[5m]))
) > 0.5
for: 5m
labels: { severity: warning }
annotations:
summary: "checkout-api p95 latency above 500 ms"
runbook_url: "https://runbooks.example.com/checkout-latency"
- alert: CheckoutTrafficDrop
# The floor stops the rule paging every night when traffic is naturally low
expr: |
sum(rate(http_server_request_duration_seconds_count{job="checkout-api"}[5m]))
< 0.5 * sum(rate(http_server_request_duration_seconds_count{job="checkout-api"}[1h] offset 5m))
and
sum(rate(http_server_request_duration_seconds_count{job="checkout-api"}[1h] offset 5m)) > 1
for: 10m
labels: { severity: warning }
annotations:
summary: "checkout-api traffic fell below half of the previous hour"
runbook_url: "https://runbooks.example.com/checkout-traffic"

Statyczna reguła 5% błędów to toporna wersja pary burn-rate z następnej sekcji. Gdy alerty burn-rate już działają, usuń statyczną regułę albo zdegraduj ją do zgłoszenia, żeby jeden incydent nie budził dyżurnego dwa razy.

Alerty burn-rate dla SLO: testowane, a nie brane na wiarę

Dział zatytułowany „Alerty burn-rate dla SLO: testowane, a nie brane na wiarę”

Progi CPU i opóźnienia mówią, że coś jest nie tak. Alert burn-rate mówi, że wydajesz budżet błędów szybciej, niż możesz sobie pozwolić. Wzorzec wielookienkowy z wieloma progami spalania z Google SRE Workbook odpala tylko wtedy, gdy zgadzają się okno długie i krótkie, więc przeczeka jeden zły scrape i szybko się wycisza po naprawie.

Najpierw potwierdź nazwy metryk. Od @opentelemetry/instrumentation-http 0.222.0 (sprawdzone 2026-09-26) usługi Node.js emitują stabilny histogram http.server.request.duration w sekundach, który Prometheus zwykle zapisuje jako http_server_request_duration_seconds_bucket, _count i _sum. Większość poradników i większość danych treningowych modeli wciąż używa http_requests_total albo http_request_duration_seconds. Szczegóły są w sekcji o nazwach metryk HTTP w aktualnym OpenTelemetry.

Reguły nagrywające od agenta powinny wyglądać tak. Każdy alert czyta wtedy gotowy, wyliczony wcześniej odsetek zamiast powtarzać dzielenie:

# monitoring/rules/api-slo.yml (excerpt)
groups:
- name: api-slo-recording
rules:
- record: job:slo_errors:ratio_rate5m
expr: |
sum by (job) (rate(http_server_request_duration_seconds_count{http_response_status_code=~"5.."}[5m]))
/ sum by (job) (rate(http_server_request_duration_seconds_count[5m]))
- record: job:slo_errors:ratio_rate1h
expr: |
sum by (job) (rate(http_server_request_duration_seconds_count{http_response_status_code=~"5.."}[1h]))
/ sum by (job) (rate(http_server_request_duration_seconds_count[1h]))
# ratio_rate30m and ratio_rate6h follow the same shape
- name: api-slo-alerts
rules:
# 99.5% SLO -> budget 0.005. 14.4x burn -> error ratio > 0.072.
# At that rate a 30-day budget is gone in about 2.1 days (30 / 14.4).
- alert: ApiErrorBudgetFastBurn
expr: |
job:slo_errors:ratio_rate1h{job="api"} > (14.4 * 0.005)
and
job:slo_errors:ratio_rate5m{job="api"} > (14.4 * 0.005)
for: 2m
labels: { severity: critical }
annotations:
summary: "api is burning error budget 14.4x faster than the SLO allows"
runbook_url: "https://runbooks.example.com/api-error-budget"

Plik testów dla tych reguł ma kształt pokazany w sekcji o regułach alertów, które testujesz bez czytania. Gdy agent później edytuje regułę, trzymaj plik testów poza jego zasięgiem, żeby „spraw, by test przeszedł” nie znaczyło „osłab test”.

Routing alertów w Alertmanagerze i dowód, że drzewo tras działa

Dział zatytułowany „Routing alertów w Alertmanagerze i dowód, że drzewo tras działa”

Burze alertów zaczynają się w routingu: group_wait: 0s na każdej trasie zamienia jedną awarię klastra w setki powiadomień. Opisz politykę eskalacji zwykłym językiem i niech amtool udowodni wynik.

Okno terminala
# Terminal: the checks you run, or have the agent run and paste
amtool check-config monitoring/alertmanager.yml
amtool config routes test --config.file=monitoring/alertmanager.yml \
--verify.receivers=pagerduty-oncall severity=critical service=checkout

Z --verify.receivers polecenie kończy się kodem niezerowym, gdy zestaw etykiet trafia do innego odbiorcy, więc ta sama linijka działa jako krok CI.

Najcenniejsza zmiana w logowaniu to trace_id w każdej linii logu. Wtedy ze spanu w Grafanie przechodzisz do otaczających go logów jednym kliknięciem. Pipeline’y pisane przez agenta psują się na nazwach pól, dlatego prompt zaczyna się od jednej prawdziwej linii logu.

Sprawdzić trzeba blok korelacji. Ścieżki pól muszą odpowiadać temu, co emituje twój most logów OpenTelemetry albo logger:

filter {
if [message] =~ /^\{/ {
json { source => "message" target => "parsed" }
mutate {
rename => {
"[parsed][trace_id]" => "trace_id"
"[parsed][span_id]" => "span_id"
"[parsed][level]" => "log_level"
}
}
}
if [environment] == "production" and [log_level] == "DEBUG" { drop {} }
}

Jeśli zamiast Elasticsearcha masz Loki, prompt się przenosi: poproś o konfigurację Grafana Alloy albo Promtail, która wyciąga trace_id jako structured metadata, a nie jako etykietę. Etykieta na każdy identyfikator śladu to ta sama eksplozja kardynalności, którą opisuje sekcja o awariach niżej. Stronę aplikacji, czyli ustrukturyzowane i maskowane logowanie z korelacją żądań, opisują wzorce logowania.

Zachowaj każdy ślad z błędem dzięki tail samplingowi

Dział zatytułowany „Zachowaj każdy ślad z błędem dzięki tail samplingowi”

Head sampling decyduje przy pierwszym spanie, zanim ktokolwiek wie, czy żądanie się nie powiodło, więc potrzebny ślad często znika. Tail sampling decyduje po zakończeniu śladu: zachowuje wszystkie błędy i wolne żądania, a resztę próbkuje.

# monitoring/otel-collector.yaml (excerpt)
processors:
tail_sampling:
decision_wait: 30s
policies:
- name: keep-errors
type: status_code
status_code: { status_codes: [ERROR] }
- name: keep-slow
type: latency
latency: { threshold_ms: 1000 }
- name: sample-the-rest
type: probabilistic
probabilistic: { sampling_percentage: 5 }

Instrumentacja usługi bez przestarzałych eksporterów

Dział zatytułowany „Instrumentacja usługi bez przestarzałych eksporterów”

Dashboardy zależą od instrumentacji. Proś wprost o OTLP. Starsza wiedza modeli sięga po @opentelemetry/exporter-jaeger, którego README oznacza pakiet jako przestarzały, ze wsparciem zakończonym w marcu 2024 (npm 2.11.0, sprawdzone 2026-09-26); Jaeger przyjmuje OTLP bezpośrednio.

// src/tracing.js — node --require ./src/tracing.js server.js
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const {
ATTR_SERVICE_VERSION,
ATTR_DEPLOYMENT_ENVIRONMENT_NAME,
} = require('@opentelemetry/semantic-conventions');
const sdk = new NodeSDK({
// service.name comes from OTEL_SERVICE_NAME
resource: resourceFromAttributes({
[ATTR_SERVICE_VERSION]: process.env.SERVICE_VERSION ?? '0.0.0',
[ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: process.env.ENVIRONMENT ?? 'production',
}),
// Reads OTEL_EXPORTER_OTLP_ENDPOINT; OTLP/HTTP is port 4318, gRPC is 4317
traceExporter: new OTLPTraceExporter(),
instrumentations: [getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-fs': { enabled: false },
})],
});
sdk.start();
process.on('SIGTERM', () => sdk.shutdown().finally(() => process.exit(0)));

deployment.environment.name to stabilny atrybut w @opentelemetry/semantic-conventions 1.43.0; starszy deployment.environment, którego używa wiele przykładów, stabilny nie jest. Stos z kolektorem, do którego ten kod eksportuje, opisuje strona monitorowanie i obserwowalność.

Audyt istniejących alertów i metryk agentem tylko do odczytu

Dział zatytułowany „Audyt istniejących alertów i metryk agentem tylko do odczytu”

Większości zespołów nie brakuje alertów; mają niewłaściwe. Audyt to dobre pierwsze zadanie dla agenta, bo nie wymaga prawa zapisu: agent czyta pliki reguł albo eksport alarmów i raportuje.

Sposób uruchomienia audytu zależy od narzędzia:

Uruchom go w trybie headless tylko z narzędziami do odczytu. W CI dodaj flagi izolacji, żeby pull request nie mógł wstrzyknąć do zadania hooków, ustawień ani serwerów MCP:

Okno terminala
claude -p "$(cat prompts/alert-audit.md)" \
--bare --setting-sources "" --strict-mcp-config \
--tools "Read,Grep,Glob" --output-format json > audit.json

--bare nigdy nie czyta danych OAuth ani pęku kluczy, łączy się tylko z serwerami MCP podanymi w wierszu poleceń (od v2.1.286) i uwierzytelnia się przez ANTHROPIC_API_KEY (albo apiKeyHelper przekazany przez --settings), więc czytaj klucz z magazynu sekretów CI. Niech zadanie CI zakończy się błędem, gdy audit.json zawiera ustalenia. Zasady dla agentów w pipeline’ach opisują receptury CI/CD.

Przy kardynalności daj agentowi liczby, zamiast prosić go o zgadywanie. Prometheus sam raportuje najcięższe metryki:

Okno terminala
# Terminal: top metrics by series count, and total head series
curl -s localhost:9090/api/v1/status/tsdb | jq '.data.seriesCountByMetricName[:10]'
curl -s 'localhost:9090/api/v1/query?query=prometheus_tsdb_head_series' | jq '.data.result[0].value[1]'

Wklej oba wyniki do promptu audytowego i poproś o regułę metric_relabel_configs, która usuwa winną etykietę.

Kod monitorujący często ma kilka lat. Dwie migracje wracają stale i obie są na tyle mechaniczne, że poradzi sobie z nimi agent. Pakiet npm aws-sdk (v2) jest w npm oznaczony jako przestarzały z komunikatem, że „has reached end-of-support, and no longer receives updates” (2.1693.0, sprawdzone 2026-09-26). @opentelemetry/metrics zatrzymał się na 0.24.0 i dwa razy zmieniał nazwę; aktualny pakiet to @opentelemetry/sdk-metrics (2.11.0, sprawdzone 2026-09-26), w którym readery metryk przekazujesz do konstruktora MeterProvider.

// src/monitoring/alarms.mjs — the migrated shape
import { CloudWatchClient, PutMetricAlarmCommand } from '@aws-sdk/client-cloudwatch';
import { MeterProvider } from '@opentelemetry/sdk-metrics';
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
const cw = new CloudWatchClient({});
await cw.send(new PutMetricAlarmCommand({
AlarmName: 'checkout-api-high-5xx',
Namespace: 'AWS/ApplicationELB',
MetricName: 'HTTPCode_Target_5XX_Count',
Statistic: 'Sum',
Period: 300,
EvaluationPeriods: 3,
DatapointsToAlarm: 2,
Threshold: 10,
ComparisonOperator: 'GreaterThanThreshold',
TreatMissingData: 'notBreaching',
AlarmActions: [process.env.SNS_TOPIC_ARN],
OKActions: [process.env.SNS_TOPIC_ARN], // without it the alarm never reports recovery
}));
// PrometheusExporter is a MetricReader; it serves /metrics on port 9464 by default
const meterProvider = new MeterProvider({ readers: [new PrometheusExporter()] });
export const meter = meterProvider.getMeter('checkout-api');

Większość pozostałości, na przykład nazwę opcji istniejącą tylko w v2, wyłapie sprawdzanie typów. Wklej agentowi błąd kompilatora, zamiast go opisywać.

Agent pisze konfigurację i uruchamia sprawdzenia; ludzie akceptują intencję. Właściciel usługi akceptuje cel SLO i przypadki testowe („odpala przy 7,2% błędów, milczy przy 0,3%”). Lider dyżurów akceptuje routing, potwierdzony wynikiem amtool. Pull request, który zmienia reguły lub routing bez wyniku testów w opisie, nie jest gotowy do review. Co jeszcze musi udowodnić taki pull request, opisuje pakiet dowodów.

Co się psuje, gdy agenci piszą konfigurację monitorowania i logowania?

Dział zatytułowany „Co się psuje, gdy agenci piszą konfigurację monitorowania i logowania?”
  1. Burza alertów po braku klauzuli for:. Reguła bez for: odpala się po jednym złym scrape’ie. Wyjście: przeszukaj pliki reguł pod kątem alertów z expr i bez for:, dodaj okno i dopisz test promtool z jednopróbkowym skokiem, który musi przejść bez alertu.

  2. Panel lub alert opóźnienia pokazuje NaN. histogram_quantile działa na serii, która nie jest histogramem _bucket, albo w klauzuli by (...) brakuje le. Wyjście: niech agent wypisze prawdziwe nazwy metryk z Prometheusa i przepisze zapytanie na ich podstawie.

  3. Alert nigdy się nie odpala, bo metryka nie istnieje. Reguła używa http_requests_total albo http_request_duration_seconds, a aktualne OpenTelemetry emituje http_server_request_duration_seconds_*. Wyjście: promtool test rules przechodzi na syntetycznych seriach, więc uruchom też raz każde wyrażenie alertu na prawdziwym Prometheusie; pusty wynik oznacza złą nazwę.

  4. Prometheusowi kończy się pamięć albo scrape’y zwalniają. Etykieta dodana przez agenta, często user_id albo surowa ścieżka URL, zwielokrotniła liczbę serii. Wyjście: znajdź metrykę przez /api/v1/status/tsdb, usuń etykietę regułą metric_relabel_configs i popraw instrumentację tak, by etykieta stała się ograniczonym szablonem trasy.

  5. Spany w ogóle nie docierają. Protokół i port eksportera nie pasują do odbiornika: OTLP/HTTP to 4318, OTLP/gRPC to 4317. Wyjście: dodaj w kolektorze eksporter debug z verbosity: detailed i potwierdź, że spany docierają, zanim zaczniesz winić backend.

  6. Logi nie łączą się ze śladami. Pipeline oczekuje trace_id na najwyższym poziomie, a logger je zagnieżdża. Wyjście: zaloguj jedno surowe zdarzenie, daj je agentowi i niech poprawi ścieżki w rename na podstawie tej próbki.

  7. Alarm CloudWatch wygląda na zawieszony w stanie alarmu. Ma AlarmActions, ale nie ma OKActions, więc nikt nie dowiaduje się o powrocie do normy. Wyjście: do każdej akcji alarmu dodaj akcję OK; resztę takich alarmów znajdzie prompt audytowy powyżej.

  8. Alert spadku ruchu budzi co noc albo jeden incydent budzi dwa razy. Względna reguła ruchu bez dolnego progu wolumenu odpala się, ilekroć ruch jest naturalnie niski, a statyczna reguła odsetka błędów obok pary burn-rate budzi dyżurnego dwa razy z powodu tej samej awarii. Wyjście: dodaj dolny próg jak w przykładzie złotych sygnałów i zostaw budzenie przy błędach tylko parze burn-rate.

  9. Progi są wymyślone. Bez dostępu przez MCP do prawdziwych danych agent podaje pewne siebie liczby, które nie pasują do twojego ruchu. Wyjście: podłącz Grafanę tylko do odczytu, niech agent zacytuje p95 i odsetek błędów z ostatniego tygodnia, i ustaw progi na ich podstawie.

Czy ten artykuł Ci pomógł?

Jedno kliknięcie, bez logowania.

wcale bardzo