Sentryを使ってみよう - Webアプリのエラー監視を始める入門

intermediate | 65分 で読める | 2026.04.10

公式ドキュメント

この記事の要点

• 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プロジェクトの作成

  1. https://sentry.io にサインアップ
  2. ProjectsCreate Project
  3. プラットフォームを選択 (React / Node.js それぞれ作成)
  4. 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 などの環境タグ。ダッシュボードで絞り込みできます。

エラー発生前のユーザー操作・ネットワーク・コンソールログの履歴。デバッグに非常に役立ちます。

注意: 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 Tokensproject:releases 権限のあるトークンを作り直してください。

イベントが多すぎてクォータを超える

無料プランは月間イベント数に上限があります。tracesSampleRate を 1.0 → 0.1 に下げる、ignoreErrors で既知のノイズを除外しましょう。

Sentry.init({
  ignoreErrors: ['ResizeObserver loop limit exceeded'],
});

ローカル開発でもイベントが送られる

environmentenabled: import.meta.env.PROD で本番のみ送信に絞ると、ノイズを減らせます。

ベストプラクティス

  • 環境を分ける: development / staging / production を必ず区別
  • リリースを必ず付ける: regression判定とソースマップ紐付けに必須
  • PIIを送らない: メアドや個人情報は beforeSend で削除、もしくは sendDefaultPii: false
  • ErrorBoundaryで包む: Reactではコンポーネント単位のフォールバックを用意
  • Slack/PagerDutyに通知: 重要Issueが発生したら即座にチームに知らせる
  • アラートルール: 「新規Issue」「Regression」「特定環境のエラー急増」をトリガーに
  • Issueにオーナーを設定: コードオーナー機能で自動アサイン

次のステップ(発展課題)

  1. Session Replay を本格活用してユーザー操作を再現
  2. Cron Monitorでバッチジョブの失敗を検知
  3. Profilingでホットパスを特定
  4. Distributed Tracingでフロント→バック→DBまで一気通貫に追う
  5. Source Mapsの自動化をCIパイプラインに組み込む
  6. Uptime Monitoringで死活監視
  7. 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-tracebaggage ヘッダが自動付与され、バックエンド側の @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など多数の連携が用意されています。チーム規模やオンコール体制に合わせて、必要十分なアラートだけを設定するのがコツです。アラートが多すぎると通知疲れで重要な障害を見逃しやすくなるので、四半期に一度はアラートルールを棚卸しすると良いでしょう。

参考リソース

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

メールで無料相談する
← 一覧に戻る