Cheat sheet · Observability and SRE: Logs, Metrics, Traces and Reliability

Observability & SRE cheat sheet

Logs, metrics, traces, SLOs, alerts, incidents and resilience patterns for a Node.js service, with the numbers interviewers expect. Metrics say that something is wrong, traces say where, logs say what.

Read the full series →

blogs · jp-blogs.vercel.app/cheatsheets/series/observability

Monitoring vs observabilityLesson 0 →

  • Monitoring answers questions you prepared. Observability answers new questions from data the system already emits.
  • Order in an incident: metric (how bad), trace (which hop), log (which exact case). Link them with ids.
  • Averages hide the tail: use percentiles. Alert on symptoms, diagnose with causes.
  • Observability costs CPU, money, attention and privacy. Sample the boring data, keep errors.
MethodApplies toMeasures
Golden signalsA user-facing serviceLatency, traffic, errors, saturation
REDA service or endpointRate, errors, duration
USEA resource (CPU, pool)Utilisation, saturation, errors

Structured logging (pino)Lesson 1 →

LevelUse for
fatalProcess cannot continue and will exit
errorAn operation failed; a person may need to act
warnUnexpected, but the request still worked
infoNormal business or lifecycle event
debug / traceBug-fixing detail / very fine detail
  • JSON lines with a fixed message and variable facts in fields.
  • Log errors under the err key. { e } printed as {} in the test.
  • Log each failure once, where you handle it. Never log secrets. Add redact as a safety net.
  • Cost was about 6 microseconds per line, near zero when the level is off.

Correlation ids and log samplingLesson 1 →

  1. Reuse the incoming request id or make one at the edge.
  2. Put it on a child logger so every line carries it.
  3. Send it on every outgoing call and inside queue messages.
  4. Search the id across services to read the full story.

Tip: Sample the boring lines, keep all errors, take totals from metrics. JSON escapes line breaks, so users cannot fake log lines.

Metric types and PromQLLesson 2 →

TypeBehaviourQuery it with
CounterOnly goes up; resets on restartrate(), increase()
GaugeGoes up and downRaw value
HistogramCounts values into bucketshistogram_quantile()
# traffic
sum(rate(http_requests_total[5m]))
# error ratio
sum(rate(http_requests_total
  {status=~"5.."}[5m]))
 / sum(rate(http_requests_total[5m]))
# p99, all instances
histogram_quantile(0.99,
 sum by (le) (rate(
  http_request_duration_seconds_bucket
  [5m])))

Percentiles and cardinalityLesson 2 →

  • Real run: average latency 81 ms, p99 about 820 ms.
  • Histogram percentiles are estimates. Coarse buckets showed p95 0.10 s when the truth was 0.60 s.
  • Never average percentiles. Sum the buckets across servers, then take the quantile.
  • Every label combination is a series. A user_id label turned 2 series into 10,000 (521 KB /metrics).
  • Safe labels: method, route template (/users/:id), status class, region, version.
  • Names: base units and _total. Initialise key counters. Prometheus gives up for free; check config with promtool.

Distributed tracing (OpenTelemetry)Lesson 3 →

  • A trace is a tree of spans with one trace id. A span has name, timing, attributes, events, status.
  • Always call span.end(). Name spans by operation. Keep secrets out of attributes.
  • API in libraries, SDK in apps. Start the SDK before the code it instruments. Set OTEL_SERVICE_NAME.
  • Put trace_id and span_id in log lines. Queues: inject context into the message, extract in the worker.
traceparent:
 00-<trace-id>-<parent-span>-01
 ver  32 hex    16 hex      flags

If any hop drops this header, the trace splits in two.

Tip: Parent-based head sampling kept 10% of traces and never half a trace. Tail sampling keeps the interesting ones but needs a collector.

SLI, SLO, SLA and the ninesLesson 4 →

  • SLI = good events / valid events, from the user's side. SLO = SLI + target + window. SLA = contract, looser than the SLO.
  • Latency SLI = share of requests under a threshold. The histogram needs a bucket at that threshold.
  • Never 100%. Rolling windows are harder to game. Dependencies in series multiply.
SLOBudgetMinutes per 30 days
99%1%432
99.9%0.1%43.2
99.95%0.05%21.6
99.99%0.01%4.3

Tip: Three dependencies at 99.9% in series give 99.7%. Dashboard green but users unhappy: the SLI is wrong.

Error budget and burn rateLesson 4 →

