Case File № 500 · Status: OPEN

The Case of the
Vanishing Request

It entered the system healthy. Forty services later, it was dead — no body, no note, no witness willing to talk. Somebody has to put on the hat.

A Noir Field Guide to Observability & Distributed Tracing

open the file

It always starts the same way. A pager buzzes at 2:14 a.m. Checkout is throwing 500s for "some" users — nobody can say which ones. The dashboard is a wall of green except for one graph that shrugged and turned red an hour ago. The request came in the front door looking perfectly healthy, walked into a city of forty microservices, and never came out. No stack trace long enough to follow. No single log that says who did it.

You pour the coffee. You pull the hat down over your eyes. Tonight you're not a developer — you're a detective, and the system is a suspect that has learned to keep its mouth shut.

The nature of the crime

In a monolith, the body is in the room with you — one process, one stack trace, one log file to read start to finish. In microservices, the victim was passed hand to hand across the network. The service that reported the failure is almost never the one that committed it. Without observability, you're interrogating forty suspects who each swear they only saw the request for four milliseconds and then it left.

MOTIVE — WHY THIS CASE MATTERSYou can't fix what you can't see

Here's the uncomfortable truth every on-call engineer learns the hard way: in a distributed system, failures are the normal state, not the exception. Networks blink. Pods evict. A downstream dependency adds 200ms and a retry storm turns it into a cascade. The question was never whether something breaks — it's whether you can name the culprit before your users do it for you on social media.

Observability is the difference between "checkout is slow, we're looking into it" for six hours, and "the payment gateway's p99 tripled at 02:03, here's the trace, deploying a timeout fix now." One is a shrug. The other is detective work. The gap between them is measured in revenue, sleep, and trust.

Monitoring tells you the house is on fire.
Observability tells you who lit the match.

THE WITNESSES — THREE PILLARSEveryone saw something different

Every case has witnesses, and a good detective knows each one only tells part of the story. Observability has three, and you need all of them talking to each other.

Logs
The diary keeper

The most detailed witness — remembers exact words, timestamps, the odd exception. But scattered across forty notebooks in forty services, and prone to writing pages nobody asked for. Useless until you can line up every entry that belongs to the same request.

Metrics
The bird's-eye watcher

Saw the whole street from the rooftop. Can tell you error rates rose, latency doubled, the queue backed up — the shape of the crime. But never remembers a single face. Great for "something's wrong," hopeless at "which request, and why."

Traces
The eyewitness who followed him

The star witness. Tailed the request from the front door through every service it touched, timing each stop, noting exactly where it stumbled. This is the one who breaks the case — the through-line the other two can only gesture at.

Detective's note

None of the three solves it alone. Metrics tell you when to start looking, traces tell you where the request died, and logs tell you why — the exact exception at that exact span. The art is stitching them together with one thread: a shared identifier every witness was forced to write down.

THE THREAD — CORRELATIONOne ID to bind their testimonies

The oldest trick in detective work: give every witness the same case number and make them cite it. In distributed tracing, that number is the trace ID — minted the instant the request enters the system, then carried across every network hop in the request headers. Each service that touches the request opens a span — its own testimony of "I received it at T, did this work, handed it off at T+Δ" — all stamped with the same trace ID.

The modern standard for this is OpenTelemetry (OTel) — vendor-neutral, and the reason your traces, metrics, and logs can finally be compelled to testify together. In .NET it rides on System.Diagnostics.Activity and W3C traceparent headers, so context propagates across HTTP and message-bus hops without you threading IDs by hand.

Program.cs — deputizing OpenTelemetry (.NET / Azure)
// Wire the whole app to testify: traces + metrics, auto-propagated.
builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r.AddService("checkout-api"))
    .WithTracing(t => t
        .AddAspNetCoreInstrumentation()   // inbound spans
        .AddHttpClientInstrumentation()   // outbound hops carry traceparent
        .AddSource("Checkout")
        .AddOtlpExporter())                // → Azure Monitor / Jaeger / Tempo
    .WithMetrics(m => m
        .AddAspNetCoreInstrumentation()
        .AddOtlpExporter());

// A custom span = one witness statement you control.
using var activity = _source.StartActivity("ReservePayment");
activity?.SetTag("order.id", order.Id);
activity?.SetTag("customer.tier", tier);
// ...on failure, record who did it:
activity?.SetStatus(ActivityStatusCode.Error, "gateway timeout");

That's the whole trick: one instant of setup, and every request now leaves a trail of breadcrumbs with the same case number stamped on each one. The suspects can no longer keep their stories straight — because they're all writing down the same ID.

EXHIBIT A — THE TRACEReading the eyewitness testimony

Here's what the star witness hands you: a waterfall. Every bar is one span — one service's slice of the request — laid out on a timeline. Read left to right and you're watching the request move through the city. The moment one bar stretches while the rest sit idle, you've found where it bled out.

Exhibit A · Trace Waterfalltrace_id: 4c1f…a903 · 1,842 ms · ERROR
api-gateway
1842ms
checkout-svc
cart-svc
120ms
inventory-svc
140ms
payment-svc
1180ms ⚠
↳ gateway-api
timeout
Reading of the exhibit: gateways up top look fine. payment-svc → gateway-api held the request for 1,180 ms and returned a timeout — the whole 500 traces back to one downstream call. Case cracked in one screen, not six hours of grep.

This is the payoff. Without the trace, you'd be SSH-ing into six services reading logs by candlelight, guessing at the order of events. With it, the guilty span is literally the longest red bar on the screen. The detective's job collapses from "search the whole city" to "read the one testimony that followed the victim all the way to the end."

THE METHOD — SOLVING THE CASEHow to work the scene

Every seasoned investigator has a procedure. Here's the one that closes distributed cases fast:

  1. Start from the alarm, not the code. A metric — error rate, p99 latency, saturation — tells you when and roughly where the trouble began. Let the RED (Rate, Errors, Duration) or USE signals point you at the district before you knock on any doors.
  2. Grab the trace for a failing request. Filter your traces to the errors in that window and open one. The waterfall shows the guilty span without a single guess about service order.
  3. Zoom from span to log. Every span carries the trace ID; every log line should too. Jump from the red span straight to its logs — the exact exception, the exact input — instead of grepping forty files.
  4. Confirm the pattern, not the anecdote. One slow trace is a lead; the metric confirms it's systemic. Check whether the p99 on that dependency moved for everyone or just this request.
  5. Name it, fix it, and leave a better witness behind. Add the missing span attribute, the timeout, the retry budget — so the next detective (probably you, next month) solves it in one screen instead of six.

FIELD KIT — ON AZURE & KUBERNETESThe detective's toolbelt

◆ CASE CLOSED ◆

The closing statement

The request that vanished at 2:14 a.m. was never really gone — it left a trail the whole way down, waiting for someone with the right instruments to read it. That's what observability is: not a dashboard, not a vanity graph, but the practice of building a system that can testify against itself when something goes wrong.

Do the work up front — one OpenTelemetry setup, a trace ID on every hop, logs that know their case number — and the next 2 a.m. page stops being a manhunt. It becomes what good detective work always is: a quiet, methodical reading of the evidence, and a name written in the file before the coffee goes cold.

Put on the hat. The system is talking. All you have to do is make it impossible for it to stay silent.