OpenTelemetry
Observability ist entscheidend für das Verständnis und die Optimierung des Verhaltens und der Leistung Ihrer Next.js-App.
Mit zunehmender Komplexität von Anwendungen wird es immer schwieriger, Probleme zu identifizieren und zu diagnostizieren. Durch den Einsatz von Observability-Tools wie Logging und Metriken können Entwickler Einblicke in das Verhalten ihrer Anwendung gewinnen und Optimierungspotenziale identifizieren. Mit Observability können Entwickler Probleme proaktiv angehen, bevor sie zu größeren Problemen werden, und so ein besseres Nutzererlebnis bieten. Daher wird dringend empfohlen, Observability in Next.js-Anwendungen zu nutzen, um die Leistung zu verbessern, Ressourcen zu optimieren und das Nutzererlebnis zu verbessern.
Wir empfehlen die Verwendung von OpenTelemetry zur Instrumentierung Ihrer Apps. Es ist eine plattformunabhängige Methode zur App-Instrumentierung, die es Ihnen ermöglicht, Ihren Observability-Anbieter zu wechseln, ohne den Code zu ändern. Lesen Sie die Offiziellen OpenTelemetry-Dokumentation für weitere Informationen über OpenTelemetry und dessen Funktionsweise.
Diese Dokumentation verwendet Begriffe wie Span, Trace oder Exporter, die alle im OpenTelemetry Observability Primer zu finden sind.
Next.js unterstützt OpenTelemetry-Instrumentierung standardmäßig, was bedeutet, dass Next.js bereits selbst instrumentiert wurde.
Wenn Sie OpenTelemetry aktivieren, werden wir automatisch den gesamten Code wie getStaticProps
in Spans mit hilfreichen Attributen einwickeln.
Erste Schritte
OpenTelemetry ist erweiterbar, aber die richtige Einrichtung kann sehr komplex sein.
Deshalb haben wir das Paket @vercel/otel
vorbereitet, das Ihnen hilft, schnell zu starten.
Verwendung von @vercel/otel
Um zu beginnen, installieren Sie die folgenden Pakete:
Erstellen Sie als Nächstes eine benutzerdefinierte instrumentation.ts
(oder .js
)-Datei im Stammverzeichnis des Projekts (oder im src
-Ordner, falls verwendet):
Weitere Konfigurationsoptionen finden Sie in der @vercel/otel
-Dokumentation.
Hinweis:
- Die
instrumentation
-Datei sollte sich im Stammverzeichnis des Projekts und nicht imapp
- oderpages
-Verzeichnis befinden. Bei Verwendung dessrc
-Ordners platzieren Sie die Datei innerhalb vonsrc
nebenpages
undapp
.- Wenn Sie die Konfigurationsoption
pageExtensions
verwenden, um ein Suffix hinzuzufügen, müssen Sie den Dateinamen voninstrumentation
entsprechend aktualisieren.- Wir haben ein einfaches with-opentelemetry-Beispiel erstellt, das Sie verwenden können.
Manuelle OpenTelemetry-Konfiguration
Das Paket @vercel/otel
bietet viele Konfigurationsoptionen und sollte die meisten Anwendungsfälle abdecken. Wenn es Ihren Anforderungen jedoch nicht entspricht, können Sie OpenTelemetry manuell konfigurieren.
Zuerst müssen Sie OpenTelemetry-Pakete installieren:
Nun können Sie NodeSDK
in Ihrer instrumentation.ts
initialisieren.
Anders als @vercel/otel
ist NodeSDK
nicht mit Edge Runtime kompatibel, daher müssen Sie sicherstellen, dass Sie sie nur importieren, wenn process.env.NEXT_RUNTIME === 'nodejs'
. Wir empfehlen, eine neue Datei instrumentation.node.ts
zu erstellen, die Sie nur bei Verwendung von Node importieren:
Dies entspricht der Verwendung von @vercel/otel
, macht es jedoch möglich, einige Funktionen zu modifizieren und zu erweitern, die von @vercel/otel
nicht bereitgestellt werden. Wenn Edge Runtime-Unterstützung erforderlich ist, müssen Sie @vercel/otel
verwenden.
Testen Ihrer Instrumentierung
Sie benötigen einen OpenTelemetry-Collector mit einem kompatiblen Backend, um OpenTelemetry-Traces lokal zu testen. Wir empfehlen unsere OpenTelemetry Dev-Umgebung.
Wenn alles funktioniert, sollten Sie den Root-Server-Span mit der Bezeichnung GET /requested/pathname
sehen können.
Alle anderen Spans aus dieser bestimmten Trace werden darunter verschachtelt sein.
Next.js verfolgt mehr Spans, als standardmäßig ausgegeben werden.
Um mehr Spans zu sehen, müssen Sie NEXT_OTEL_VERBOSE=1
setzen.
Bereitstellung
Verwendung des OpenTelemetry Collectors
Bei der Bereitstellung mit OpenTelemetry Collector können Sie @vercel/otel
verwenden.
Es funktioniert sowohl auf Vercel als auch bei Selbst-Hosting.
Bereitstellung auf Vercel
Wir haben sichergestellt, dass OpenTelemetry standardmäßig auf Vercel funktioniert.
Folgen Sie der Vercel-Dokumentation, um Ihr Projekt mit einem Observability-Anbieter zu verbinden.
Selbst-Hosting
Die Bereitstellung auf anderen Plattformen ist ebenfalls unkompliziert. Sie müssen Ihren eigenen OpenTelemetry Collector einrichten, um die Telemetrie-Daten von Ihrer Next.js-App zu empfangen und zu verarbeiten.
Führen Sie dies aus, indem Sie der OpenTelemetry Collector Getting Started-Anleitung folgen, die Sie durch das Einrichten des Collectors und die Konfiguration zum Empfang von Daten aus Ihrer Next.js-App führt.
Sobald Ihr Collector läuft, können Sie Ihre Next.js-App auf der von Ihnen gewählten Plattform gemäß deren jeweiligen Bereitstellungsanleitungen bereitstellen.
Benutzerdefinierte Exporters
OpenTelemetry Collector ist nicht erforderlich. Sie können einen benutzerdefinierten OpenTelemetry-Exporter mit @vercel/otel
oder manueller OpenTelemetry-Konfiguration verwenden.
Benutzerdefinierte Spans
Sie können einen benutzerdefinierten Span mit OpenTelemetry-APIs hinzufügen.
Das folgende Beispiel zeigt eine Funktion, die GitHub-Sterne abruft und einen benutzerdefinierten fetchGithubStars
-Span hinzufügt, um das Ergebnis der Abrufanfrage zu verfolgen:
Die register
-Funktion wird vor der Ausführung Ihres Codes in einer neuen Umgebung ausgeführt.
Sie können neue Spans erstellen, und sie sollten korrekt zur exportierten Trace hinzugefügt werden.
Standard-Spans in Next.js
Next.js instrumentiert automatisch mehrere Spans, um nützliche Einblicke in die Leistung Ihrer Anwendung zu geben.
Attribute auf Spans folgen den OpenTelemetry-Semantischen Konventionen. Wir fügen auch einige benutzerdefinierte Attribute unter dem next
-Namespace hinzu:
next.span_name
- dupliziert Span-Namenext.span_type
- jeder Span-Typ hat einen eindeutigen Bezeichnernext.route
- Das Routenmuster der Anfrage (z.B./[param]/user
).next.rsc
(true/false) - Ob es sich um eine RSC-Anfrage handelt, wie z.B. Prefetch.next.page
- Dies ist ein interner Wert, der von einem App-Router verwendet wird.
- Sie können es sich als Route zu einer speziellen Datei vorstellen (wie
page.ts
,layout.ts
,loading.ts
und andere) - Es kann nur als eindeutiger Bezeichner verwendet werden, wenn es mit
next.route
kombiniert wird, da/layout
sowohl/(groupA)/layout.ts
als auch/(groupB)/layout.ts
identifizieren kann
[http.method] [next.route]
next.span_type
:BaseServer.handleRequest
Dieser Span repräsentiert den Root-Span für jede eingehende Anfrage an Ihre Next.js-Anwendung. Er verfolgt die HTTP-Methode, Route, Ziel und Statuscode der Anfrage.
Attribute:
- Gemeinsame HTTP-Attribute
http.method
http.status_code
- Server-HTTP-Attribute
http.route
http.target
next.span_name
next.span_type
next.route
Route rendern (app) [next.route]
next.span_type
:AppRender.getBodyResult
.
Dieser Span repräsentiert den Prozess des Renderns einer Route im App-Router.
Attribute:
next.span_name
next.span_type
next.route
Abruf [http.method] [http.url]
next.span_type
:AppRender.fetch
Dieser Span repräsentiert die in Ihrem Code ausgeführte Abrufanfrage.
Attribute:
- Gemeinsame HTTP-Attribute
http.method
- Client-HTTP-Attribute
http.url
net.peer.name
net.peer.port
(nur wenn angegeben)
next.span_name
next.span_type
Dieser Span kann durch Setzen von NEXT_OTEL_FETCH_DISABLED=1
in Ihrer Umgebung deaktiviert werden. Dies ist nützlich, wenn Sie eine benutzerdefinierte Fetch-Instrumentierungsbibliothek verwenden möchten.
API-Route ausführen (app) [next.route]
next.span_type
:AppRouteRouteHandlers.runHandler
.
Dieser Span repräsentiert die Ausführung eines API-Route-Handlers im App-Router.
Attribute:
next.span_name
next.span_type
next.route
getServerSideProps [next.route]
next.span_type
:Render.getServerSideProps
.
Dieser Span repräsentiert die Ausführung von getServerSideProps
für eine bestimmte Route.
Attribute:
next.span_name
next.span_type
next.route
getStaticProps [next.route]
next.span_type
:Render.getStaticProps
.
Dieser Span repräsentiert die Ausführung von getStaticProps
für eine bestimmte Route.
Attribute:
next.span_name
next.span_type
next.route
Route rendern (pages) [next.route]
next.span_type
:Render.renderDocument
.
Dieser Span repräsentiert den Prozess des Renderns des Dokuments für eine bestimmte Route.
Attribute:
next.span_name
next.span_type
next.route
generateMetadata [next.page]
next.span_type
:ResolveMetadata.generateMetadata
.
Dieser Span repräsentiert den Prozess der Metadatengenerierung für eine bestimmte Seite (eine einzelne Route kann mehrere dieser Spans haben).
Attribute:
next.span_name
next.span_type
next.page
Seitenkomponenten auflösen
next.span_type
:NextNodeServer.findPageComponents
.
Dieser Span repräsentiert den Prozess des Auffindens von Seitenkomponenten für eine bestimmte Seite.
Attribute:
next.span_name
next.span_type
next.route
Segmentmodule auflösen
next.span_type
:NextNodeServer.getLayoutOrPageModule
.
Dieser Span repräsentiert das Laden von Codemodules für ein Layout oder eine Seite.
Attribute:
next.span_name
next.span_type
next.segment
Antwort starten
next.span_type
:NextNodeServer.startResponse
.
Dieser Span mit Nulllänge repräsentiert den Zeitpunkt, an dem das erste Byte in der Antwort gesendet wurde.