sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

feat(javascript): Add Claude Code Agent SDK instrumentation

Open codyde opened this issue 3 months ago • 5 comments

Summary

Adds Sentry tracing instrumentation for the @anthropic-ai/claude-agent-sdk (Claude Code Agent SDK) following OpenTelemetry Semantic Conventions Sentry's Agent Monitoring.

This integration enables AI monitoring for Claude Code agents with comprehensive telemetry:

  • Agent invocation spans (invoke_agent)
  • LLM chat spans (chat)
  • Tool execution spans (execute_tool)
  • Token usage tracking (including cache metrics)
  • Model info and session tracking
  • Optional input/output recording

Key Implementation Details

Why Not Automatic Like Other AI Integrations?

The Claude Code SDK (@anthropic-ai/claude-agent-sdk) is ESM-only with no CommonJS build, which prevents automatic instrumentation via OpenTelemetry's require() hooks that work for other integrations (Anthropic AI, OpenAI, etc.).

Solution: Helper Function Pattern

Provides createInstrumentedClaudeQuery() - a one-line helper that:

  • Lazy loads the SDK via dynamic import() (avoids bundler issues)
  • Automatically retrieves options from claudeCodeIntegration() config
  • Uses global singleton pattern (patches once, reuses everywhere)
  • Works with any bundler (Next.js/webpack, Vite, etc.)

Usage

// Step 1: Configure in Sentry init
import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: 'your-dsn',
  integrations: [
    Sentry.claudeCodeIntegration({
      recordInputs: true,
      recordOutputs: true
    })
  ],
});

// Step 2: Use in your code (1 line!)
import * as Sentry from '@sentry/node';

const query = Sentry.createInstrumentedClaudeQuery();

// Use query as normal - automatically instrumented
for await (const message of query({
  prompt: 'Hello',
  options: { model: 'claude-sonnet-4-5' }
})) {
  console.log(message);
}

Remaining TODO's

  • [ ] Tests
  • [ ] Handle PII (disabling prompt transmission etc...)
  • [ ] Expanded JavaScript server SDKs

codyde avatar Oct 01 '25 21:10 codyde

size-limit report 📦

Path Size % Change Change
@sentry/browser 24.64 kB - -
@sentry/browser - with treeshaking flags 23.14 kB - -
@sentry/browser (incl. Tracing) 40.99 kB - -
@sentry/browser (incl. Tracing, Replay) 79.31 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 68.99 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 84.02 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 96.17 kB - -
@sentry/browser (incl. Feedback) 41.33 kB - -
@sentry/browser (incl. sendFeedback) 29.3 kB - -
@sentry/browser (incl. FeedbackAsync) 34.26 kB - -
@sentry/react 26.35 kB - -
@sentry/react (incl. Tracing) 42.99 kB - -
@sentry/vue 29.13 kB - -
@sentry/vue (incl. Tracing) 42.79 kB - -
@sentry/svelte 24.66 kB - -
CDN Bundle 26.94 kB - -
CDN Bundle (incl. Tracing) 41.65 kB - -
CDN Bundle (incl. Tracing, Replay) 77.91 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 83.37 kB - -
CDN Bundle - uncompressed 78.95 kB - -
CDN Bundle (incl. Tracing) - uncompressed 123.53 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 238.57 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 251.33 kB - -
@sentry/nextjs (client) 45.13 kB - -
@sentry/sveltekit (client) 41.42 kB - -
@sentry/node-core 50.78 kB +0.01% +1 B 🔺
@sentry/node 154.43 kB +0.02% +25 B 🔺
@sentry/node - without tracing 92.66 kB - -
@sentry/aws-serverless 106.35 kB -0.01% -2 B 🔽

View base workflow run

github-actions[bot] avatar Oct 01 '25 23:10 github-actions[bot]

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 9,090 - 8,754 +4%
GET With Sentry 1,399 15% 1,355 +3%
GET With Sentry (error only) 6,127 67% 6,114 +0%
POST Baseline 1,207 - 1,187 +2%
POST With Sentry 515 43% 509 +1%
POST With Sentry (error only) 1,057 88% 1,058 -0%
MYSQL Baseline 3,336 - 3,250 +3%
MYSQL With Sentry 475 14% 467 +2%
MYSQL With Sentry (error only) 2,729 82% 2,647 +3%

View base workflow run

github-actions[bot] avatar Oct 01 '25 23:10 github-actions[bot]

Thanks for working on this! For the first pass, the biggest lift here is to try to auto patch the functions we need automatically instead of asking user to import patched method, then we can move to tackling the other TODOs you have

Thanks SO much for all these. I'll get started on them.

I tried REALLY hard to figure out how to hook into the existing query, and I couldn't get it to work no matter what I tried. I'll chat with you in slack on it, but I'd love some advice / guidance. I tried a bunch of different angles - but each time I ran into effectively timing issues where we couldn't hook fast enough. Felt like a limitation on how Claude Code's SDK works - but could be a total skill issue on my side.

codyde avatar Oct 06 '25 17:10 codyde

Thanks for working on this! For the first pass, the biggest lift here is to try to auto patch the functions we need automatically instead of asking user to import patched method, then we can move to tackling the other TODOs you have

Thanks SO much for all these. I'll get started on them.

I tried REALLY hard to figure out how to hook into the existing query, and I couldn't get it to work no matter what I tried. I'll chat with you in slack on it, but I'd love some advice / guidance. I tried a bunch of different angles - but each time I ran into effectively timing issues where we couldn't hook fast enough. Felt like a limitation on how Claude Code's SDK works - but could be a total skill issue on my side.

Hello @codyde, are you still working on this? if not, let's close this, we're trying to clean up the stale PRs

RulaKhaled avatar Oct 20 '25 11:10 RulaKhaled

Thanks for working on this! For the first pass, the biggest lift here is to try to auto patch the functions we need automatically instead of asking user to import patched method, then we can move to tackling the other TODOs you have

Thanks SO much for all these. I'll get started on them. I tried REALLY hard to figure out how to hook into the existing query, and I couldn't get it to work no matter what I tried. I'll chat with you in slack on it, but I'd love some advice / guidance. I tried a bunch of different angles - but each time I ran into effectively timing issues where we couldn't hook fast enough. Felt like a limitation on how Claude Code's SDK works - but could be a total skill issue on my side.

Hello @codyde, are you still working on this? if not, let's close this, we're trying to clean up the stale PRs

I definitely am! I pushed up a few more commits today that included fixes for some of the other items you mentioned - but im struggling to get through this proxy one. I might need some pairing time to take a look at it together since im less familiar with the functionality.

codyde avatar Oct 20 '25 16:10 codyde