budget    = 1 - SLO
burn rate = error ratio / budget
threshold = fraction x
  window_hours / alert_hours

SLO 99.9%: 1.44% failing is burn 14.4, budget gone in 2.1 days.

Error ratioBurn rateBudget gone in
0.10%1.030.0 days
0.50%5.06.0 days
1.44%14.42.1 days
5.00%50.00.6 days
  • The budget is meant to be spent on change. Agree a freeze policy with the product owner while it is calm.
  • Low traffic makes budgets jumpy. Count budget in requests.

Good alertsLesson 5 →

  • A page must be urgent, actionable and about user pain. Otherwise: ticket, dashboard or nothing.
  • Every page links a runbook. Fight fatigue: count the actionable share of pages.
  • Never alert on average latency. Beware low traffic, long for:, and missing data. Add a dead man's switch.
AlertLong windowBurnAction
Fast burn2% in 1 h (short 5m)14.4Page
Slow burn5% in 6 h6Page
Trend10% in 3 days1Ticket

Tip: Join two windows with and: long means big enough, short means still happening, so the alert clears on recovery. Test with promtool test rules.

Alertmanager and dashboardsLesson 5 →

SettingDefaultMeaning
group_wait30sCollect more alerts before the first message
group_interval5mWait before news about a group
repeat_interval4hResend if nothing changed
  • Alertmanager groups, routes, inhibits (a big alert hides its children) and silences.
  • One dashboard, one question. Overview: traffic, errors, percentiles, saturation, deploy markers. Keep it in version control.

Incident responseLesson 6 →

LevelMeaningResponse
SEV-1Critical, many customers hurtFull response, IC, exec notice
SEV-2Major, partial impactCoordinated team
SEV-3Minor, workaround existsOwning team
  • Roles: IC (coordinates, rarely fixes), deputy, scribe, experts, liaison. One channel, regular updates.
  • Mitigate first, understand later. Small reversible changes, one at a time, confirm with the SLI.
  • Unsure about severity? Treat it as the higher one.

Watch out: Mean time to recover (MTTR) hides uneven incidents. Track detect, ack, mitigate, resolve, and budget used per incident.

Blameless post-mortemsLesson 6 →

  • Ask what in the system made the mistake easy. Blameless is not unaccountable.
  • List contributing factors, not one root cause.
  • Timeline, impact in budget terms, what went well, what was lucky.
  • A good action item is small, has an owner and a date, and is tracked.
  • On-call: primary and secondary, real rotation size, handoffs, rest, improve one thing per shift.

Timeouts, retries, breakersLesson 7 →

  • A slow dependency is worse than a dead one. Timeout on every call, a bit above healthy p99. Share one deadline.
  • Retry only passing failures on idempotent calls (or with an idempotency key), inside a deadline, with a retry budget.
  • Layers multiply: 3 x 3 x 3 = 27 calls. Retry in one layer only.
delay = random() *
  min(cap, base * 2 ** attempt)

Full jitter: 1000 retries, busiest 10 ms slice 35 instead of 200.

Breaker stateBehaviour
ClosedCalls pass; failures counted
OpenFail fast, no calls
Half-openTrial call after a wait; success closes it

Bulkheads, shedding, degradationLesson 7 →

  • Breaker: one per dependency, % over a window plus a minimum volume. Count timeouts and 5xx, not 4xx. Export its state.
  • Bulkhead: a separate limit per dependency, so a slow optional one cannot starve a critical one.
  • Load shedding: refuse early (503/429, Retry-After). An unlimited queue just turns overload into delay.
  • Degradation: plan B decided in advance, marked degraded, counted. Stale price to browse, never to charge.
  • Test with fault injection: hangs, slowness, flapping, partial failure.

Interview one-linersLesson 8 →

QuestionShort answer
Three pillars?Metrics say that, traces say where, logs say what.
Why not average latency?1% at 10 s: average 236 ms, p99 8.7 s.
Cardinality?Labels multiply series. No user ids.
SLI vs SLO vs SLA?Measure, target, contract.
99.9% in minutes?43.2 per 30 days. 99.99% is 4.3.
Burn rate?Error ratio / budget ratio. 14.4 for 1 h = 2%.
Good alert?Urgent, actionable, user pain, runbook.
First 10 minutes?Severity, roles, channel, mitigate, update.
Retries safe?Idempotent only, backoff + jitter + budget.
Mitigate or fix?Mitigate first (roll back), fix later.

A cheat sheet is a reminder, not a teacher. Each card links to the lesson that explains it step by step.