Przejdź do głównej zawartości

Monitorowanie i obserwowalność

Nowoczesne systemy rozproszone wymagają wyrafinowanych rozwiązań monitorowania i obserwowalności. Asystenci AI do kodowania wyróżniają się w implementacji OpenTelemetry, tworzeniu dashboardów, pisaniu zapytań i konfigurowaniu alertowania - przekształcając obserwowalność z ciężaru w strategiczną przewagę.

Tradycyjne podejścia do monitorowania mają problemy z:

  • Złożonymi architekturami rozproszonymi obejmującymi wiele serwisów
  • Masowymi wolumenami danych z logów, metryk i śladów
  • Zmęczeniem alertami z źle dostrojonych progów
  • Ręczną korelacją między różnymi typami telemetrii
  • Reaktywnym reagowaniem na incydenty zamiast proaktywnej prewencji

Asystenci AI pomagają poprzez:

  • Generowanie kodu instrumentacji z odpowiednią propagacją kontekstu
  • Tworzenie inteligentnych zapytań ujawniających wglądy
  • Budowanie kompleksowych dashboardów dostosowanych do Twojego stosu
  • Pisanie reguł alertów redukujących szum
  • Automatyzację korelacji incydentów między sygnałami
@codebase "Skonfiguruj OpenTelemetry dla naszych mikroserwisów Node.js:
- Automatyczna instrumentacja dla Express, MongoDB, Redis
- Niestandardowe spany dla operacji biznesowych
- Propagacja kontekstu śledzenia między serwisami
- Metryki dla SLI (opóźnienie, wskaźnik błędów, przepustowość)
- Strukturalne logowanie z korelacją śladów
- Export zarówno do Jaeger, jak i Prometheus"
// Kompleksowa konfiguracja OTel wygenerowana przez AI
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
// Inicjalizacja OpenTelemetry
const sdk = new NodeSDK({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: process.env.SERVICE_NAME,
[SemanticResourceAttributes.SERVICE_VERSION]: process.env.SERVICE_VERSION,
[SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: process.env.NODE_ENV,
}),
traceExporter: new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
}),
metricReader: new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
}),
exportIntervalMillis: 30000,
}),
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-fs': {
enabled: false, // Zbyt głośne
},
}),
],
});
// Niestandardowa instrumentacja biznesowa
export function createBusinessSpan(operation: string) {
const tracer = trace.getTracer('business-operations');
return tracer.startSpan(operation, {
attributes: {
'business.operation': operation,
'business.user_id': getCurrentUserId(),
'business.tenant': getTenantId(),
},
});
}
// Strukturalne logowanie z korelacją śladów
export function getLogger(component: string) {
return {
info: (message: string, data?: any) => {
const span = trace.getActiveSpan();
const traceId = span?.spanContext().traceId;
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'info',
component,
message,
traceId,
...data,
}));
},
// Podobnie dla error, warn, debug
};
}
graph TB subgraph Applications A1[Service A] A2[Service B] A3[Service C] end subgraph Collection OC[OTel Collector] FA[Fluent Bit] end subgraph Storage P[Prometheus] L[Loki] T[Tempo] end subgraph Visualization G[Grafana] AM[Alert Manager] end A1 --> OC A2 --> OC A3 --> OC A1 --> FA A2 --> FA A3 --> FA OC --> P OC --> T FA --> L P --> G L --> G T --> G G --> AM

Prompt AI dla konfiguracji stosu

"Stwórz kompletny stos monitorowania z:
- OpenTelemetry Collector z odpowiednią konfiguracją
- Prometheus dla metryk z politykami retencji
- Loki dla logów z backendem S3
- Tempo dla śladów z możliwościami wyszukiwania
- Grafana z pre-skonfigurowanymi źródłami danych
- Odpowiednim networkingiem i persistence"

AI wygeneruje kompleksowy docker-compose.yml ze wszystkimi serwisami odpowiednio skonfigurowanymi i połączonymi.

