Next.jsプロジェクトへのSentry導入ガイド:ランタイムエラーの検知からパフォーマンス監視まで徹底解説

Development tutorial - IT technology blog
Development tutorial - IT technology blog

ユーザーが「購入手続き」ボタンをクリックしたものの、画面のローディングが30秒間ぐるぐる回り続けてそのままフリーズ——。ユーザーは不満を感じて離脱し、サーバーログにも残っていないため開発者は原因すら把握できない。これはすべてのECサイトにとって典型的な悪夢です。Sentryはまさにこの課題を解決するために生まれました。24時間365日稼働する監視レーダーのように機能し、コードのどこかでエラーが発生すると即座にエラー全体をキャッチしてデバイス情報を記録し、数秒以内にアラートを送信します。

クイックスタート(5分で完了する初期設定)

Next.jsとSentryは非常に相性が良く設計されています。開発チームが提供する自動化ツールがあるため、ゼロから設定ファイルを書く必要はありません。

ステップ1:Sentryウィザードを実行する

プロジェクトのルートディレクトリでターミナルを開き、次のコマンドを実行します。

npx @sentry/wizard@latest -i nextjs

このコマンドを実行するとブラウザが起動し、Sentryアカウントへのログインが求められます。次に、連携したいOrganizationとProjectを選択するだけで、ウィザードが必要なnpmパッケージのインストールと設定ファイルの自動生成をすべて完了してくれます。

ステップ2:自動生成された3つの設定ファイルを確認する

SentryはNext.jsの実行環境ごとに以下の設定ファイルを自動生成します。

  • sentry.client.config.ts: クライアント側(ブラウザ)のJSクラッシュを捕捉します。
  • sentry.server.config.ts: Node.jsランタイム(Server Components、Route Handlers、Server Actions)のエラーを捕捉します。
  • sentry.edge.config.ts: MiddlewareやEdge Runtime上で実行される関数を監視します。

ステップ3:ランタイムエラーをテストする

Client Component内にテスト用エラーを発生させるシンプルなボタンを作成してみましょう。

"use client";

export default function TestErrorButton() {
  return (
    <button
      onClick={() => {
        throw new Error("Sentryテスト: クライアント側からテストエラーを送信!");
      }}
      className="px-4 py-2 bg-red-600 text-white rounded font-medium"
    >
      テストエラーを送信
    </button>
  );
}

ブラウザ上でこのボタンをクリックし、SentryダッシュボードのIssuesタブを開いてみてください。詳細なスタックトレース、ブラウザのバージョン、OS、ユーザーがアクセスしていたURLとともにエラーが記録されていることが確認できます。

フルスタックNext.jsでSentryはどう動くのか?

Next.js App Routerのアーキテクチャはクライアントとサーバーが密接に統合されています。ユーザーからの1つのリクエストは、Middlewareを通過し、Node.jsサーバー上でHTMLがレンダリングされ、Reactクライアント側でハイドレーションされます。トラブルはこれらどのフェーズでも発生する可能性があります。

1. next.configでビルド設定をラップする

Sentryはnext.config.mjs内のwithSentryConfigラッパーを介して、webpack/turbopackのビルドプロセスに直接介入します。

import { withSentryConfig } from "@sentry/nextjs";

const nextConfig = {
  // 既存のNext.js設定
};

export default withSentryConfig(nextConfig, {
  silent: true, // CIビルド時の不要なログを抑制
  org: "my-company",
  project: "ecommerce-nextjs",
  widenClientFileUpload: true,
  hideSourceMaps: true,
});

2. 手動での例外キャッチ(Manual Capture)

未処理の例外(Unhandled Exception)だけに頼るべきではありません。決済APIの呼び出しやDBクエリなどクリティカルな処理では、try...catchで囲み、デバッグしやすいようにメタデータを付与して送信することをおすすめします。

import * as Sentry from "@sentry/nextjs";

export async function fetchUserOrders(userId: string) {
  try {
    const res = await db.query("SELECT * FROM orders WHERE user_id = $1", [userId]);
    return res.rows;
  } catch (error) {
    Sentry.captureException(error, {
      extra: { 
        userId, 
        query: "SELECT * FROM orders WHERE user_id = $1",
        timestamp: new Date().toISOString()
      },
    });
    return null;
  }
}

3. ユーザー情報の紐付け(User Context)

重要顧客から不具合の問い合わせがあった際、そのユーザーのリクエスト履歴を素早く調査できるようにする必要があります。ユーザーがログインした直後に、Sentryへコンテキストを設定しましょう。

Sentry.setUser({
  id: user.id,
  email: user.email,
  username: user.username,
});

分散トレーシングとパフォーマンス監視

システムが完全にクラッシュしていなくても、決済APIのレスポンスに8秒もかかっていればカゴ落ち率は急増します。ここで真価を発揮するのがパフォーマンス監視とDistributed Tracing(分散トレーシング)です。

Distributed Tracing(分散トレーシング)とは?

決済フローは複数のステップで構成されています(ブラウザがリクエスト送信 -> Next.jsサーバーが受信 -> Stripe決済API呼び出し -> Postgresへのデータ書き込み)。分散トレーシングは、この一連のフロー全体を1つのガントチャート(Trace)に集約します。これにより、Stripeの呼び出しに5.2秒かかっているのか、SQLクエリのインデックス不足で詰まっているのかが一目で分かります。

sentry.client.config.tsおよびsentry.server.config.tsでの設定例:

import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  // 開発環境ではトレースを100%取得し、本番環境ではクォータ節約のため10% (0.1) のみ取得
  tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1.0,
  
  // クラッシュ直前のユーザー操作を録画(Session Replay)
  replaysOnErrorSampleRate: 1.0,
  replaysSessionSampleRate: 0.05,
});

送信前に機密データをフィルタリングする

セキュリティコンプライアンスの遵守は必須です。JWTトークン、セッションCookie、クレジットカード番号などをSentryのダッシュボードに送信してはいけません。beforeSendフックを活用してデータをサニタイズしましょう。

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  beforeSend(event) {
    if (event.request?.headers) {
      delete event.request.headers["authorization"];
      delete event.request.headers["cookie"];
    }
    return event;
  },
});

本番運用の実践ノウハウ

数々の商用システムにSentryを導入・運用してきた経験から、特に重要な4つのポイントを紹介します。

  • Source Mapsを正確にアップロードする: CI/CD(GitHub ActionsやVercel)の環境変数にSENTRY_AUTH_TOKENを設定します。Source Mapsがないと、スタックトレースがa.b(c) at 412-df89.js:1:182のように難読化された意味のない表示になってしまいます。
  • データペイロードの検証: イベントコンテキストのデバッグやエラーに付与するJSON文字列のフォーマット確認には、toolcraft.app(JSON Formatter / Regex Testerなど)のようなオンラインツールを使うと生データの加工・確認が迅速に行えます。
  • 適切なアラート閾値を設定する: 些細なWarningごとにメール通知が飛ぶようなアラート疲れ(スパム化)を防ぎましょう。「新規エラーの発生(New Issue)」や「既存エラーが毎分50回以上急増した際」にのみSlack/Discordへ通知するルールを作成するのが効果的です。
  • サンプリングレートでクォータを最適化する: Sentryの無料プランでは月間5,000エラー、10,000トランザクションまでとなっています。月間50万PV規模のWebサイトでは、一般的な記事ページではtracesSampleRateを0.01〜0.02に抑え、Checkout(決済)ページでサンプリング率を引き上げる調整が有効です。
Share: