OpenTelemetry
可観測性は、Next.js アプリの動作とパフォーマンスを理解し、最適化するために極めて重要です。
アプリケーションがより複雑になるにつれ、発生する可能性のある問題を特定し、診断することが困難になります。ログやメトリクスなどの可観測性ツールを活用することで、開発者はアプリケーションの動作に関する洞察を得て、最適化の領域を特定できます。可観測性により、開発者は重大な問題になる前に積極的に問題に対処し、より良いユーザーエクスペリエンスを提供できます。そのため、パフォーマンスを向上させ、リソースを最適化し、ユーザーエクスペリエンスを強化するために、Next.js アプリケーションで可観測性を使用することを強くお勧めします。
アプリを計装するには OpenTelemetry の使用をお勧めします。 これはプラットフォームに依存しないアプリ計装の方法であり、コードを変更せずに可観測性プロバイダーを変更できます。 OpenTelemetry とその仕組みの詳細については、OpenTelemetry 公式ドキュメントをお読みください。
このドキュメントでは、Span、Trace、Exporter などの用語を使用しており、これらはすべて OpenTelemetry 可観測性プライマー で見つけることができます。
Next.js は OpenTelemetry 計装を最初から サポートしており、Next.js 自体をすでに計装しています。
OpenTelemetry を有効にすると、getStaticProps
のようなすべてのコードを自動的に有用な属性を持つ spans でラップします。
はじめに
OpenTelemetry は拡張可能ですが、適切にセットアップするのはかなり冗長になる可能性があります。
そのため、迅速に始められるよう @vercel/otel
パッケージを用意しました。
@vercel/otel
の使用
開始するには、以下のパッケージをインストールします:
次に、プロジェクトのルートディレクトリ(または src
フォルダを使用している場合はその中)に、カスタム instrumentation.ts
(または .js
)ファイルを作成します:
これで instrumentation.ts
で NodeSDK
を初期化できます。
@vercel/otel
とは異なり、NodeSDK
はエッジランタイムと互換性がないため、process.env.NEXT_RUNTIME === 'nodejs'
の場合にのみインポートされることを確認する必要があります。Node を使用する場合のみ条件付きでインポートする新しいファイル instrumentation.node.ts
を作成することをお勧めします:
これは @vercel/otel
を使用するのと同等ですが、@vercel/otel
では公開されていない一部の機能を変更および拡張することが可能です。エッジランタイムのサポートが必要な場合は、@vercel/otel
を使用する必要があります。
インストゥルメンテーションのテスト
OpenTelemetry トレースをローカルでテストするには、互換性のあるバックエンドを持つ OpenTelemetry コレクターが必要です。 OpenTelemetry 開発環境の使用をお勧めします。
正常に動作する場合、GET /requested/pathname
というラベルの付いたルートサーバースパンが表示されるはずです。
その特定のトレースからの他のすべてのスパンは、その下にネストされます。
Next.js はデフォルトで出力されるよりも多くのスパンをトレースします。
より多くのスパンを表示するには、NEXT_OTEL_VERBOSE=1
を設定する必要があります。
デプロイメント
OpenTelemetry コレクターの使用
OpenTelemetry コレクターを使用してデプロイする場合、@vercel/otel
を使用できます。
Vercel と自己ホストの両方で動作します。
Vercel へのデプロイ
OpenTelemetry が Vercel ですぐに使えるように設定しました。
Vercel ドキュメントに従って、プロジェクトを可観測性プロバイダーに接続してください。
自己ホスティング
他のプラットフォームへのデプロイも簡単です。Next.js アプリからテレメトリデータを受信および処理するために、独自の OpenTelemetry コレクターを起動する必要があります。
OpenTelemetry Collector の出発ガイドに従って、コレクターをセットアップし、Next.jsアプリからデータを受信するように設定します。
コレクターが稼働したら、選択したプラットフォームの各デプロイガイドに従ってNext.jsアプリをデプロイできます。
カスタムエクスポーター
OpenTelemetry Collectorは必須ではありません。@vercel/otel
または手動OpenTelemetry設定でカスタムOpenTelemetryエクスポーターを使用できます。
カスタムスパン
OpenTelemetry APIsを使用してカスタムスパンを追加できます。
以下の例は、GitHubスターを取得し、取得リクエストの結果を追跡するカスタムfetchGithubStars
スパンを追加する関数を示しています:
register
関数は、新しい環境でコードが実行される前に実行されます。
新しいスパンを作成でき、エクスポートされたトレースに正しく追加されるはずです。
Next.jsのデフォルトスパン
Next.jsは、アプリケーションのパフォーマンスに関する有用な洞察を提供するため、自動的にいくつかのスパンを計測します。
スパンの属性はOpenTelemetry セマンティック規約に従います。さらに、next
名前空間の下にいくつかのカスタム属性を追加しています:
next.span_name
- スパン名を複製next.span_type
- 各スパンタイプには一意の識別子があるnext.route
- リクエストのルートパターン(例:/[param]/user
)next.rsc
(true/false) - プリフェッチなどのRSCリクエストかどうかnext.page
- これはアプリルーターで使用される内部値
page.ts
、layout.ts
、loading.ts
などの特別なファイルへのルートと考えられるnext.route
と組み合わせた場合にのみ一意の識別子として使用できる。/layout
は/(groupA)/layout.ts
と/(groupB)/layout.ts
の両方を識別できるため
[http.method] [next.route]
next.span_type
:BaseServer.handleRequest
このスパンは、Next.jsアプリケーションへの各着信リクエストのルートスパンを表します。HTTPメソッド、ルート、ターゲット、およびリクエストのステータスコードを追跡します。
属性:
- 共通HTTPの属性
http.method
http.status_code
- サーバーHTTPの属性
http.route
http.target
next.span_name
next.span_type
next.route
render route (app) [next.route]
next.span_type
:AppRender.getBodyResult
このスパンは、アプリルーターでのルートのレンダリングプロセスを表します。
属性:
next.span_name
next.span_type
next.route
fetch [http.method] [http.url]
next.span_type
:AppRender.fetch
このスパンは、コード内で実行されるfetchリクエストを表します。
属性:
- 共通HTTPの属性
http.method
- クライアントHTTPの属性
http.url
net.peer.name
net.peer.port
(指定された場合のみ)
next.span_name
next.span_type
環境変数NEXT_OTEL_FETCH_DISABLED=1
を設定することで、このスパンをオフにできます。カスタムfetch計測ライブラリを使用する場合に便利です。
executing api route (app) [next.route]
next.span_type
:AppRouteRouteHandlers.runHandler
このスパンは、アプリルーターのAPIルートハンドラの実行を表します。
属性:
next.span_name
next.span_type
next.route
getServerSideProps [next.route]
next.span_type
:Render.getServerSideProps
このスパンは、特定のルートのgetServerSideProps
の実行を表します。
属性:
next.span_name
next.span_type
next.route
getStaticProps [next.route]
next.span_type
:Render.getStaticProps
このスパンは、特定のルートのgetStaticProps
の実行を表します。
属性:
next.span_name
next.span_type
next.route
render route (pages) [next.route]
next.span_type
:Render.renderDocument
このスパンは、特定のルートのドキュメントレンダリングプロセスを表します。
属性:
next.span_name
next.span_type
next.route
generateMetadata [next.page]
next.span_type
:ResolveMetadata.generateMetadata
このスパンは、特定のページのメタデータ生成プロセスを表します(1つのルートで複数のスパンが存在する可能性があります)。
属性:
next.span_name
next.span_type
next.page
resolve page components
next.span_type
:NextNodeServer.findPageComponents
このスパンは、特定のページのページコンポーネントの解決プロセスを表します。
属性:
next.span_name
next.span_type
next.route
resolve segment modules
next.span_type
:NextNodeServer.getLayoutOrPageModule
このスパンは、レイアウトまたはページのコードモジュールの読み込みを表します。
属性:
next.span_name
next.span_type
next.segment
start response
next.span_type
:NextNodeServer.startResponse
このゼロ長さのスパンは、レスポンスの最初のバイトが送信された時点を表します。