@prometheus @grafana "Stwórz dashboard zdrowia serwisu pokazujący:
- Request rate, error rate, duration (metryki RED)
- Opóźnienia P50, P95, P99 według endpointu
- Wskaźnik spalania budżetu błędów
- Aktywne alerty i ich status
- Wykorzystanie zasobów (CPU, pamięć, połączenia)
- Status zdrowia zależności
Użyj najlepszych praktyk PromQL i uczyń go responsywnym"
  1. Zdefiniuj kluczowe metryki

    "Zidentyfikuj nasze kluczowe metryki biznesowe:
    - Zaangażowanie użytkowników (DAU, MAU, retencja)
    - Wskaźniki sukcesu transakcji
    - Wpływ błędów na przychody
    - Wskaźniki adopcji funkcji"
  2. Wygeneruj zapytania

    "Napisz zapytania PromQL dla tych metryk biznesowych,
    korelując metryki techniczne z wpływem biznesowym"
  3. Stwórz wizualizacje

    "Zaprojektuj panele Grafana, które opowiadają historię,
    z możliwościami drill-down od metryk biznesowych do technicznych"
// Middleware propagacji śledzenia wygenerowany przez AI
export const traceMiddleware = (req, res, next) => {
const tracer = trace.getTracer('http-middleware');
const propagator = new W3CTraceContextPropagator();
// Wyodrębnij kontekst z przychodzącego żądania
const parentContext = propagator.extract(
context.active(),
req.headers,
defaultTextMapGetter
);
// Rozpocznij nowy span jako dziecko wyodrębnionego kontekstu
const span = tracer.startSpan(
`${req.method} ${req.route.path}`,
{
kind: SpanKind.SERVER,
attributes: {
'http.method': req.method,
'http.url': req.url,
'http.target': req.route.path,
'http.host': req.hostname,
'http.scheme': req.protocol,
'user.id': req.user?.id,
},
},
parentContext
);
// Wstrzyknij kontekst dla serwisów downstream
const headers = {};
propagator.inject(
trace.setSpan(context.active(), span),
headers,
defaultTextMapSetter
);
req.traceHeaders = headers;
// Zakończ span na odpowiedzi
res.on('finish', () => {
span.setAttributes({
'http.status_code': res.statusCode,
'http.response.size': res.get('content-length'),
});
span.setStatus({
code: res.statusCode >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK,
});
span.end();
});
next();
};
# Konfiguracja Loki wygenerowana przez AI
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
ingester:
wal:
enabled: true
dir: /loki/wal
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
schema_config:
configs:
- from: 2023-01-01
store: boltdb-shipper
object_store: s3
schema: v11
index:
prefix: index_
period: 24h
storage_config:
aws:
s3: s3://access_key:secret_key@endpoint/bucket
s3forcepathstyle: true
boltdb_shipper:
active_index_directory: /loki/boltdb-shipper-active
cache_location: /loki/boltdb-shipper-cache
shared_store: s3
limits_config:
ingestion_rate_mb: 10
ingestion_burst_size_mb: 20
max_streams_per_user: 10000
max_global_streams_per_user: 10000
compactor:
working_directory: /loki/compactor
shared_store: s3
compaction_interval: 10m
# Reguły alertów Prometheus wygenerowane przez AI
groups:
- name: service_health
interval: 30s
rules:
- alert: HighErrorRate
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
) > 0.05
for: 5m
labels:
severity: critical
team: platform
annotations:
summary: "Wysoki wskaźnik błędów na {{ $labels.service }}"
description: "{{ $labels.service }} ma {{ $value | humanizePercentage }} wskaźnik błędów"
runbook_url: "https://wiki.example.com/runbooks/high-error-rate"
- alert: SLOBurnRateTooHigh
expr: |
(
1 - (
sum(rate(http_requests_total{status!~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
)
) > (1 - 0.999) * 14.4
for: 5m
labels:
severity: warning
team: platform
annotations:
summary: "Wskaźnik spalania SLO zbyt wysoki dla {{ $labels.service }}"
description: "W tym tempie {{ $labels.service }} wyczerpie budżet błędów w < 1 dzień"
- alert: PodMemoryUsageHigh
expr: |
(
container_memory_working_set_bytes{pod!=""}
/
container_spec_memory_limit_bytes{pod!=""} > 0
) > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} wykorzystanie pamięci > 90%"
description: "Rozważ zwiększenie limitów pamięci lub optymalizację aplikacji"
# Konfiguracja AlertManager wygenerowana przez AI
global:
resolve_timeout: 5m
slack_api_url: '{{ SLACK_API_URL }}'
route:
group_by: ['alertname', 'cluster', 'service']
group_wait: 10s
group_interval: 10s
repeat_interval: 12h
receiver: 'default'
routes:
# Krytyczne alerty idą do PagerDuty
- match:
severity: critical
receiver: pagerduty
continue: true
# Ostrzeżenia tylko w godzinach pracy
- match:
severity: warning
receiver: slack-warnings
active_time_intervals:
- business-hours
# Routing specyficzny dla zespołu
- match_re:
service: ^(payment|billing).*
receiver: finance-team
# Alerty środowiska deweloperskiego
- match:
environment: development
receiver: dev-null
receivers:
- name: 'default'
slack_configs:
- channel: '#alerts'
title: 'Alert: {{ .GroupLabels.alertname }}'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'
- name: 'pagerduty'
pagerduty_configs:
- service_key: '{{ PAGERDUTY_SERVICE_KEY }}'
description: '{{ .GroupLabels.alertname }}: {{ .CommonAnnotations.summary }}'
- name: 'dev-null'
# Cicho odrzuć
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'service']
"Stwórz dashboard Grafana, który koreluje:
- Ślady pokazujące wolne żądania
- Logi z tych konkretnych ID śledzenia
- Metryki pokazujące stan systemu podczas incydentu
- Powiązane alerty, które zostały wywołane
Użyj widoku Explore Grafana z integracją Loki/Tempo"
  1. Zidentyfikuj anomalię

    # Zapytanie wykrywania anomalii wygenerowane przez AI
    (
    rate(http_request_duration_seconds_sum[5m])
    /
    rate(http_request_duration_seconds_count[5m])
    ) >
    (
    avg_over_time(
    rate(http_request_duration_seconds_sum[5m])[1h:5m]
    /
    rate(http_request_duration_seconds_count[5m])[1h:5m]
    ) * 2
    )
  2. Analiza śladów

    "Dla ID śledzenia X, przeanalizuj:
    - Który span trwał najdłużej
    - Wszelkie błędy w spanach dziecięcych
    - Wzorce zapytań do bazy danych
    - Wywołania serwisów zewnętrznych"
  3. Badanie logów

    # Zapytanie LogQL wygenerowane przez AI
    {service="api"}
    | json
    | trace_id="abc123"
    | line_format "{{.timestamp}} [{{.level}}] {{.message}}"
    | pattern "<_> error=<error> <_>"
  4. Korelacja metryk

    "Pokaż mi metryki CPU, pamięci i puli połączeń
    dla serwisu podczas okna incydentu"
@tempo @grafana "Stwórz zapytania do znalezienia:
- Najwolniejszych endpointów według opóźnienia P95
- Najczęstszych zapytań do bazy danych
- Serwisów z najwyższymi wskaźnikami błędów
- Śladów z największą liczbą spanów (złożoność)
- Wskaźników trafień cache według serwisu"

Automatyczna analiza wydajności

// Analizator wydajności wygenerowany przez AI
export class PerformanceAnalyzer {
async analyzeTraces(timeRange: TimeRange) {
const slowTraces = await this.tempo.search({
query: 'duration > 1s',
limit: 100,
start: timeRange.start,
end: timeRange.end,
});
const patterns = this.identifyPatterns(slowTraces);
const recommendations = this.generateRecommendations(patterns);
return {
bottlenecks: patterns.bottlenecks,
recommendations,
estimatedImpact: this.calculateImpact(patterns),
};
}
private identifyPatterns(traces: Trace[]) {
// Grupuj według operacji i analizuj
const operationStats = traces.reduce((acc, trace) => {
trace.spans.forEach(span => {
if (!acc[span.operation]) {
acc[span.operation] = {
count: 0,
totalDuration: 0,
errors: 0,
};
}
acc[span.operation].count++;
acc[span.operation].totalDuration += span.duration;
if (span.status === 'error') acc[span.operation].errors++;
});
return acc;
}, {});
// Znajdź wąskie gardła
const bottlenecks = Object.entries(operationStats)
.filter(([_, stats]) => stats.totalDuration / stats.count > 100)
.sort((a, b) => b[1].totalDuration - a[1].totalDuration)
.slice(0, 5);
return { operationStats, bottlenecks };
}
}
# Polisy retencji wygenerowane przez AI
retention_policies:
metrics:
- selector: '{__name__=~"up|scrape_.*"}'
retention: 30d # Metryki infrastruktury
- selector: '{__name__=~"http_.*"}'
retention: 90d # Metryki aplikacji
- selector: '{__name__=~"business_.*"}'
retention: 400d # Metryki biznesowe
logs:
- level: debug
retention: 1d
- level: info
retention: 7d
- level: warning
retention: 30d
- level: error
retention: 90d
traces:
- sampling_rate: 0.1 # 10% dla normalnego ruchu
- error_sampling: 1.0 # 100% dla błędów
- slow_sampling: 0.5 # 50% dla wolnych żądań
"Przeanalizuj nasz stos obserwowalności i zasugeruj optymalizacje:
- Redukcja kardynalności dla Prometheus
- Parsowanie logów w celu zmniejszenia storage
- Strategie samplingowania śladów
- Optymalizacja zapytań dashboardu
- Deduplikacja alertów"
{
"mcpServers": {
"sentry": {
"command": "npx",
"args": ["-y", "sentry-mcp"],
"env": {
"SENTRY_AUTH_TOKEN": "${SENTRY_AUTH_TOKEN}",
"SENTRY_ORG": "your-org"
}
}
}
}

Użycie:

"Używając Sentry MCP:
- Pobierz trendy błędów z ostatnich 24h
- Znajdź najczęstsze błędy
- Przeanalizuj wpływ błędów według liczby użytkowników
- Stwórz zgłoszenia GitHub dla krytycznych błędów"
{
"mcpServers": {
"grafana": {
"command": "npx",
"args": ["-y", "@leval/mcp-grafana"],
"env": {
"GRAFANA_URL": "https://grafana.example.com",
"GRAFANA_API_KEY": "${GRAFANA_API_KEY}"
}
}
}
}
  1. Kontrola wersji wszystkiego

    • Definicje dashboardów w JSON
    • Reguły alertów w YAML
    • Konfiguracje kolektorów
    • Polisy retencji
  2. Automatyzuj wdrożenie

    # CI/CD dla obserwowalności wygenerowane przez AI
    deploy-monitoring:
    steps:
    - name: Walidacja konfiguracji
    run: |
    promtool check rules alerts/*.yml
    grafana-validator dashboards/*.json
    - name: Wdróż reguły Prometheus
    run: |
    kubectl apply -f k8s/prometheus-rules.yaml
    - name: Importuj dashboardy
    run: |
    for dashboard in dashboards/*.json; do
    curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
    -H "Content-Type: application/json" \
    -d @$dashboard \
    https://grafana.example.com/api/dashboards/db
    done
  3. Testuj swoją obserwowalność

    "Stwórz testy dla naszego monitorowania:
    - Zweryfikuj, że alerty są poprawnie wywoływane
    - Testuj, że zapytania dashboardu zwracają dane
    - Waliduj propagację śladów
    - Sprawdź reguły parsowania logów"

Prywatność danych

  • Maskuj wrażliwe dane w logach
  • Implementuj szyfrowanie na poziomie pól
  • Używaj samplingu dla wrażliwych operacji
  • Przestrzegaj polis retencji

Kontrola dostępu

  • RBAC dla dashboardów
  • Oddzielne dane prod/dev
  • Ścieżka audytu dla zmian
  • Bezpieczne przechowywanie poświadczeń
"Przeanalizuj metryki Prometheus pod kątem wysokiej kardynalności:
- Znajdź metryki z największą liczbą unikalnych kombinacji etykiet
- Zasugeruj strategie redukcji etykiet
- Zaimplementuj reguły nagrywania dla agregacji
- Dodaj egzekwowanie kardynalności"
"Zaimplementuj wykrywanie anomalii oparte na ML:
- Trenuj modele na historycznych metrykach
- Automatycznie wykrywaj nietypowe wzorce
- Przewiduj potrzeby pojemnościowe
- Automatycznie generuj raporty incydentów"
  • OpenTelemetry Profiling - Wkrótce dla ciągłego profilowania
  • Integracja eBPF - Obserwowalność bez instrumentacji
  • OTTL - OpenTelemetry Transformation Language
  • Testowanie oparte na śladach - Walidacja zachowania przez ślady
  1. Zacznij od OpenTelemetry - Jest niezależny od dostawcy i przyszłościowy
  2. Instrumentuj kompleksowo - Ślady, metryki i logi razem
  3. Automatyzuj wszystko - Od konfiguracji do wglądów
  4. Skup się na wpływie biznesowym - Połącz metryki techniczne z wynikami
  5. Optymalizuj ciągle - Monitoruj swoje monitorowanie

Połączenie pomocy AI i nowoczesnych narzędzi obserwowalności sprawia, że kompleksowe monitorowanie jest dostępne dla zespołów każdej wielkości. Zacznij od małego, iteruj szybko i pozwól AI obsługiwać złożoność, podczas gdy Ty skupiasz się na wglądach.