Observability Monitoring And Incident Response
Production Monitoring Orientation
The Three Pillars
Observability rests on three kinds of telemetry, and they answer different questions:
<?php
declare(strict_types=1);
$pillars = [
'logs' => 'discrete events with detail: what happened, here, with this context',
'metrics' => 'aggregated numbers over time: how much, how many, how fast',
'traces' => 'the path of one request across functions and services: where the time went',
];
foreach ($pillars as $pillar => $answers) {
echo $pillar . ': ' . $answers . PHP_EOL;
}
// Prints:
// logs: discrete events with detail: what happened, here, with this context
// metrics: aggregated numbers over time: how much, how many, how fast
// traces: the path of one request across functions and services: where the time went
- Logs are the detailed record. They tell you exactly what happened at a point in time, with context. Their strength is depth; their weakness is that at volume, unstructured logs are a haystack. This is why production logs should be structured (JSON with consistent fields) rather than free-text
error_logstrings — structured logs are queryable, and queryability is what turns a log pile into an investigation tool. - Metrics are cheap numbers aggregated over time: request rate, error rate, latency percentiles, queue depth, CPU. They are what dashboards and most alerts are built from, because they are compact enough to keep for a long time and fast to query. They tell you that something is wrong and roughly where, rarely why.
- Traces follow a single request through the code and across service boundaries, timing each span. When a request is slow, a trace shows whether the time went to the database, an external API, or your own code — the question metrics and logs answer only clumsily.
The three are complementary, not competing: metrics alert you that error rate spiked, a trace shows you which dependency, and logs show you the exact failing request. A mature setup lets you pivot between them on a shared identifier (a request or trace ID), which is why propagating that ID everywhere is foundational.
The Golden Signals
You cannot watch everything, so watch the signals that correlate with user pain. Google's SRE practice names four golden signals, and they are a reliable starting dashboard for any service:
- Latency — how long requests take, watched as percentiles (p50, p95, p99), never as an average. Averages hide the tail, and the tail is where users suffer; a p99 of 4 seconds means one in a hundred requests is miserable even if the average looks fine.
- Traffic — how much demand: requests per second, throughput.
- Errors — the rate of failing requests, which requires deciding what "failing" means (5xx obviously; also 4xx spikes, and slow-enough-to-be-useless).
- Saturation — how full the system is: CPU, memory, connection pool, queue depth — the resource that will run out first.
Watching these four per service catches most user-visible problems and gives you the vocabulary to describe them. Everything more specific is added because an incident taught you to.
Instrument For Questions You Will Have
The orientation to carry into the rest of this track: instrumentation is an investment you make before the incident, because you cannot add it during one. The design questions are which signals to emit, how to keep logs structured and correlated, what the golden-signal dashboard for each service looks like, and — crucially — how this ties back to the security monitoring from the hardening track, which is the same discipline pointed at a different class of problem. Detection you cannot act on is noise; the following lessons are about making each signal actionable.
What To Check
Before moving on, make sure you can:
- distinguish monitoring (known signals) from observability (new questions)
- explain what logs, metrics, and traces each answer and where each is weak
- explain why production logs should be structured and correlated by request ID
- name the four golden signals and why latency is watched as percentiles
- explain why instrumentation must precede the incident
What You Should Be Able To Do
After this lesson, you should be able to lay out a monitoring strategy for a PHP service around the three pillars and the golden signals, decide what telemetry to emit, and recognize the difference between data you collect and data you can actually investigate with.
Practice
Practice: Design A Service's Baseline Observability
Show solution
Metrics: the four golden signals per tier. Latency as p50/p95/p99 for HTTP and for queue job processing; traffic as requests/sec and jobs/sec; errors as 5xx rate, unhandled-exception rate, and failed-job rate; saturation as CPU, memory, php-fpm busy workers, MySQL connections, and Redis queue depth. These feed the primary dashboard.
Traces: request tracing that spans the controller, database queries, Redis calls, and outbound HTTP, so a slow request shows where its time went. Each trace carries the same id that appears in the logs.
The dashboard: one screen with the golden signals for web and for the queue, plus queue depth and DB connection saturation, because those are the two resources most likely to run out first for this stack.
Connecting the pillars in an investigation: a latency or error-rate alert (metric) names the affected endpoint and time window; opening a trace from that window shows the slow span (say, MySQL); the request id on that trace pulls the exact log lines for the failing requests. The shared id across all three is the design's load-bearing feature — without it, the three pillars are three separate haystacks.
Practice: Diagnose A Blind Investigation
Task
Explain why each piece of tooling failed the investigation and what would have made it fast.
Show solution
Each tool was the wrong shape for the question.
Average response time hid the problem. An average is dominated by the many fast requests and drowns out the slow tail — the exact requests timing out. A p95/p99 latency graph would have shown the tail lifting off sharply while the average stayed calm, which is why latency is always watched as percentiles. The team was looking at the one metric guaranteed to under-report their incident.
Free-text logs on four separate servers made correlation nearly impossible: no shared query surface, so an engineer would SSH to each box and grep, unable to follow a single slow request across tiers or even know which server served it. Structured logs shipped to one store and filtered by time window and severity would have surfaced the failing requests in seconds; a request id would have let them follow one end to end.
No tracing meant that even once a slow request was found, nothing showed where the 40 seconds went — app code, a locked database, or a stalled external API. A trace would have pointed straight at the culprit span; without it, "slow" had no next step.
What makes it fast: percentile latency (see the tail), structured centralized logs (find the requests), and tracing (locate the time), all correlated by a shared request id so the team pivots metric → trace → log instead of guessing. The meta-lesson: this instrumentation had to exist before the incident; none of it can be added mid-outage.
Practice: Define Observability Readiness Checks
Define the checks that confirm a service is observable enough to investigate an incident quickly, covering the three pillars and correlation.
Show solution
- A synthetic request is traced end to end and asserted to produce: a trace with spans for each tier, log lines carrying that trace's id, and metric increments — proving all three pillars fire and share an id.
- Logs are asserted to be structured (parseable JSON with the required fields) and to arrive in the central store within a freshness bound; a host going quiet alerts.
- The golden-signal metrics exist and are non-stale for every service, with latency exposed as percentiles, not just an average.
Human, periodically:
- Run the "could we investigate this?" drill: pick a hypothetical symptom (slow checkout) and confirm an engineer can pivot metric → trace → log to a root cause using only the tooling, in minutes. Gaps found here are cheap; gaps found mid-incident are not.
- Confirm new services and endpoints shipped with golden-signal instrumentation rather than being invisible until their first outage.
- Check that request/trace id propagation survives across every service boundary the request crosses, since a broken link there silently defeats correlation.