Logging & Observability mit Claude Code: Pino, Winston, OpenTelemetry 2026
Wenn ein Production-Bug um 3 Uhr nachts auftritt, entscheiden deine Logs ob du ihn in 5 Minuten oder 5 Stunden findest. Claude Code baut strukturierte Logging-Pipelines, konfiguriert OpenTelemetry und erklärt welches Log-Level wann passt.
Log-Levels: Was wann loggen?
| Level | Wann | Beispiel | Alert? |
|---|---|---|---|
| ERROR | Fehler der User-Experience beeinflusst | DB-Verbindung fehlgeschlagen, API 500 | Ja — sofort |
| WARN | Unerwartetes aber verkraftbares Ereignis | Rate Limit nähert sich, Retry nötig | Bei Häufung |
| INFO | Normaler Business-Flow | User eingeloggt, Order erstellt | Nein |
| DEBUG | Entwicklung + gezieltes Debugging | SQL-Query, Request-Details | Nein — Production aus! |
Claude Code Prompt: "Review diese Datei auf falsche Log-Levels. Prüfe: werden sensible Daten geloggt? Sind DEBUG-Logs in Production aktiv? Sind alle ERROR-Logs structured mit request_id und user_id?"
Pino: Schnelles strukturiertes Logging
PinoProduction-Setup mit Request-Context
# Prompt: "Erstelle Pino-Setup mit Request-ID-Tracking und Production/Development-Config"
# logger.js
const pino = require('pino');
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
// Development: lesbare Ausgabe
transport: process.env.NODE_ENV !== 'production'
? { target: 'pino-pretty', options: { colorize: true } }
: undefined, // Production: JSON (Loki/CloudWatch verarbeitet JSON)
// Sensible Felder maskieren
redact: {
paths: ['password', 'token', '*.creditCard', '*.ssn'],
censor: '[REDACTED]'
},
// Basis-Felder für jedes Log
base: {
service: process.env.SERVICE_NAME || 'api',
env: process.env.NODE_ENV
}
});
module.exports = logger;
# Express Middleware: Request-ID + Timing
const { randomUUID } = require('crypto');
app.use((req, res, next) => {
const requestId = req.headers['x-request-id'] || randomUUID();
const start = Date.now();
// Child-Logger mit Request-Context
req.log = logger.child({
requestId,
method: req.method,
url: req.url,
userId: req.user?.id
});
res.on('finish', () => {
req.log.info({
status: res.statusCode,
duration: Date.now() - start
}, 'request completed');
});
next();
});
Structured Logging: Was ins JSON gehört
StructuredKonsistente Log-Felder
# FALSCH — schwer zu filtern:
logger.error(`User ${userId} kann Bestellung ${orderId} nicht stornieren: ${error.message}`);
# RICHTIG — strukturiert, filterbar:
logger.error({
event: 'order.cancel.failed',
userId,
orderId,
errorCode: error.code,
errorMessage: error.message,
stack: error.stack
}, 'Order cancellation failed');
# Warum: In Grafana/Kibana/Loki kannst du filtern:
# {event="order.cancel.failed", userId="123"}
# Freitext-Suche in Strings ist langsam und unzuverlässig
OpenTelemetry: Distributed Tracing
OpenTelemetryTraces durch Microservices verfolgen
# Prompt: "Richte OpenTelemetry für Node.js ein — Traces zu Grafana Tempo"
# instrumentation.js (vor allem anderen laden!)
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
const { PgInstrumentation } = require('@opentelemetry/instrumentation-pg');
const sdk = new NodeSDK({
serviceName: 'order-service',
traceExporter: new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT // Grafana Tempo / Jaeger
}),
instrumentations: [
new HttpInstrumentation(), // Alle HTTP-Requests
new ExpressInstrumentation(), // Express Routen
new PgInstrumentation() // PostgreSQL Queries
]
});
sdk.start();
// node --require ./instrumentation.js server.js
# Manueller Span für Business-Logik:
const { trace } = require('@opentelemetry/api');
const tracer = trace.getTracer('order-service');
async function processOrder(orderId) {
return tracer.startActiveSpan('process-order', async (span) => {
span.setAttribute('order.id', orderId);
try {
const result = await doProcessing(orderId);
span.setAttribute('order.status', 'success');
return result;
} catch (err) {
span.recordException(err);
span.setStatus({ code: SpanStatusCode.ERROR });
throw err;
} finally {
span.end();
}
});
}
Metrics mit Prometheus
MetricsCustom Business Metrics
# prom-client für Node.js Metrics
const { Counter, Histogram, register } = require('prom-client');
const httpRequests = new Counter({
name: 'http_requests_total',
help: 'Total HTTP requests',
labelNames: ['method', 'route', 'status']
});
const responseTime = new Histogram({
name: 'http_response_duration_seconds',
help: 'HTTP response times',
buckets: [0.05, 0.1, 0.3, 0.5, 1, 2, 5]
});
// Business Metric: Orders pro Minute
const ordersProcessed = new Counter({
name: 'orders_processed_total',
help: 'Total orders processed',
labelNames: ['status', 'payment_method']
});
// Metrics-Endpoint für Prometheus Scraping:
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
Log-Aggregation: Grafana Loki
# docker-compose für lokalen Observability-Stack
# Prompt: "Erstelle docker-compose mit Grafana, Loki, Prometheus, Tempo"
services:
grafana:
image: grafana/grafana:latest
ports: ["3000:3000"]
loki: # Log-Aggregation
image: grafana/loki:latest
ports: ["3100:3100"]
prometheus: # Metrics
image: prom/prometheus:latest
ports: ["9090:9090"]
tempo: # Distributed Tracing
image: grafana/tempo:latest
ports: ["4317:4317"] # OTLP gRPC
# Pino → Loki: pino-loki Transport
const transport = pino.transport({
target: 'pino-loki',
options: {
host: 'http://localhost:3100',
labels: { app: 'order-service', env: 'production' }
}
});
DSGVO-Achtung bei Logs: Niemals E-Mail-Adressen, IPs (ohne Rechtsgrundlage), Passwörter oder Zahlungsdaten in Logs. Claude Code kann einen Audit deiner Logging-Felder machen — frage: "Prüfe alle log.* Aufrufe auf DSGVO-kritische Daten."
Observability im Kurs
Im Claude Code Mastery Kurs: vollständiger Observability-Stack mit Pino, OpenTelemetry, Grafana Loki und Prometheus — von der ersten Log-Zeile bis zum Production-Dashboard mit automatischen Alerts.
14 Tage kostenlos testen →