Guide

Code that looks clean in a PR and pages you at 2 a.m. every week is not clean. Observability is the ability to explain a system's state from its outputs — logs, metrics, traces — without SSH folklore. If you need to "just know" which box to check, the system is under-instrumented.

Include the signals in the same PR, or a paired follow-up that blocks launch.

SignalPurpose
LogsStructured fields: request_id, user_id (careful with PII), error_code — greppable, not novels
MetricsRate, errors, duration for the new path; saturation for new queues or pools
DashboardOne panel row for the feature; link it from the runbook
AlertsSymptom-based where possible ("export failure rate > 2% for 10 m"), not "CPU high" unless that is all you have
TracesCritical cross-service paths get a trace id propagated

Alert on symptoms users feel (errors, latency, queue lag) more than on causes (CPU). Causes are for dashboards during debugging. Symptoms are for pages.

Walking through "what will they see at 2 a.m.?"

Before you merge a risky change, ask: "If this breaks at 2 a.m., what will the on-call see first?" If the answer is "nothing obvious," add the panel and the alert in the same change set. Future on-call-you is a stakeholder with veto power.

Name owners for alerts. An alert with no runbook and no owner is a future 3 a.m. archaeology dig.

You may not own the whole monitoring stack, but you own the alerts your changes introduce.

  • Page only when a human must act soon (user-visible breakage, SLO burn, impending saturation).
  • Ticket for issues that can wait until morning.
  • Dashboard only for interesting but non-actionable signals.

If you got paged and the correct action was "look and close," the alert is wrong — tune the threshold, add silence for known batch windows, or demote to ticket. Noisy pages train people to ignore the pager. That is how real incidents get slow responses. Also delete dead alerts when you remove a feature. Orphan alerts are a tax on every future shift.

This is the operational half of ownership: done includes a pulse, not only a merge.

Common mistakes

  • Shipping with no metrics. "We'll add monitoring later" is how 2 a.m. starts from zero.
  • Paging on causes nobody can act on. CPU is a dashboard; user-visible errors are a page.
  • Leaving orphan alerts after a feature dies.

Check yourself

The new export path has tests and no dashboard. Is it done?

No. If it breaks at 2 a.m., the on-call needs a panel and a symptom-based alert.

You got paged, looked, and closed with no action. What is wrong?

The alert. Tune it, silence the batch window, or demote it to a ticket.

Key takeaways

  • Ship logs, metrics, a dashboard, and an actionable alert with the feature.
  • Alert on symptoms users feel, not on causes.
  • Page only when a human must act soon. Delete dead alerts.
  • "What will they see at 2 a.m.?" is a merge question.

Further learning

Next: handling a page.