Skip to content

feat(profiling): add continuous profiler timeline exploration - #877

Merged
platinummonkey merged 1 commit into
DataDog:mainfrom
AlexJF:feat/timeline-exploration
Oct 2, 2026
Merged

platinummonkey merged 1 commit into
DataDog:mainfrom
AlexJF:feat/timeline-exploration

Conversation

@AlexJF

@AlexJF AlexJF commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds pup profiling explore timeline, which calls the Continuous Profiler timeline exploration endpoint (POST /api/unstable/profiling/pup/explore/timeline). It returns an AI-friendly summary of a profile timeline: top lane groups (threads, GC, etc.) with thread-state and event breakdowns, utilization and insights, and optionally the critical path of a span.

  • src/commands/profiling.rs: explore_timeline, scoped by exactly one of:

    • --profile-id + --event-id: a single profile
    • --runtime-id + --query: recent profiles of one process
    • --trace-id + --span-id + --time-hint: the profiles behind a span

    Optional flags are --limit-lanes, --focus-from/--focus-to, --focus-event-type, --focus-lane-group and --critical-path (Go only, requires --trace-id). Unset fields are left out so server defaults apply.

  • src/main.rs: ProfilingExploreActions::Timeline plus dispatch and doc-comment updates.

  • Tests: each scope's request body, all validation rules, null optional response fields, a 400 error, and missing auth.

  • Docs: timeline examples in docs/EXAMPLES.md and the command listing in docs/COMMANDS.md.

Motivation

Follow-up to #819 (pup profiling operations), alongside call graph exploration (#876). Timeline exploration was the remaining exploration view only exposed through the profiling MCP server.

Additional Notes

Checklist

  • The code change follows the project conventions (see CONTRIBUTING.md)
  • Tests have been added/updated (if applicable)
  • Documentation has been updated (if applicable)
  • All CI checks pass
  • Code coverage is maintained or improved

Related Issues

Follow-up to #819 and #876.

Plan
# PROF-16039: Add timeline exploration support to pup (pup leg)

Full cross-repo plan: /home/bits/.claude/plans/lets-work-on-https-datadoghq-atlassian-n-nested-dragon.md

## Context

Third of three repos for PROF-16039 (follow-up to PROF-15503; sibling of PROF-16038/callgraph).
- profiling-backend: ddoghq/profiling-backend#9128 adds `POST /api/pup/explore/timeline`.
- dd-source: ddoghq/dd-source#114431 proxies it at `/api/unstable/profiling/pup/explore/timeline`.
- This leg adds `pup profiling explore timeline`.

Follows pup's own conventions (branch `feat/timeline-exploration`, conventional commits, fork PR).
Originally stacked on `feat/callgraph-exploration` (DataDog/pup#876, now merged); rebased onto
upstream/main so the PR only carries the timeline commit.

Signing: the DataDog-org SSH signing key isn't in the forwarded agent, so commits are signed with
the user's personal SSH key (repo-local `user.signingkey`; registered as a signing key on AlexJF).

## Backend contract (TimelineExplorationRequest)

Exactly one of `runtimeId` (requires non-empty filter query), `traceContext`
(`traceId`+`spanId`+`timeHint`, all `@NotEmpty`), `profileContext` (`profileId`+`eventId`).
Optional, server-defaulted: `limitLanes` (>0), `focusEventType`, `focusStartTime`/`focusEndTime`
(Instant), `focusLaneGroup` (exact `groupName` match), `useCriticalPath` (requires traceContext; Go).

## Bug found along the way

`timeHint` is `@NotEmpty` on the backend `TraceContext`, but pup sent `timeHint: null`, so
`--trace-id` scoping always 400'd. Fixed for callgraph in #876 (new commit fc8b744): shared
`trace_context_json` helper requiring `--trace-id`/`--span-id`/`--time-hint` together and
converting `--time-hint` (any pup time format) to epoch seconds. Timeline reuses it.
**Not fixed** (pre-existing, already merged in #819): `explore flamegraph` and
`profile-types list` trace-id modes have the same bug — flagged to the user as a separate fix.

## Changes

- `src/commands/profiling.rs`: `explore_timeline` (validation: exactly one scope, profile/event
  pairing, runtime-id requires query, critical-path requires trace-id, limit-lanes > 0; optional
  fields omitted when unset; focus times sent as RFC3339). 13 tests.
- `src/main.rs`: `ProfilingExploreActions::Timeline` + dispatch; doc comment capability/example;
  `Explore` doc string mentions call graphs/timelines.
- `docs/EXAMPLES.md`: "Explore a Timeline" (profile-id, runtime-id + focus lane group, trace-id +
  critical path). `docs/COMMANDS.md`: `timeline` in row/bullet.

## Status

- [x] Worktree `.claude/worktrees/feat-timeline-exploration`, branch stacked on callgraph
- [x] Implementation, docs, tests
- [x] `cargo fmt --check`, `cargo clippy --all-targets -- -D warnings`
- [x] `cargo test profiling::` — 52 pass
- [x] Commit + push to `origin`; draft PR DataDog/pup#877. After #876 merged, rebased onto upstream/main (now a single commit 75968ad); 52 profiling tests pass.
Prompts
# Prompts log — PROF-16039 (pup leg)

1. "Lets work on https://datadoghq.atlassian.net/browse/PROF-16039, following similar patterns to
   https://github.com/ddoghq/profiling-backend/pull/9070 and https://github.com/ddoghq/dd-source/pull/102914"
2. Plan approved as-is (via plan mode).
3. "Can't we sign with my personal SSH key, open a PR against my fork AlexJF/pup and open a draft PR
   from there to upstream?"
4. "try again" (after the forwarded SSH agent was restored)
5. "Hmm just the timeline PUP PR is showing 3 commits, including the callgraph one, despite me having already merged it" / "hmm did things hang?"

🤖 Generated with Claude Code

Add `pup profiling explore timeline`, calling the new prof-gateway
/api/unstable/profiling/pup/explore/timeline endpoint (PROF-16039).

- explore_timeline in src/commands/profiling.rs: scoped by exactly one of
  --runtime-id (with --query), --trace-id (with --span-id/--time-hint) or
  --profile-id (with --event-id); optional focus window, focus event type,
  focus lane group, lane limit and Go critical-path analysis
- ProfilingExploreActions::Timeline clap variant and dispatch in src/main.rs
- Tests for each scope, request body shape, validation rules, null optional
  response fields, 400 errors and missing auth
- Timeline examples in docs/EXAMPLES.md and command listing in docs/COMMANDS.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AlexJF
AlexJF force-pushed the feat/timeline-exploration branch from 8f9ac32 to 75968ad Compare October 2, 2026 13:55
@AlexJF
AlexJF marked this pull request as ready for review October 2, 2026 13:57
@AlexJF
AlexJF requested a review from a team as a code owner October 2, 2026 13:57
@platinummonkey
platinummonkey removed the request for review from a team October 2, 2026 14:05
@platinummonkey
platinummonkey merged commit 5210d85 into DataDog:main Oct 2, 2026
10 checks passed
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.

2 participants