Skip to content

feat(profiling): continuous CPU/heap profiling via WithProfiling#6

Open
FrameAutomata wants to merge 2 commits into
tracewayapp:mainfrom
FrameAutomata:feat/profiling
Open

feat(profiling): continuous CPU/heap profiling via WithProfiling#6
FrameAutomata wants to merge 2 commits into
tracewayapp:mainfrom
FrameAutomata:feat/profiling

Conversation

@FrameAutomata

Copy link
Copy Markdown

What

Adds opt-in continuous profiling to the core SDK. traceway.WithProfiling(serviceName) starts a background goroutine that, on an interval (WithProfilingInterval, default 60s; CPU window ~30s, capped to interval/2), captures a CPU profile and a heap profile and POSTs each as a separate request to <server>/api/profiles/ingest.

Also folds in a small, independent hardening commit: Init no longer panics on a malformed connection string.

Why

Profiling powers flame graphs / allocation views alongside the existing traces and metrics. The ingest contract is already live on the backend.

How it works

  • Reuses the existing report plumbing. The ingest URL is derived from the connection-string report URL (scheme://host + /api/profiles/ingest); auth (Authorization: Bearer <token>), serverName, and appVersion come from the same config as /api/report.
  • No double compression. The body is the raw, already-gzipped pprof bytes with no extra Content-Encoding — the backend's gzip middleware only decompresses when that header is present, and profile.Parse reads gzipped pprof directly.
  • Verified against the backend contract: path, Bearer auth, service/serverName/appVersion query params, raw pprof body, and 200 {} success.
  • Never affects the host app. Capture/upload failures are isolated per profile and silent unless WithDebug(true) is set; a bad URL disables profiling without failing Init.

Scope

Core traceway package only. HTTP middleware pass-through options (tracewayhttp/gin/fiber/chi/fasthttp) are a deliberate follow-up — apps that call traceway.Init directly (e.g. workers using MeasureTask) can enable it today.

Commits

  • feat(profiling): add WithProfiling continuous CPU/heap profiling
  • fix(init): reject malformed connection strings instead of panicking

Tests

  • URL derivation; CPU/heap capture (validated by full gzip decompression, not just magic bytes); upload request shape (path / Bearer / query params / byte-exact raw body / no gzip Content-Encoding); options wiring; and a deterministic single-cycle test asserting CPU + heap are sent as two requests.
  • Regression test for the Init panic fix.
  • go test, go vet, go build all green; framework subpackage suites (tracewayhttp, tracewaygin) green.

Docs

See docs/profiling.md.

🤖 Generated with Claude Code

FrameAutomata and others added 2 commits June 23, 2026 22:00
Add an opt-in background profiler that, on an interval (default 60s, CPU
window ~30s capped to interval/2), captures CPU and heap pprof profiles
and POSTs each as a separate request to <server>/api/profiles/ingest,
reusing the connection-string token and host.

The ingest URL is derived from the existing report URL (scheme+host +
/api/profiles/ingest); Bearer auth, serverName and appVersion reuse the
existing report plumbing. Profiling never affects the host app: capture
and upload failures are isolated and silent unless WithDebug is set, and
a bad URL disables profiling without failing Init.

Verified against the backend contract (tracewayapp/traceway
/api/profiles/ingest): path, Bearer auth, service/serverName/appVersion
query params, and raw already-gzipped pprof body with no extra
Content-Encoding.

Core package only; HTTP middleware pass-through options are a follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Init split the connection string on "@" and unconditionally indexed
connParts[1], panicking with "index out of range" when the string had
no "@". Use SplitN with a length guard so a malformed connection string
returns an error, and so a "@" inside the URL (e.g. userinfo) no longer
silently truncates the endpoint.

Co-Authored-By: Claude Opus 4.8 <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