This is the cast I wish I’d had to point at when I first started explaining httptap. It’s short: I pick a running process, attach, and let the traffic scroll.

The setup here is a payments-api that I suspect is misbehaving against a downstream webhook collector. I find the pid with ps, then sudo httptap --pid 12843 --decrypt-tls to attach. No restart, no wrapper, no setup in the code. The TLS decryption is the uprobe on libssl line — that’s the one that does the actual work.

Notice that the first three Stripe calls to api.stripe.com come back green, 94-221ms. The moment traffic hits hooks.example.io, it falls off a cliff: three 502s in a row, each one taking about three seconds, with a matching backoff retry printed in red. The built-in slow-response detector flags it after the second consecutive failure, which I like because it means I don’t have to stare at the screen — the tool nudges me.

At the end I hit d on a line to dump its body, and you can see what actually went over the wire. Envoy is timing out upstream, which is a nice diagnostic to hand to whoever owns the webhook service. “Here’s the 502, here’s the header that says envoy, here’s the upstream_service_time — good luck.”

A couple of callouts:

  • No app-level changes. The service has no idea it’s being traced.
  • Sample rate is 100% by default. For a busy service you’ll want --sample 0.01 or a filter.
  • -> giving up, surfacing to caller is httptap’s own annotation; the client was doing the retries, and httptap correlated them.