Structured JSON logs with correlation IDs. Levels: DEBUG → INFO → WARN → ERROR → FATAL. The foundation of observability — immutable forensic records of system behavior.
CPU % · Memory % · Disk I/O · Thread pool queue depth
CPU > 80% sustained
Method
Full Form
Best For
Metrics
RED
Rate · Errors · Duration
Microservices, APIs
Requests/sec · Error % · p99 response time
USE
Utilization · Saturation · Errors
Infrastructure — CPU, memory, disk, network
CPU % · queue depth · device error count
▸ Why p99 Matters More Than Average
▸ SLI / SLO / SLA Relationship
SLI / SLO / SLA:SLI (indicator) — actual measured metric. SLO (objective) — internal target. SLA (agreement) — contractual commitment with penalty. SLO should be stricter than SLA. Error Budget = 100% − SLO.
⚠️ Cardinality Explosion: Every unique combination of label values creates a new time series. user_id as a label = millions of series → OOM. request_path with IDs (/users/12345) = unbounded. Fix: use bounded labels (method, status_code, service) and move high-cardinality to logs/traces. Rule of thumb: <10 values per label.
One-liner: Track p99 not average — use RED for services, USE for infra, alert on Golden Signals, define SLOs stricter than SLA. Watch for cardinality explosion.
Distributed Tracing
Track a single request across services. Trace ID → Spans → Parent-child relationships → Latency breakdown. Essential for debugging microservices.
▸ Trace / Span Hierarchy — Request Flow
Core Concepts:Trace — end-to-end journey of a request. Span — single unit of work (one service call). Root Span — first span, sets trace duration. Child Span — nested operation within parent. Span Context — trace_id + span_id + flags propagated across boundaries.
▸ Context Propagation Standards
Standard
Header Format
Example
Used By
W3C TraceContext
traceparent / tracestate
00-abc123-span456-01
OpenTelemetry (default), modern systems
B3 (Zipkin)
X-B3-TraceId / X-B3-SpanId
X-B3-TraceId: abc123
Zipkin, Spring Cloud Sleuth
B3 Single
b3 (single header)
abc123-span456-1
Zipkin compact format
Jaeger
uber-trace-id
abc123:span456:0:1
Jaeger native (legacy)
Baggage
baggage
user_id=123,region=us
W3C Baggage — custom context across services
▸ Sampling Strategies: Head-Based vs Tail-Based
Strategy
Decision Point
Pros
Cons
Best For
Head-based
At trace start (first service)
Simple, low overhead, consistent
May miss interesting traces (errors decided later)
High-volume, cost-sensitive
Tail-based
After trace completes (collector)
Keep all errors/slow traces, smarter
Higher memory (buffer full traces), complex
Debug-focused, error analysis
Priority-based
Based on attributes (user tier, endpoint)
VIP users always traced
Configuration complexity
Multi-tenant systems
Rate-limiting
N traces per second per service
Predictable cost
May miss bursts
Budget-constrained
Async Boundary Propagation: For Kafka — inject trace context into message headers (traceparent header). For SQS — use message attributes. For gRPC — metadata headers. For HTTP — request headers. Key: consumer creates a new span linked to producer span (SpanLink, not parent-child).
One-liner: Propagate W3C TraceContext headers across all boundaries. Use tail-based sampling to capture errors. Every span needs: service name, operation, duration, status, and parent span ID.
Monitoring & Alerting
Collect → Evaluate → Alert → Route → Respond → Root Cause Analysis. Only page if human action is needed.
▸ Alerting Pipeline Architecture
▸ Alert Quality: Good vs Bad
Quality
Alert Example
Why
Action
✅ Good
Error rate > 1% for 5 min on payment-svc
Sustained, actionable, specific service
Investigate payment gateway
✅ Good
p99 latency > 2s for 3 min
User-impacting, time-windowed
Check DB queries, scale pods
✅ Good
Error budget burn rate > 14.4x for 1h
SLO-based, predictive
Will breach SLO in 6h if unchecked
❌ Bad
Any single 500 error
Too noisy — single errors are normal
Alert fatigue, ignored
❌ Bad
CPU > 50%
Not actionable — 50% is healthy
Wastes on-call time
❌ Bad
Disk usage > 80% (no duration)
No time window — transient spikes trigger
False positives
▸ On-Call Best Practices
On-Call Rules:Every alert must have a runbook — link in alert annotation. Escalation policy — if no ack in 5 min, escalate. Rotation — weekly, with handoff notes. Blameless culture — focus on systems, not people. Toil budget — if >50% time on toil, fix the system.
▸ Burn Rate Alerting (Multi-Window)
Burn Rate Concept: If SLO = 99.9% over 30 days → error budget = 0.1% = 43.2 min of downtime/month.
Burn rate 1x = consuming budget at exactly the allowed rate (will exhaust in 30 days).
Burn rate 14.4x = will exhaust entire budget in ~2 days → page immediately.
Burn rate 6x = will exhaust in ~5 days → ticket, investigate.
Burn rate 1x = normal → no action.
Multi-window: Use short window (5 min) to detect fast burns + long window (1h) to confirm sustained. Prevents false positives from brief spikes.
One-liner: Only page if human action needed. Use burn rate alerts over static thresholds. Every alert needs a runbook. Group + deduplicate to prevent alert fatigue.
OpenTelemetry
Vendor-neutral observability framework — one SDK for Traces + Metrics + Logs. Instrument once, export to any backend. CNCF project, industry standard.
One-liner: Use OTel auto-instrumentation for 80% coverage, add manual spans for business logic. Deploy collector as agent + gateway in production. Correlate all three signals via trace_id.
Dashboards & Visualization
Dashboards are the first thing you look at during an incident. Design for clarity: USE for infra, RED for services, business KPIs for stakeholders.
Service overview → endpoint breakdown → individual trace
Time alignment
All panels share same time range
Correlate CPU spike with latency increase at same moment
Annotations
Mark deployments, incidents on timeline
Vertical line: "v2.4.1 deployed" — correlate with metric change
Thresholds visible
Show SLO/SLA lines on graphs
Red line at p99 = 500ms (SLO boundary)
≤ 8 panels
Cognitive load limit per dashboard
More panels = slower load + harder to scan during incident
▸ The 4 Golden Dashboards Every Service Needs
1. Service Health (RED)
Request rate (RPS)
Error rate (%)
p50 / p95 / p99 latency
Active connections
2. Infrastructure (USE)
CPU utilization %
Memory usage / limits
Disk I/O + space
Network in/out
3. Dependencies
DB query latency
Cache hit ratio
External API latency
Queue depth / lag
4. Business KPIs
Orders/min
Signup conversion
Revenue per minute
Active users
▸ Dashboard Anti-Patterns
Anti-Pattern
Problem
Fix
Too many panels
Cognitive overload, slow rendering, can't find signal in noise
Max 6-8 panels per dashboard. Split into sub-dashboards.
Vanity metrics
"Total requests ever" — not actionable, always goes up
Show rate of change (RPS), not cumulative totals
No context
Graph shows spike but no reference for "normal"
Add SLO threshold lines + deployment annotations
Average-only
Hides tail latency — 1% of users suffering
Always show p50 + p95 + p99 together
Stale dashboards
Panels for decommissioned services, broken queries
Quarterly dashboard review. Delete unused panels.
No drill-down
See problem but can't investigate further
Link panels to detailed dashboards, traces, logs
Grafana Tips: Use variables for service/environment selectors. Annotations for deploys. Alert rules directly on panels. Exemplars — click a metric data point to jump to the exact trace. Explore mode for ad-hoc investigation.
One-liner: Build 4 dashboards per service (RED, USE, Dependencies, Business). Max 8 panels each. Show percentiles not averages. Add SLO lines + deploy annotations. Link to traces for drill-down.
Incident Response
Structured process: Detect → Triage → Mitigate → Resolve → Postmortem. Goal: minimize user impact, learn from failures, prevent recurrence.
Chaos Engineering: Proactively inject failures to find weaknesses before production incidents. Tools: Chaos Monkey (random instance kill) · Litmus (Kubernetes chaos) · Gremlin (managed platform). Start with Game Days — scheduled, controlled experiments with rollback plan.
One-liner:Detect fast (MTTD < 5 min), mitigate first (rollback > debug), resolve properly, then blameless postmortem with action items. Every SEV1 gets a postmortem within 48h.