😎

Next.jsのInstrumentationで実現する高度な監視と分析

に公開

はじめに

Next.jsのエコシステムは常に進化を続けており、アプリケーションの監視や分析のための強力な機能が追加されています。最近、Next.jsにSentryを導入する機会があり、その際にInstrumentationという機能を知ったので、ご紹介します!

Instrumentationとは

Next.jsのInstrumentationは、アプリケーションの起動時に特定のコードを実行できる機能です。これにより、アプリケーション全体の監視、パフォーマンス計測、エラートラッキングなどを設定できます。

https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation

具体的には、プロジェクトのルートディレクトリ(srcがある場合はその中に)に、instrumentation.tsファイルを作成することで、アプリケーションの起動プロセスに独自のコードを注入することができます。

src/instrumentation.ts
export async function register() {
  // アプリケーション起動時に実行されるコード
  console.log('アプリケーションが起動しました')
}

この機能は、v13.2.0で最初に導入され、v15.0.0-RCで安定版 (Stable)となりました。また、Pages RouterとApp Routerのどちらでも使用できるため、プロジェクトの構成に関わらず柔軟に導入することができます。

MiddlewareとInstrumentationの違い

Next.jsには、Middlewareという似たような機能がありますが、InstrumentationとMiddlewareには明確な違いがあります。

Middlewareの特徴

  • リクエスト/レスポンスのライフサイクルに介入する
  • 各リクエストごとに実行される
  • URLベースのルーティングやリダイレクト、ヘッダーの変更などに適している
  • リクエスト処理の「途中」で動作する

Instrumentationの特徴

  • アプリケーションの起動時に一度だけ実行される
  • グローバルな設定や監視の初期化に適している
  • リクエスト単位ではなく、アプリケーション全体に影響を与える
  • アプリケーションの「始まり」で動作する

つまり、Middlewareはリクエストごとの処理に焦点を当てているのに対し、Instrumentationはアプリケーション全体の監視や分析のためのグローバルな設定に適しています。

Instrumentationの実装方法

Instrumentationを実装するには、プロジェクトのルートにinstrumentation.tsファイルを作成し、register関数をエクスポートします。Pages RouterとApp Routerのどちらでも同じ方法で実装できます。

src/instrumentation.ts
export async function register() {
  // アプリケーション起動時に実行されるコード
  console.log('アプリケーションが起動しました')
}

v15.0.0-RC未満では、next.config.tsで実験的機能を有効にする必要があります。

next.config.ts
import type { NextConfig } from "next"

const nextConfig: NextConfig = {
  experimental: {
    instrumentationHook: true
  }
}

export default nextConfig

実際の使いどころ

Instrumentationは様々なユースケースで活用できますが、特に以下のような場面で威力を発揮します。

Sentryによるエラー監視

Sentryは人気のエラー監視ツールですが、Next.jsのInstrumentationを使うことで、アプリケーション全体でのSentryの初期化を簡単に行えます。

https://docs.sentry.io/platforms/javascript/guides/nextjs/

src/instrumentation.ts
import * as Sentry from '@sentry/nextjs'

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('../sentry.server.config')
  }

  if (process.env.NEXT_RUNTIME === 'edge') {
    await import('../sentry.edge.config')
  }
}

export const onRequestError = Sentry.captureRequestError

これにより、アプリケーション全体でエラーが発生した際に、自動的にSentryにレポートされるようになります。従来のように各ページやコンポーネントで個別に初期化する必要がなくなり、コードの重複を避けることができます。

OpenTelemetryによる分散トレーシング

マイクロサービスアーキテクチャやクラウドネイティブアプリケーションでは、分散トレーシングが重要です。OpenTelemetryを使用すると、アプリケーション全体のパフォーマンスを可視化できます。

https://azukiazusa.dev/blog/instrumentation-with-opentelemetry-in-nextjs/

src/instrumentation.ts
import { registerOTel } from '@vercel/otel'
 
export function register() {
  registerOTel({ serviceName: "next-otel" })
}

これにより、アプリケーション内の各操作がトレースされ、ボトルネックの特定や最適化が容易になります。特に複雑なバックエンドシステムとの連携がある場合に有用です。

まとめ

Next.jsのInstrumentationは、アプリケーションの監視や分析のための強力な機能です。Middlewareとは異なり、アプリケーション全体のグローバルな設定に焦点を当てており、Sentryによるエラー監視やOpenTelemetryによる分散トレーシングなど、様々なユースケースで活用できます。

Pages RouterとApp Routerのどちらでも使用できる点も大きなメリットで、プロジェクトの構成に関わらず一貫した監視・分析体制を構築できます。特に大規模なアプリケーションや本番環境での運用を考える際には、Instrumentationを活用することで、より堅牢なモニタリング体制を構築することができます。

最新の情報は常にNext.jsの公式ドキュメントを参照することをお勧めします。

ispec inc.

Discussion