sentry-span-streaming について
JavaScript の Sentry プロジェクトをトランザクション単位のトレースから span streaming へ移行するためのスキルです。対応する JavaScript SDK 環境で、設定の確認、変更、検証を案内します。
主な機能
- 01プラットフォーム、SDK バージョン、トレース設定の検出
- 02ブラウザーおよびサーバー SDK でのストリーミング有効化
- 03span コールバックとフィルターの調整
- 04プロファイリング設定の移行
- 05ビルドと実行時の動作確認
活用シーン
- 01Sentry プロジェクトを span のストリーミング配信へ切り替え
- 02ストリーミング用に beforeSendSpan を更新
- 03beforeSendTransaction の処理を置き換え
- 04静的モードへのフォールバック警告の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ getsentry/ sentry-for-ai --skill sentry-span-streamingインストール後、Claude Code で/sentry-span-streamingを入力して読み込まれたか確認します。
詳細
Sentry スパンストリーミングへの移行
デフォルトのトランザクションベースのトレースライフサイクル(static)からスパンストリーミング(stream)に移行します。スパンストリーミングでは、スパンは最後に1つのトランザクションにまとめられるのではなく、完了時に複数のバッチで送信されます。
このスキルを使うとき
- ユーザーが「スパンストリーミングを有効にして」または「スパンストリーミングに移行して」と依頼した場合
- トランザクションベースからストリーミングによるスパン配信に切り替えたい場合
traceLifecycle、spanStreamingIntegration、またはwithStreamedSpanに言及した場合- スパン配信の遅延を減らしたい場合、またはスパン単位で処理したい場合
対応プラットフォーム
| プラットフォーム | 状態 |
|---|---|
| JavaScript(Browser、Node.js、Bun、Deno、Cloudflare) | 対応済み |
| Python | 未対応 |
| Ruby | 未対応 |
| Go | 未対応 |
| その他の SDK | 未対応 |
ユーザーのプロジェクトで対応 SDK を使用していない場合、スパンストリーミングは現在 JavaScript SDK でのみ利用可能であることを伝え、ここで終了してください。
フェーズ 1:検出
ユーザーのプラットフォーム、SDK バージョン、および現在のトレーシング設定を特定します。
1.1 プラットフォームと SDK の検出
# Check for JavaScript Sentry packages
cat package.json 2>/dev/null | grep -E '"@sentry/'
# Check for Python Sentry
cat requirements.txt setup.py pyproject.toml 2>/dev/null | grep -i sentry
# Check for Ruby Sentry
cat Gemfile 2>/dev/null | grep sentry
# Check for Go Sentry
cat go.mod 2>/dev/null | grep sentry
対応していない Sentry SDK が検出された場合、ユーザーのプラットフォームではスパンストリーミングをまだ利用できないことを伝えてください。
1.2 JavaScript 環境の検出
# Detect if browser, server, or both
grep -rn "from '@sentry/browser'\|from '@sentry/react'\|from '@sentry/vue'\|from '@sentry/angular'\|from '@sentry/svelte'\|from '@sentry/nextjs'\|from '@sentry/nuxt'\|from '@sentry/sveltekit'\|from '@sentry/remix'\|from '@sentry/solidstart'\|from '@sentry/astro'\|from '@sentry/react-router'" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.mjs" -l 2>/dev/null | head -20
grep -rn "from '@sentry/node'\|from '@sentry/bun'\|from '@sentry/deno'\|from '@sentry/cloudflare'" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.mjs" -l 2>/dev/null | head -20
1.3 既存の Sentry 設定を検索
# Find Sentry.init calls
grep -rn "Sentry\.init\|init({" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.mjs" -l 2>/dev/null | head -20
# Find beforeSendSpan usage
grep -rn "beforeSendSpan" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.mjs" -l 2>/dev/null
# Find beforeSendTransaction usage
grep -rn "beforeSendTransaction" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.mjs" -l 2>/dev/null
# Find ignoreSpans usage
grep -rn "ignoreSpans" --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" --include="*.mjs" -l 2>/dev/null
1.4 環境の分類
検出結果に基づいて、各 Sentry.init 呼び出しを次のように分類します。
| 環境 | パッケージ | 移行方法 |
|---|---|---|
| ブラウザー | @sentry/browser、@sentry/react、@sentry/vue、@sentry/angular、@sentry/svelte | spanStreamingIntegration() を追加 |
| サーバー | @sentry/node、@sentry/bun、@sentry/deno、@sentry/cloudflare | traceLifecycle: 'stream' を追加 |
| フレームワーク(両方) | @sentry/nextjs、@sentry/nuxt、@sentry/sveltekit、@sentry/remix、@sentry/astro、@sentry/solidstart、@sentry/react-router | クライアントとサーバーの設定を個別に移行 |
フェーズ 2:移行(JavaScript)
前提条件: Sentry JavaScript SDK >=10.53.1 を使用し、トレーシング(tracesSampleRate または tracesSampler の設定)が有効であること。
Sentry.init の各呼び出しに変更を適用します。フェーズ 1 で特定した各ファイルを順番に確認してください。
2.1 スパンストリーミングを有効化
サーバーサイド SDK
Sentry.init() に traceLifecycle: 'stream' を追加します。
// Before
Sentry.init({
dsn: '...',
tracesSampleRate: 1.0,
});
// After
Sentry.init({
dsn: '...',
tracesSampleRate: 1.0,
traceLifecycle: 'stream',
});
ブラウザーサイド SDK
Sentry.spanStreamingIntegration() を integrations 配列に追加します。このインテグレーションにより traceLifecycle: 'stream' が自動的に有効になるため、手動で設定する必要はありません。
// Before
Sentry.init({
dsn: '...',
integrations: [
Sentry.browserTracingIntegration(),
],
tracesSampleRate: 1.0,
});
// After
Sentry.init({
dsn: '...',
integrations: [
Sentry.spanStreamingIntegration(),
Sentry.browserTracingIntegration(),
],
tracesSampleRate: 1.0,
});
他のインテグレーションに対する spanStreamingIntegration() の順序は問いません。
フレームワーク SDK(クライアント+サーバー)
クライアント設定ファイルにはブラウザー向けの移行を適用し、サーバー設定ファイルにはサーバー向けの移行を適用します。一般的なパターンは次のとおりです。
| フレームワーク | クライアント設定 | サーバー設定 |
|---|---|---|
| Next.js | sentry.client.config.ts | sentry.server.config.ts、sentry.edge.config.ts |
| Nuxt | モジュール内のクライアントサイド Sentry.init | モジュール内のサーバーサイド Sentry.init |
| SvelteKit | src/hooks.client.ts | src/hooks.server.ts |
| Remix | entry.client.tsx | entry.server.tsx |
| Astro | クライアントサイドの初期化 | サーバーサイドの初期化 |
2.2 beforeSendSpan を移行する
beforeSendSpan コールバックを使用している場合、ストリーミングモードで動作させるには、Sentry.withStreamedSpan() でラップする必要があります。このラッパーがない場合、SDK は静的モードにフォールバックします。
コールバックの形式も変更されています。
descriptionはnameになりましたdataはattributesになりました- スパンオブジェクトは
SpanJSONではなくStreamedSpanJSONです
// Before (static mode)
Sentry.init({
beforeSendSpan: (span) => {
if (span.description?.includes('/health')) {
span.description = '[filtered]';
}
// 'data' contains span attributes
delete span.data?.['http.request.body'];
return span;
},
});
// After (streaming mode)
Sentry.init({
beforeSendSpan: Sentry.withStreamedSpan((span) => {
if (span.name?.includes('/health')) {
span.name = '[filtered]';
}
// 'attributes' replaces 'data'
if (span.attributes) {
delete span.attributes['http.request.body'];
}
return span;
}),
});
コールバックの主な違い:
静的(SpanJSON) | ストリーミング(StreamedSpanJSON) |
|---|---|
span.description | span.name |
span.data(処理済みの属性) | span.attributes(生の属性) |
span.timestamp(終了時刻) | span.end_timestamp |
span.status(任意の文字列) | span.status('ok' または 'error') |
span.op | span.attributes['sentry.op'] |
beforeSendSpan から null を返しても、スパンは破棄されません。戻り値は無視され、警告がログに記録されます。
2.3 beforeSendTransaction を削除または置き換える
beforeSendTransaction はストリーミングモードでは効果がありません。スパンはトランザクションにまとめられず、個別に送信されます。
// Before
Sentry.init({
beforeSendTransaction: (event) => {
// This entire callback is ignored in streaming mode
if (event.transaction === '/health') {
return null;
}
return event;
},
});
beforeSendTransaction の用途に応じた移行方法:
| 用途 | ストリーミングでの置き換え |
|---|---|
| 名前やルートでスパンを破棄する | ignoreSpans オプションを使用する |
| 送信前にスパンデータを変更する | withStreamedSpan と組み合わせて beforeSendSpan を使用する |
| トランザクション名でフィルタリングする | 文字列または RegExp パターンを指定して ignoreSpans を使用する |
| トランザクションにタグやコンテキストを追加する | withStreamedSpan と組み合わせて beforeSendSpan を使用する |
ロジックの移行後、Sentry.init() から beforeSendTransaction オプションを削除してください。
2.4 ignoreSpans を設定する(任意)
ignoreSpans は静的モードとストリーミングモードの両方で機能しますが、フィルターが評価されるタイミングはスパンのライフサイクル内で異なります。
- ストリーミングモード: スパンの開始時に評価されます。スパン開始時に利用できるデータ、つまりスパン名と作成時に設定された属性のみが考慮されます。
- 静的モード: ルートスパンの終了時に評価されます。その時点で利用できるデータ、つまりスパン名と属性のみが考慮されます。
どちらのモードでも、一致したスパンは記録も送信もされません。ストリーミングモードではスパンの開始時点で照合される場合があるため、スパン名とスパン開始時に設定された属性のみが確実に利用できます。スパンのライフタイム中に後から追加される属性には依存しないでください。
Sentry.init({
traceLifecycle: 'stream',
ignoreSpans: [
// String match against span name
'/health',
'/ready',
// RegExp match against span name
/^OPTIONS /,
// Object filter — all conditions must match
{
op: 'middleware.handle',
name: /^corsMiddleware/,
},
// Filter by attributes (string = substring match, RegExp for patterns)
{
op: 'http.server',
attributes: {
'http.route': /^\/internal\//,
},
},
],
});
フィルターオブジェクトのプロパティ:
| プロパティ | 型 | 照合対象 |
|---|---|---|
name | string | RegExp | スパン名(description) |
op | string | RegExp | スパンのオペレーション |
attributes | Record<string, string | RegExp | number | boolean | Array> | スパン属性 |
フィルターオブジェクトで複数のプロパティを指定した場合、スパンを無視するにはすべてが一致する必要があります。
2.5 ブラウザプロファイリングを設定する(任意)
ブラウザでスパンストリーミングを使用する場合は、従来の profilesSampleRate ではなく、v2 のプロファイリングオプションを使用してください。従来のオプションは非推奨であり、スパンストリーミングのライフサイクルと連携しません。
browserProfilingIntegration() を追加し、2 つの v2 オプションを設定します。
// Before (legacy profiling — do NOT use with span streaming)
Sentry.init({
integrations: [
Sentry.browserTracingIntegration(),
],
tracesSampleRate: 1.0,
profilesSampleRate: 0.5, // deprecated
});
// After (v2 profiling with span streaming)
Sentry.init({
integrations: [
Sentry.spanStreamingIntegration(),
Sentry.browserTracingIntegration(),
Sentry.browserProfilingIntegration(),
],
tracesSampleRate: 1.0,
profileSessionSampleRate: 1.0,
profileLifecycle: 'trace',
});
v2 のプロファイリングオプション:
| オプション | 型 | 説明 |
|---|---|---|
profileSessionSampleRate | number(0~1) | プロファイリングが有効になるユーザーセッションの割合です。デフォルト:0(無効)。 |
profileLifecycle | 'trace' | 'manual' | 'trace':サンプリングされたルートスパンが存在する間、プロファイラーが自動的に実行されます。'manual':Sentry.uiProfiler.startProfiler() / stopProfiler() でプロファイラーを明示的に開始/停止します。デフォルト:'manual'。 |
profileLifecycle: 'trace' を使用するには、トレーシングを有効にする必要があります(tracesSampleRate または tracesSampler)。ルートスパンが開始するとプロファイラーが起動し、サンプリングされたルートスパンがなくなると停止します。プロファイルチャンクは 60 秒ごと、または最後のルートスパンが終了したときに個別に送信されます。
従来のオプションと v2 のオプションを混在させないでください。profilesSampleRate が設定されている場合、profileSessionSampleRate は効果がなく、SDK は警告をログに記録します。
フェーズ 3:検証
変更を適用した後、移行が正しく動作することを確認してください。
3.1 ビルドの確認
# TypeScript check
npx tsc --noEmit 2>&1 | head -30
# Build
npm run build 2>&1 | tail -20
3.2 実行時の検証
ブラウザーの開発者ツールまたはサーバーログで、ユーザーに次の点を確認するよう案内してください。
- ネットワークタブを確認する:スパンエンベロープが、トランザクションエンベロープではなく、コンテンツタイプ
application/vnd.sentry.items.span.v2+jsonの個別のリクエストとして表示されること - Sentry ダッシュボードを確認する:トランザクション全体の完了を待たずに、スパンの完了後すぐに Traces ビューに表示されること
- フォールバック警告を確認する:SDK が静的モードにフォールバックするという警告をログに記録する場合、
beforeSendSpanコールバックにwithStreamedSpanラッパーがない可能性があります
3.3 よくある問題
| 症状 | 原因 | 修正方法 |
|---|---|---|
| SDK が静的モードにフォールバックする | beforeSendSpan が withStreamedSpan でラップされていない | コールバックをラップします:Sentry.withStreamedSpan(callback) |
beforeSendTransaction が呼び出されない | ストリーミングモードでは想定どおりの動作です | ロジックを beforeSendSpan または ignoreSpans に移行します |
| スパンが依然としてトランザクションとして届く | traceLifecycle が設定されていないか、インテグレーションがありません | サーバー:traceLifecycle: 'stream' を追加します。ブラウザー:spanStreamingIntegration() を追加します |
span.description で型エラーが発生する | StreamedSpanJSON では description ではなく name が使われています | コールバック内で span.description を span.name に変更します |
span.data で型エラーが発生する | StreamedSpanJSON では data ではなく attributes が使われています | コールバック内で span.data を span.attributes に変更します |
profileSessionSampleRate が効果を発揮しない | 従来の profilesSampleRate も設定されています | profilesSampleRate を削除し、profileSessionSampleRate と profileLifecycle のみを使用します |
クイックリファレンス(JavaScript)
最小限のサーバー設定
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: '__DSN__',
tracesSampleRate: 1.0,
traceLifecycle: 'stream',
});
最小限のブラウザー設定
import * as Sentry from '@sentry/browser';
Sentry.init({
dsn: '__DSN__',
integrations: [
Sentry.spanStreamingIntegration(),
Sentry.browserTracingIntegration(),
],
tracesSampleRate: 1.0,
});
プロファイリングを使用するブラウザー設定
import * as Sentry from '@sentry/browser';
Sentry.init({
dsn: '__DSN__',
integrations: [
Sentry.spanStreamingIntegration(),
Sentry.browserTracingIntegration(),
Sentry.browserProfilingIntegration(),
],
tracesSampleRate: 1.0,
profileSessionSampleRate: 1.0,
profileLifecycle: 'trace',
});
移行チェックリスト
- SDK のバージョンが
>=10.53.1 - サーバー設定:
traceLifecycle: 'stream'を追加済み - ブラウザー設定:
spanStreamingIntegration()を追加済み -
beforeSendSpanコールバックをSentry.withStreamedSpan()でラップ済み -
beforeSendSpanコールバックを更新済み:description->name、data->attributes -
beforeSendTransactionのロジックをbeforeSendSpanまたはignoreSpansに移行済み - 設定から
beforeSendTransactionを削除済み - (プロファイリングを使用する場合)
profilesSampleRateをprofileSessionSampleRateとprofileLifecycleに置き換え済み - (プロファイリングを使用する場合)
browserProfilingIntegration()をインテグレーションに追加済み - 型エラーなしでビルドが成功する
- Sentry ダッシュボードにスパンが表示される