Skip to content

Add access logging + host TCP sampler to diagnose pypi download failures - #362

Merged
alexreinking merged 1 commit into
masterfrom
diagnostics/pypi-download-instrumentation
Jul 29, 2026
Merged

Add access logging + host TCP sampler to diagnose pypi download failures#362
alexreinking merged 1 commit into
masterfrom
diagnostics/pypi-download-instrumentation

Conversation

@alexreinking

Copy link
Copy Markdown
Member

Problem

Halide CI intermittently (~10%) fails to reach pypi.halide-lang.org, with uv reporting client error (Connect): operation timed out (3 retries, ~47s) — on both wheel downloads and the tiny /simple/ index. The appliance had no request-level visibility, so failures could not be localized.

What this adds

  • Caddy JSON access log for the pypi site → dedicated caddy-logs volume, rotated, kept off the ACME/TLS log stream. Distinguishes a truncated download (200 with size < content-length) from a request that never arrived (absent), and shows whether the server was serving other clients during an incident.
  • monitor/sample.sh — a network_mode: host sidecar (netmon) sampling host TCP stack counters every 15s (accept-queue drops, conntrack, SYN_RECV, retransmits, load) to net-samples.tsv. Tells us whether lost SYNs were dropped on this host vs upstream of it.
  • Caddy global metrics on 127.0.0.1:2019 for on-demand in-flight snapshots.

What the data already showed

Correlated against a live failure (2026-07-29): during the failing runner's 47s retry window, Caddy served the identical /simple/halide-llvm/ request from three other runners (200 in ~15ms), the failing runner's request never reached Caddy, and every host drop counter stayed flat (listen_drops/overflows/reqq_full_drop = 0, conntrack ~20/262144, load < 0.5).

Conclusion: the packet loss is upstream of the host (network path / OpenStack floating-IP NAT), not Caddy/pypiserver/host config. This instrumentation is what let us establish that, and stays in place to triage future incidents.

🤖 Generated with Claude Code

Halide CI intermittently fails to reach pypi.halide-lang.org with uv
"client error (Connect): operation timed out" (3 retries, ~47s). The
appliance had no request-level visibility, so failures couldn't be
localized. This adds two complementary, low-overhead data sources:

- Caddy JSON access log for the pypi site -> dedicated caddy-logs volume,
  rotated, kept off the ACME/TLS log stream. Distinguishes a truncated
  download (status 200, size < content-length) from a request that never
  arrived (absent), and shows whether the server was serving other clients
  during an incident.
- monitor/sample.sh: a network_mode:host sidecar (netmon) that samples host
  TCP stack counters every 15s (accept-queue drops, conntrack, SYN_RECV,
  retransmits, load) to net-samples.tsv. Tells us whether lost SYNs were
  dropped on this host vs upstream of it.
- Caddy global `metrics` on 127.0.0.1:2019 for on-demand in-flight snapshots.

Correlating these against a live failure showed the server serving identical
requests from other runners in the same window while the failing runner's
request never reached Caddy and every host drop counter stayed flat --
i.e. the loss is upstream of the host (network path / OpenStack NAT), not
the server software.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alexreinking
alexreinking merged commit c1394dc into master Jul 29, 2026
9 checks passed
@alexreinking
alexreinking deleted the diagnostics/pypi-download-instrumentation branch July 29, 2026 17:08
alexreinking added a commit to halide/Halide that referenced this pull request Jul 29, 2026
The existing retry() only spanned 60s + 120s of backoff (3 attempts total),
which wasn't enough to ride out every pypi.halide-lang.org connect-timeout
blackhole (halide/build_bot#362).

- Retry harder: 5 attempts, backoff doubling from 60s up to a 300s cap
  (worst case ~12 extra minutes instead of ~3).
- On each failed attempt, log a UTC timestamp, the runner's egress IP
  (via api.ipify.org), and a path trace to pypi.halide-lang.org
  (tracepath/traceroute/tracert, whichever is available), folded into a
  collapsible log group. MIT network ops asked for an exact 5-tuple and
  timestamp from a live incident to correlate against their own border
  logs; this makes the next incident self-documenting without needing to
  reproduce it.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant