Wzorce Monitorowania i Logowania
Twoje API zwraca losowe błędy 500. Pulpity Grafany świecą na zielono, logi błędów nie pokrywają się ze spanami, a Twój PM chce oszacowania czasu. Bolesna prawda: konfiguracja obserwowalności jest drobiazgowa, łatwo ją źle skopiować, a ten jeden ślad, którego potrzebujesz, został odrzucony przez próbkowanie godzinę temu.
Ta receptura pokazuje, jak użyć Cursor, Claude Code i Codex do wygenerowania instrumentacji i konfiguracji, która wyłapuje te awarie — oraz jak połączyć AI bezpośrednio z Grafaną i Sentry, by mogło czytać telemetrię na żywo w trakcie debugowania.
Co Z Tego Wyniesiesz
Dział zatytułowany „Co Z Tego Wyniesiesz”- Gotowy do wklejenia prompt, który automatycznie instrumentuje usługę Express lub FastAPI za pomocą OpenTelemetry i eksportuje OTLP do Twojego kolektora
- Prompty generujące reguły nagrywania Prometheus, alerty burn-rate dla SLO oraz drzewo routingu AlertManagera, które możesz przejrzeć linijka po linijce
- Prompt do pipeline’u Logstash, który parsuje logi JSON, redaguje PII i koreluje
trace_id, dzięki czemu logi linkują z powrotem do śladów - Konfiguracja MCP dla Grafany i Sentry, która pozwala agentowi odpytywać Twoje prawdziwe pulpity i issues, zamiast zgadywać
- Tryby awarii, które gryzą na produkcji — eksplozje kardynalności, gubione spany, próbkowanie ukrywające ślad, którego potrzebujesz
Najpierw Podłącz Serwery MCP do Obserwowalności
Dział zatytułowany „Najpierw Podłącz Serwery MCP do Obserwowalności”Zanim wygenerujesz konfigurację, daj agentowi wgląd w telemetrię na żywo. Z podłączonymi serwerami MCP Grafany i Sentry model może czytać pulpity, odpytywać źródła danych i wyciągać stosy wywołań — więc jego sugestie opierają się na Twoich rzeczywistych danych, a nie na ogólnym szablonie.
Dodaj do .cursor/mcp.json. Oficjalny serwer Sentry jest zdalny (hostowany); Grafana dostarcza oficjalny binarny plik Go, który uruchamiasz lokalnie i kierujesz na swoją instancję:
{ "mcpServers": { "sentry": { "url": "https://mcp.sentry.dev/mcp" }, "grafana": { "command": "mcp-grafana", "env": { "GRAFANA_URL": "https://grafana.example.com", "GRAFANA_API_KEY": "${GRAFANA_SERVICE_ACCOUNT_TOKEN}" } } }}Sentry to oficjalny serwer zdalny (uwierzytelnij się przez /mcp po dodaniu). Oficjalny binarny plik Grafany grafana/mcp-grafana działa przez stdio:
# Oficjalny zdalny serwer MCP Sentry — uwierzytelnianie przez /mcpclaude mcp add --transport http sentry https://mcp.sentry.dev/mcp
# Oficjalny serwer MCP Grafana Labs (binarka mcp-grafana / obraz Docker mcp/grafana)claude mcp add grafana \ --env GRAFANA_URL=https://grafana.example.com \ --env GRAFANA_API_KEY=$GRAFANA_SERVICE_ACCOUNT_TOKEN \ -- mcp-grafanaCodex przechowuje wpisy MCP w ~/.codex/config.toml. Użyj --url dla hostowanego serwera Sentry oraz polecenia stdio dla Grafany:
# Hostowany serwer MCP Sentry (OAuth: codex mcp login sentry)codex mcp add sentry --url https://mcp.sentry.dev/mcp
# Serwer stdio Grafana Labscodex mcp add grafana \ --env GRAFANA_URL=https://grafana.example.com \ --env GRAFANA_API_KEY=$GRAFANA_SERVICE_ACCOUNT_TOKEN \ -- mcp-grafanaKorzyść: zamiast wklejać stos wywołań do czatu, prosisz agenta, by go pobrał.
Zinstrumentuj Usługę (Tam, Gdzie Naprawdę Zaczyna Się Większość Bugów)
Dział zatytułowany „Zinstrumentuj Usługę (Tam, Gdzie Naprawdę Zaczyna Się Większość Bugów)”Pulpity są pochodną instrumentacji. Jeśli usługa emituje złe atrybuty lub brak kontekstu śladu, żadna liczba paneli Grafany Cię nie uratuje. To rzecz o najwyższej dźwigni, którą trzeba zrobić dobrze, i jest identyczna niezależnie od tego, którego agenta używasz — liczy się prompt.
To, co generuje agent, to standardowy bootstrap SDK — częścią wartą przejrzenia jest eksporter i zamykanie:
// tracing.js — load with: node --require ./tracing.js server.jsconst { 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_NAME, ATTR_SERVICE_VERSION,} = require('@opentelemetry/semantic-conventions');
const sdk = new NodeSDK({ resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: process.env.SERVICE_NAME ?? 'api-service', [ATTR_SERVICE_VERSION]: process.env.SERVICE_VERSION ?? '0.0.0', 'deployment.environment': process.env.ENVIRONMENT ?? 'production', }), // Jaeger ingests OTLP natively since v1.35 — no Jaeger exporter needed. traceExporter: new OTLPTraceExporter({ url: process.env.OTLP_ENDPOINT ?? 'http://otel-collector:4318/v1/traces', }), instrumentations: [getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-fs': { enabled: false }, })],});
sdk.start();process.on('SIGTERM', () => sdk.shutdown().finally(() => process.exit(0)));Generuj Reguły Prometheus i Alerty SLO
Dział zatytułowany „Generuj Reguły Prometheus i Alerty SLO”Pliki reguł Prometheus to obszar, gdzie pomoc AI błyszczy — składnia jest wybredna, a PromQL łatwo subtelnie zepsuć. Trzymaj prompt zdecydowany, by dostać reguły nagrywania metodą RED plus alerty burn-rate, a nie ścianę wszystkich metryk, jakie tylko można sobie wyobrazić.
Wygenerowane reguły nagrywania wyglądają tak — krótkie, łatwe do przejrzenia i będące fundamentem każdego alertu:
groups: - name: api_recording interval: 30s rules: - record: job:http_requests:rate5m expr: sum by (job) (rate(http_requests_total[5m])) - record: job:http_errors:ratio5m expr: | sum by (job) (rate(http_requests_total{status=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m])) - record: job:http_latency:p95_5m expr: | histogram_quantile(0.95, sum by (job, le) (rate(http_request_duration_seconds_bucket[5m])))Dla routingu AlertManagera przekaż agentowi swoją politykę eskalacji prostym językiem i pozwól mu wytworzyć drzewo:
Parsuj i Koreluj Logi
Dział zatytułowany „Parsuj i Koreluj Logi”Najbardziej wartościowy ruch w logowaniu to sprawienie, by logi linkowały ze śladami. Jeśli każda linia logu niesie trace_id, klikasz ze spanu w Grafanie prosto do otaczających logów. Poniższy prompt produkuje pipeline Logstash, który robi dokładnie to.
Blok korelacji śladów to część do zweryfikowania — upewnij się, że nazwy pól pasują do tego, co emituje Twój SDK OpenTelemetry:
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 {} }}Próbkowanie Ogonowe w Kolektorze
Dział zatytułowany „Próbkowanie Ogonowe w Kolektorze”Domyślne próbkowanie nagłówka (head sampling) odrzuca ślady na ślepo — i tak właśnie znika ten jeden ślad, którego potrzebowałeś. Próbkowanie ogonowe (tail sampling) decyduje po zakończeniu śladu, więc możesz zachować 100% błędów i wolnych żądań, próbkując nudne rzeczy na poziomie 5%.
Kiedy To Się Psuje
Dział zatytułowany „Kiedy To Się Psuje”-
Spany w ogóle się nie pojawiają. Najpierw sprawdź endpoint eksportera i niezgodność protokołu — OTLP/HTTP to 4318, OTLP/gRPC to 4317, a eksporter
protovshttp/jsonmusi pasować do odbiornika. Uruchom eksporterdebugkolektora (verbosity: detailed), by potwierdzić, że spany docierają, zanim zaczniesz winić backend. -
Prometheus dostaje OOM albo scrapy są wolne. Masz eksplozję kardynalności. Odpytaj
topk(20, count by (__name__)({__name__=~".+"}))orazprometheus_tsdb_head_series, by znaleźć winowajcę, a potem usuń sprawczą etykietę regułąmetric_relabel_configs. Niemal zawsze jest to etykieta dodana przez AI, której nie wyłapałeś podczas przeglądu. -
Alerty odpalają z opóźnieniem albo w burzach. Sprawdź ponownie
for:,group_waitirepeat_interval. Alert burn-rate ze zbyt długim oknem nie zawiadomi, dopóki nie przepalisz już budżetu;group_wait: 0sna wszystkim zamienia awarię klastra w setki powiadomień. -
Logi nie korelują ze śladami. Nazwa pola
trace_idz Twojego SDK nie pasuje do tego, czego oczekuje pipeline, albo jest zagnieżdżona. Zaloguj jedno surowe zdarzenie i potwierdź dokładną ścieżkę, zanim zaufasz blokowirename/mutate. -
Ślad, którego potrzebowałeś, został odrzucony przez próbkowanie. Odrzuciło go próbkowanie nagłówka. Przenieś decyzje o błędach/opóźnieniu do próbkowania ogonowego w kolektorze (powyżej) i trzymaj błędy na 100%.