🎷

Next.jsのinstrumentationHookとは

2024/12/08に公開

どうもこんにちはけんやです。
みなさんは Next.js ディレクトリの root に置くファイルと言ったら何を思い浮かべますか? 多くの方がmiddleware を思い浮かべると思いますが、同様にディレクトリの root にファイルを置くinstrumentationHook について紹介したいと思います。

はじめに

この記事は「Commune Advent Calendar 2024」シリーズ 2 の 8 日目の記事です。

Next.js の instrumentationHook 機能とは

instrumentationHook について

機能自体をinstrumentationHook と呼んできましたがこれは機能が experimental だった時に next.config に書くオプションだった時の名称です。Next.js のv15.0.0-RCで stable となり、ドキュメントでは Instrumentation という名称で説明がされているので、以降は Instrumentation と呼びます。

Instrumentation の機能

Instrumentation の機能を使用すると、 Next.js のサーバインスタンスを起動した時に一度だけ実行される処理を定義することができます。

たとえば Next.js のドキュメントで紹介されているのは、OpenTelemetry を使用したセットアップ例です。このような処理を Instrumentation で行うことで、サーバの起動時に一度だけトレースの設定を行うことができます。

Instrumentation の使い方としてはディレクトリのrootか、またはsrcディレクトリを採用してる場合はその中にinstrumentation.tsというファイルを作成します。そこに Next.js のサーバが起動した際同時に一度だけ実行したい処理を記述します。下記は OpenTelemetry のセットアップを行う例です。

instrumentation.ts
import { registerOTel } from "@vercel/otel";

export function register() {
  registerOTel("next-app");
}

これによりregister関数がサーバの起動時に一度だけ実行されます(Instrumentation を使用した OpenTelemetry セットアップのコード例はGitHub の exampleに載っています)。

コミューンではフィーチャーフラグのクライアントの初期化に Instrumentation の機能を使用しています。

Instrumentation 使用の際の注意点

Instrumentation の実行はすべての環境で呼び出されます。つまりregister関数に実装した処理が特定のランタイムに依存するようだとその処理が動かなくなってしまします。そのため、特定のランタイムでしか動作しないような処理は、register関数内でそのランタイムをチェックするような処理を書く必要があります。

instrumentation.ts
export async function register() {
  // Node.js の場合のみ実行
  if (process.env.NEXT_RUNTIME === "nodejs") {
    await import("./instrumentation-node");
  }

  // Edge の場合のみ実行
  if (process.env.NEXT_RUNTIME === "edge") {
    await import("./instrumentation-edge");
  }
}

実際に私もこの点を考慮せずに実装して意図せず動作が正常に行われないということがありました。そのため、この点には注意が必要です。

まとめ

Next.js の Instrumentation の機能を紹介してきましたがいかがでしたでしょうか?

余談ですが Instrumentation の単語の意味は「楽器の使用」的な意味だと思っていたのですが、エンジニアリングの文脈で使用すると「計装」という訳語になるそうです(筆者調べ)。以上、豆知識でした。

最後までお読みいただきありがとうございました!

GitHubで編集を提案
コミューン株式会社

Discussion