この記事の要点
• SentryをReact・Node.jsに導入してエラーを自動収集
• ソースマップ・リリース管理・パフォーマンスモニタリングの設定
• ユーザーコンテキストとブレッドクラムによる素早いデバッグ
このチュート��アルで学ぶこと
- Sentryアカウントとプロジェクト作成
- React (Vite) でのフロントエンドSDK導入
- Node.js/Expressでのバックエンド導入
- ソースマップアップロードでスタックトレースを読みやすく
- リリース管理とデプロイトラッキング
- パフォーマンスモニタリング(トランザクション)
- ユーザーコンテキストとブレッドクラム
Sentryは本番環境で発生したエラー・例外・パフォーマンス劣化を自動収集し、開発者に通知する監視SaaSです。フロントエンドとバックエンドを横断してトレースできるのが強みです。
前提条件・必要な環境
- Node.js 20以上
- 既存のReactアプリ もしくは Express API (新規でもOK)
- Sentryアカウント (https://sentry.io 無料プランあり)
- Git管理されたプロジェクト
インストール / セットアップ
Sentryプロジェクトの作成
- https://sentry.io にサインアップ
Projects→Create Project- プラットフォームを選択 (React / Node.js それぞれ作成)
- DSNが発行されるのでメモする (例:
https://abc123@o0.ingest.sentry.io/123456)
React (Vite) への導入
npm install @sentry/react
Node.js (Express) への導入
npm install @sentry/node @sentry/profiling-node
基本概念
ポイント: DSNはプロジェクト固有の接続URLで、EventとIssueのグルーピングを理解することがSentry活用の第一歩です。
DSN (Data Source Name)
プロジェクト固有の接続URL。クライアントから送信されるイベントの宛先になります。publicな値ですが、レート制限やプロジェクト識別に使われるため漏洩に注意。
Event / Issue
- Event: 1件のエラー発生
- Issue: 同一のスタックトレースを持つEventをグルーピングしたもの
Release
デプロイされたコードのバージョン識別子。コミットSHAなどを使うのが一般的。
Environment
production / staging / development などの環境タグ。ダッシュボードで絞り込みできます。
Breadcrumb
エラー発生前のユーザー操作・ネットワーク・コンソールログの履歴。デバッグに非常に役立ちます。
注意: tracesSampleRateを本番で1.0にすると大量のデータが送信されます。本番では0.1〜0.3程度に設定し、コストを抑えましょう。
ステップバイステップ実装
Step 1: フロントエンド(React)の初期化
src/main.tsx:
import React from 'react';
import ReactDOM from 'react-dom/client';
import * as Sentry from '@sentry/react';
import App from './App';
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
release: import.meta.env.VITE_APP_VERSION,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration({
maskAllText: true,
blockAllMedia: true,
}),
],
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<Sentry.ErrorBoundary fallback={<p>エラーが発生しました</p>}>
<App />
</Sentry.ErrorBoundary>
</React.StrictMode>,
);
.env.local(Vite 5 の環境変数規約に従う):
VITE_SENTRY_DSN=https://xxx@o0.ingest.sentry.io/yyy
VITE_APP_VERSION=1.0.0
Step 2: 意図的にエラーを送信して動作確認
src/App.tsx:
import * as Sentry from '@sentry/react';
export default function App() {
return (
<div>
<h1>Sentry Demo</h1>
<button onClick={() => { throw new Error('Test error from button'); }}>
Throw error
</button>
<button onClick={() => Sentry.captureMessage('Hello from Sentry')}>
Send message
</button>
</div>
);
}
ボタンをクリックすると、数秒以内にSentryのIssues画面に表示されます。
Step 3: ユーザーコンテキストを付与
ログイン処理が成功したタイミングで:
import * as Sentry from '@sentry/react';
Sentry.setUser({
id: user.id,
email: user.email,
username: user.name,
});
ログアウト時には Sentry.setUser(null) でクリアします。
Step 4: バックエンド(Express)に導入
src/server.ts:
import * as Sentry from '@sentry/node';
import { nodeProfilingIntegration } from '@sentry/profiling-node';
import express from 'express';
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
release: process.env.APP_VERSION,
integrations: [nodeProfilingIntegration()],
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
});
const app = express();
app.get('/', (_req, res) => {
res.send('Hello world');
});
app.get('/debug-sentry', () => {
throw new Error('Backend test error');
});
// Sentryのエラーハンドラは最後に登録する
Sentry.setupExpressErrorHandler(app);
app.use((err: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
res.statusCode = 500;
res.end(`Internal Server Error\nSentry ID: ${(res as any).sentry}`);
});
app.listen(3000, () => {
console.log('Server listening on http://localhost:3000');
});
/debug-sentry を叩くとサーバーエラーがSentryに記録されます。
Step 5: ソースマップのアップロード
本番ビルドでminifyされたコードのスタックトレースを読みやすくするため、ソースマップをSentryに送ります。Vite の場合:
npm install -D @sentry/vite-plugin
vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { sentryVitePlugin } from '@sentry/vite-plugin';
export default defineConfig({
build: {
sourcemap: true,
},
plugins: [
react(),
sentryVitePlugin({
org: 'your-org-slug',
project: 'your-project-slug',
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
],
});
CIで SENTRY_AUTH_TOKEN を環境変数として渡します。npm run build 時にソースマップが自動アップロード&削除されます。
Step 6: リリース管理
リリース名にコミットSHAを使うのがおすすめ:
export VITE_APP_VERSION=$(git rev-parse --short HEAD)
npm run build
Sentry CLI を使ってデプロイを通知することもできます:
npm install -g @sentry/cli
sentry-cli releases new "$VITE_APP_VERSION"
sentry-cli releases set-commits "$VITE_APP_VERSION" --auto
sentry-cli releases finalize "$VITE_APP_VERSION"
sentry-cli releases deploys "$VITE_APP_VERSION" new -e production
これでIssueに「どのリリースで初出か」「regressionか」が記録されます。
Step 7: パフォーマンスモニタリング
tracesSampleRate を設定するだけで、各HTTPリクエスト/ナビゲーションがTransactionとして自動収集されます。
カスタムスパンを追加したい場合:
import * as Sentry from '@sentry/node';
await Sentry.startSpan(
{ name: 'expensive-job', op: 'task' },
async () => {
await doExpensiveWork();
},
);
Step 8: 機微情報のフィルタリング
beforeSend フックでイベントを加工・破棄できます。
Sentry.init({
dsn: process.env.SENTRY_DSN,
beforeSend(event) {
if (event.request?.headers) {
delete event.request.headers['authorization'];
delete event.request.headers['cookie'];
}
return event;
},
});
完成コード全体
my-app/
├── src/
│ ├── main.tsx # フロント初期化
│ └── App.tsx # テスト用ボタン
├── server/
│ └── server.ts # バックエンド + Sentry
├── vite.config.ts # ソースマップアップロード設定
└── .env.local # DSN
.env.local はGit管理しないこと。本番のDSNとAuth Tokenはホスティングサービスのシークレットに保存します。
よくあるエラーと対処
スタックトレースが minify されたまま
ソースマップのアップロードに失敗しているか、リリース名がフロントとアップロード時で一致していません。release の値を環境変数で統一しましょう。
SENTRY_AUTH_TOKEN 関連エラー
トークンがCIに正しく設定されていない、もしくは権限不足です。Sentryの Settings → Auth Tokens で project:releases 権限のあるトークンを作り直してください。
イベントが多すぎてクォータを超える
無料プランは月間イベント数に上限があります。tracesSampleRate を 1.0 → 0.1 に下げる、ignoreErrors で既知のノイズを除外しましょう。
Sentry.init({
ignoreErrors: ['ResizeObserver loop limit exceeded'],
});
ローカル開発でもイベントが送られる
environment や enabled: import.meta.env.PROD で本番のみ送信に絞ると、ノイズを減らせます。
ベストプラクティス
- 環境を分ける: development / staging / production を必ず区別
- リリースを必ず付ける: regression判定とソースマップ紐付けに必須
- PIIを送らない: メアドや個人情報は
beforeSendで削除、もしくはsendDefaultPii: false - ErrorBoundaryで包む: Reactではコンポーネント単位のフォールバックを用意
- Slack/PagerDutyに通知: 重要Issueが発生したら即座にチームに知らせる
- アラートルール: 「新規Issue」「Regression」「特定環境のエラー急増」をトリガーに
- Issueにオーナーを設定: コードオーナー機能で自動アサイン
次のステップ(発展課題)
- Session Replay を本格活用してユーザー操作を再現
- Cron Monitorでバッチジョブの失敗を検知
- Profilingでホットパスを特定
- Distributed Tracingでフロント→バック→DBまで一気通貫に追う
- Source Mapsの自動化をCIパイプラインに組み込む
- Uptime Monitoringで死活監視
- GitHub連携でIssueにコミットを自動リンク
まとめ
実践メモ: ソースマップをアップロードすると、minified コードのスタックトレースが元のソースコードで表示され、デバッグ効率が劇的に向上します。
Sentryを入れるだけで、本番のエラー対応の質が一段階上がります。
- ユーザーから「動かない」と言われる前に検知できる
- スタックトレース・ブレッドクラム・リプレイで再現が早い
- リリースとIssueが紐付くので原因コミット特定が早い
- フロントとバックを横断したパフォーマンス分析もできる
「動いた、デプロイした、終わり」ではなく、本番で起きていることを観測する文化を作る第一歩としてSentryは最適です。
補足: 主要フレームワーク向けSDK
Sentryは多数のフレームワーク向けSDKを提供しています。Reactの代わりに以下を選ぶことも多いです。
| フレームワーク | パッケージ |
|---|---|
| Next.js | @sentry/nextjs |
| Remix | @sentry/remix |
| Vue 3 | @sentry/vue |
| Svelte / SvelteKit | @sentry/sveltekit |
| Angular | @sentry/angular |
| Express / Node | @sentry/node |
| Bun | @sentry/bun |
| Deno | @sentry/deno |
例えばNext.jsの場合は専用ウィザードがあります。
npx @sentry/wizard@latest -i nextjs
sentry.client.config.ts sentry.server.config.ts sentry.edge.config.ts が自動生成され、ApiRoutes・Middleware・Edge Functions すべての例外を捕捉できる構成になります。
補足: GitHub Actions でのソースマップアップロード
CIから自動でソースマップを送る最小例です。
name: deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: your-org
SENTRY_PROJECT: your-project
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build
- run: npx sentry-cli sourcemaps inject ./dist
- run: npx sentry-cli sourcemaps upload --release="${GITHUB_SHA}" ./dist
@sentry/vite-plugin を使っていれば inject / upload は自動なので、明示的に呼ぶ必要はありません。
補足: Distributed Tracing
フロントとバックを別々のプロジェクトに分けてもSentryは1つのトレースとして繋いで表示できます。フロントの fetch リクエストに sentry-trace と baggage ヘッダが自動付与され、バックエンド側の @sentry/node がそれを引き継ぐ仕組みです。
設定としては、フロントの tracePropagationTargets にバックエンドのオリジンを追加します。
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
integrations: [Sentry.browserTracingIntegration()],
tracePropagationTargets: [
'localhost',
/^https:\/\/api\.example\.com\//,
],
tracesSampleRate: 1.0,
});
これで「ボタンをクリック → API呼び出し → DBクエリ」という一連の流れが1つのトレース図として可視化され、どこが遅いのか・どこで例外が起きたのかを瞬時に把握できます。
補足: アラートとSlack連携
Sentryのダッシュボードから Alerts → Create Alert で「新規Issue発生時にSlackへ通知」のような自動化が設定できます。重要度の高いプロジェクトでは、PagerDutyやOpsgenie連携を入れてオンコール体制と統合することも一般的です。
代表的なアラートテンプレート:
- 新規Issue: 過去に発生していない種類のエラーが起きた瞬間に通知
- Regression: 解決済みにしたIssueが再発したら通知
- エラー数の急増: 1時間あたりのEvent数が閾値を超えたら通知
- 特定タグ:
environment:productionかつlevel:fatalのときだけ通知 - パフォーマンス劣化: P95レスポンスタイムが基準を超えたら通知
通知先はSlack、Microsoft Teams、Discord、メール、Webhookなど多数の連携が用意されています。チーム規模やオンコール体制に合わせて、必要十分なアラートだけを設定するのがコツです。アラートが多すぎると通知疲れで重要な障害を見逃しやすくなるので、四半期に一度はアラートルールを棚卸しすると良いでしょう。
参考リソース
- Sentry Documentation
- Sentry GitHub Organization
- Sentry React SDK Guide
- Sentry Node.js SDK Guide
- Sentry CLI Reference