Skip to content

[codex] add diagnostics resource history#2685

Open
juliusmarminge wants to merge 2 commits into
mainfrom
t3code/better-diagnostics-monitoring
Open

[codex] add diagnostics resource history#2685
juliusmarminge wants to merge 2 commits into
mainfrom
t3code/better-diagnostics-monitoring

Conversation

@juliusmarminge
Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge commented May 14, 2026

Summary

Adds an in-memory process resource monitor for Diagnostics that samples the T3 server root process and live descendants over time. The new history API rolls samples up into CPU-time summaries and chart buckets so the UI can show cumulative CPU, current/average/peak CPU, and memory peaks across selectable windows.

Details

  • Adds a ProcessResourceMonitor service with a bounded 60-minute in-memory ring buffer.
  • Includes the root T3 server process in the sampled state alongside descendants.
  • Adds server.getProcessResourceHistory contracts/RPC/client wiring.
  • Extends Settings -> Diagnostics with a Resource History section, window selector, CPU timeline, and top process table.
  • Keeps existing live process diagnostics and process signaling behavior unchanged.

Validation

  • bun fmt
  • bun typecheck
  • bun lint (passes with existing warnings)
  • bun run test src/diagnostics/ProcessDiagnostics.test.ts src/diagnostics/ProcessResourceMonitor.test.ts from apps/server

Note

Add process resource history monitoring and diagnostics UI

  • Adds ProcessResourceMonitor service (ProcessResourceMonitor.ts) that samples server process and descendants every 5s, retains samples within a fixed window, and exposes a readHistory method returning bucketed CPU/memory aggregates.
  • Adds a server.getProcessResourceHistory WebSocket RPC endpoint with full contract definitions in server.ts and rpc.ts.
  • Adds a Resource History section to the Diagnostics settings panel (DiagnosticsSettings.tsx) with a CPU bar chart, per-process summary table, window selector, and 5s polling via useProcessResourceHistory.
  • Disables RPC tracing for the new endpoint in RpcInstrumentation.ts to avoid noise.

Macroscope summarized 20a2a1c.


Note

Medium Risk
Adds a new background sampler and WebSocket RPC for process CPU/RSS history; risk is moderate due to continuous sampling/polling and new aggregation logic that could affect performance or memory if mis-sized.

Overview
Adds a new ProcessResourceMonitor service that samples the server root PID plus live descendants every 5s, retains a bounded in-memory history, and aggregates it into per-process CPU-time summaries and time-bucketed CPU/RSS stats.

Exposes this via new contracts and server.getProcessResourceHistory RPC wiring (server ws.ts handler + client localApi/wsRpcClient), and disables tracing for the new method to avoid span noise.

Extends the web Diagnostics settings with a Resource History section (window selector, CPU timeline chart, and per-process table), and exports a few ProcessDiagnostics helpers (ProcessRow, buildDescendantEntries, isDiagnosticsQueryProcess, readProcessRows) for reuse; updates server tests to mock the new monitor and adds unit tests for the monitor’s sampling/aggregation behavior.

Reviewed by Cursor Bugbot for commit 20a2a1c. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1384f5f7-8fdc-449e-9257-d3f6b925a38e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/better-diagnostics-monitoring

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels May 14, 2026
- Group sampled processes by PID and command to keep histories stable across elapsed-time drift
- Show all process summaries in the window and refine the diagnostics table and chart UI
- Add coverage for grouping drift and expanded summaries
@juliusmarminge juliusmarminge marked this pull request as ready for review May 14, 2026 06:17
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Redundant fetch logic diverges between refresh and interval
    • Replaced the duplicated fetch logic in the refresh callback with a refreshKey state counter that triggers the useEffect to re-run, ensuring a single fetch path with isMounted guards and proper interval reset.

Create PR

Or push these changes by commenting:

@cursor push 842ce7848e
Preview (842ce7848e)
diff --git a/apps/web/src/lib/processDiagnosticsState.ts b/apps/web/src/lib/processDiagnosticsState.ts
--- a/apps/web/src/lib/processDiagnosticsState.ts
+++ b/apps/web/src/lib/processDiagnosticsState.ts
@@ -83,22 +83,11 @@
   const [data, setData] = useState<ServerProcessResourceHistoryResult | null>(null);
   const [error, setError] = useState<string | null>(null);
   const [isPending, setIsPending] = useState(true);
+  const [refreshKey, setRefreshKey] = useState(0);
 
   const refresh = useCallback(() => {
-    setIsPending(true);
-    void ensureLocalApi()
-      .server.getProcessResourceHistory({ bucketMs, windowMs })
-      .then((result) => {
-        setData(result);
-        setError(null);
-      })
-      .catch((cause: unknown) => {
-        setError(formatProcessDiagnosticsError(cause));
-      })
-      .finally(() => {
-        setIsPending(false);
-      });
-  }, [bucketMs, windowMs]);
+    setRefreshKey((k) => k + 1);
+  }, []);
 
   useEffect(() => {
     let isMounted = true;
@@ -127,7 +116,7 @@
       isMounted = false;
       window.clearInterval(interval);
     };
-  }, [bucketMs, windowMs]);
+  }, [bucketMs, windowMs, refreshKey]);
 
   return { data, error, isPending, refresh };
 }

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 20a2a1c. Configure here.

.finally(() => {
setIsPending(false);
});
}, [bucketMs, windowMs]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant fetch logic diverges between refresh and interval

Low Severity

The refresh callback duplicates the fetch logic from the useEffect's read function but omits the isMounted guard and doesn't reset the interval timer. This means a manual refresh near an interval tick produces two concurrent in-flight requests that race on setData/setIsPending, and refresh can set state after unmount. Extracting a shared fetch function or having refresh simply restart the effect would avoid the divergence.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 20a2a1c. Configure here.

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented May 14, 2026

Approvability

Verdict: Needs human review

This PR introduces a new process resource history monitoring feature with a backend sampling service, new RPC endpoint, and substantial new UI components. New features introducing user-facing behavior warrant human review regardless of how well-scoped they are.

You can customize Macroscope's approvability policy. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant