feat(coderd): add consolidated /debug/profile endpoint for pprof collection (#22892)

## Summary

Adds a new `GET /api/v2/debug/profile` endpoint that collects multiple
pprof profiles in a single request and returns them as a tar.gz archive.
This allows collecting profiles (including block and mutex) without
requiring `CODER_PPROF_ENABLE` to be set, and without restarting
`coderd`.

Closes #21679

## What it does

The endpoint:
- Temporarily enables block and mutex profiling (normally disabled at
runtime)
- Runs CPU profile and/or trace for a configurable duration (default
10s, max 60s)
- Collects snapshot profiles (heap, allocs, block, mutex, goroutine,
threadcreate)
- Returns a tar.gz archive containing all requested `.prof` files
- Uses an atomic bool to prevent concurrent collections (returns 409
Conflict)
- Is protected by the existing debug endpoint RBAC (owner-only)

**Supported profile types:** cpu, heap, allocs, block, mutex, goroutine,
threadcreate, trace

**Query parameters:**
- `duration`: How long to run timed profiles (default: `10s`, max:
`60s`)
- `profiles`: Comma-separated list of profile types (default:
`cpu,heap,allocs,block,mutex,goroutine`)

## Additional changes

- **SDK client method** (`codersdk.Client.DebugCollectProfile`) for easy
programmatic access
- **`coder support bundle --pprof` integration**: tries the consolidated
endpoint first, falls back to individual `/debug/pprof/*` endpoints for
older servers
- **8 new tests** covering defaults, custom profiles, trace+CPU,
validation errors, authorization, and conflict detection
This commit is contained in:
Kacper Sawicki
2026-03-13 14:09:39 +00:00
committed by GitHub
parent cc6716c730
commit df2360f56a
8 changed files with 783 additions and 2 deletions
+22
View File
@@ -869,6 +869,28 @@ const docTemplate = `{
}
}
},
"/debug/profile": {
"post": {
"security": [
{
"CoderSessionToken": []
}
],
"tags": [
"Debug"
],
"summary": "Collect debug profiles",
"operationId": "collect-debug-profiles",
"responses": {
"200": {
"description": "OK"
}
},
"x-apidocgen": {
"skip": true
}
}
},
"/debug/tailnet": {
"get": {
"security": [
+20
View File
@@ -752,6 +752,26 @@
}
}
},
"/debug/profile": {
"post": {
"security": [
{
"CoderSessionToken": []
}
],
"tags": ["Debug"],
"summary": "Collect debug profiles",
"operationId": "collect-debug-profiles",
"responses": {
"200": {
"description": "OK"
}
},
"x-apidocgen": {
"skip": true
}
}
},
"/debug/tailnet": {
"get": {
"security": [