Next.js 15 -fullstack-kehitys (App Router + Server Actions) · Oppitunti

OpenTelemetry-jäljitys instrumentation.ts-tiedostolla

Rekisteröikää OpenTelemetry instrumentation-hookin kautta palvelinpyyntöjen ja spanien jäljittämiseksi.

Oppitunti 1/413 vaihetta

OpenTelemetry-jäljitys instrumentation.ts-tiedostolla on ilmainen Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Next.js 15 -fullstack-kehitys (App Router + Server Actions)-kurssilla on yhteensä 4 oppituntia.

Mikä OpenTelemetry on ja miksi Next.js tarvitsee sitä

OpenTelemetry (OTel) on toimittajasta riippumaton observability-kehys, joka tuottaa sovelluksesta traceja, metriikoita ja lokeja. Trace tallentaa yhden pyynnön koko kulun — reunalta Server Components- ja Server Actions -komponenttien kautta tietokantakutsuihin — spanien puuna.

Next.js 15 tukee OTel-kehystä sisäänrakennetusti ja ensiluokkaisesti instrumentation.ts-hookin kautta. Saatte tällöin automaattisesti spanit seuraaville toiminnoille:

  • App Router -sivujen ja asettelujen renderöinti
  • Route Handler -HTTP-pyynnöt
  • Server Actions -kutsut
  • Palvelinkoodin sisältämät fetch-kutsut

Ilman traceja voitte vain arvailla, mihin viive kätkeytyy. Tracejen avulla näette täsmälleen, mikä span — ja kuinka pitkäkestoinen se — on hidas.

Instrumentation-hookin käyttöönotto tiedostossa next.config.ts

Ennen kuin instrumentation.ts otetaan käyttöön, se on erikseen sallittava. Next.js 15:ssä lippu on vakaa, mutta asetustunniste tarvitaan edelleen vanhempia 14-yhteensopivia kokoonpanoja varten. Lisätkää se asetuksiinne:

Tiedosto next.config.ts on Next.js 15:ssä esitelty TypeScript-natiivi asetustiedosto. experimental.instrumentationHook-avain käskee kehystä tuomaan instrumentation.ts-tiedoston kerran, kun Node.js-palvelin käynnistyy — ennen yhdenkään pyynnön käsittelyä.

Kun lippu on lisätty, luokaa instrumentation.ts projektin juureen (samalle tasolle kuin app/, ei sen sisälle).

// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    // Required in Next.js 14; stable & default-true in Next.js 15
    // but explicit opt-in avoids version ambiguity
    instrumentationHook: true,
  },
};

export default nextConfig;

OpenTelemetry-pakettien asentaminen

OTel-ekosysteemi koostuu monista pienistä paketeista. Next.js-kokoonpanoa varten tarvitsette seuraavat:

  • @opentelemetry/sdk-node — Node.js SDK, joka yhdistää kaiken
  • @opentelemetry/auto-instrumentations-node — instrumentoi automaattisesti http-, fetch-, dns- ja suositut kirjastot ilman manuaalista koodia
  • @opentelemetry/exporter-trace-otlp-http — vie spanit OTLP/HTTP:n kautta kerääjälle (Jaeger, Grafana Tempo, Honeycomb, Datadog jne.)
  • @opentelemetry/resources ja @opentelemetry/semantic-conventions — kuvaavat palvelunne vakiomuotoisilla attribuuttinimillä

Asentakaa kaikki tuotantoriippuvuuksiksi:

// Terminal — install once
// npm install @opentelemetry/sdk-node \
//   @opentelemetry/auto-instrumentations-node \
//   @opentelemetry/exporter-trace-otlp-http \
//   @opentelemetry/resources \
//   @opentelemetry/semantic-conventions

// No code to run — this is a shell command reference.
// After install, package.json will contain these entries:
const expectedDeps = [
  '@opentelemetry/sdk-node',
  '@opentelemetry/auto-instrumentations-node',
  '@opentelemetry/exporter-trace-otlp-http',
  '@opentelemetry/resources',
  '@opentelemetry/semantic-conventions',
];

console.log('Required OTel packages:', expectedDeps);

register()-vientitoiminto — instrumentoinnin aloituspiste

instrumentation.ts-tiedoston on vietävä nimetty async-funktio nimeltä register(). Next.js kutsuu sitä täsmälleen kerran palvelinprosessin käynnistyessä.

Tärkeät säännöt:

  • Tiedosto suoritetaan vain Node.js-ajoympäristössä — ei Edge-ajoympäristössä eikä selaimessa.
  • Käyttäkää ehtoa process.env.NEXT_RUNTIME === 'nodejs' Node-kohtaisten tuontien suojaamiseen, koska Next.js saattaa tuoda tiedoston muihin ajoympäristöihin analyysin aikana.
  • SDK:n alustuksen on valmistuttava synkronisesti tai ennen ensimmäistä pyyntöä — kehys odottaa register()-funktion valmistumista.
// instrumentation.ts  (project root)
export async function register() {
  // Guard: only run the heavy Node.js OTel SDK in the Node runtime.
  // Edge runtime does not support 'async_hooks' which OTel depends on.
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    // Dynamically import so the module is never bundled into Edge chunks.
    await import('./instrumentation.node');
  }
}

instrumentation.node.ts-tiedoston luominen — SDK:n alustus

Käytännön mukaisesti raskas asetusten määritys sijoitetaan erilliseen instrumentation.node.ts-tiedostoon, joka tuodaan vain Node-ajoympäristön ehdon sisällä. Näin pakettinne pysyy siistinä.

@opentelemetry/sdk-node-paketin NodeSDK-luokka on tärkein aloituspiste. Sille annetaan:

  • resource — palvelunne metatiedot (nimi, versio ja ympäristö)
  • trace exporter — kohde, johon spanit lähetetään
  • Valinnaiset instrumentations — kirjastojen automaattinen instrumentointi

Kutsukaa sdk.start()-metodia aktivointia varten. Rekisteröikää SIGTERM-käsittelijä, joka tyhjentää keskeneräiset spanit ennen prosessin päättymistä.

// instrumentation.node.ts  (project root)
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { Resource } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  resource: new Resource({
    [ATTR_SERVICE_NAME]: process.env.OTEL_SERVICE_NAME ?? 'my-nextjs-app',
    [ATTR_SERVICE_VERSION]: process.env.npm_package_version ?? '0.0.0',
  }),
  traceExporter: new OTLPTraceExporter({
    // Default: http://localhost:4318/v1/traces
    url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? 'http://localhost:4318/v1/traces',
  }),
  instrumentations: [
    getNodeAutoInstrumentations({
      // Disable noisy filesystem instrumentation in Next.js
      '@opentelemetry/instrumentation-fs': { enabled: false },
    }),
  ],
});

sdk.start();

// Flush spans before the process exits (e.g. during Vercel cold-start teardown)
process.on('SIGTERM', () => {
  sdk.shutdown().finally(() => process.exit(0));
});

Next.js:n automaattisesti luomat spanit

Kun SDK on käynnissä, Next.js 15 tuottaa spanit automaattisesti jokaisesta palvelinpuolen toiminnosta. Teidän ei tarvitse kirjoittaa trace-koodia komponentteihinne. Sisäänrakennettuja spaneja ovat:

  • BaseServer.handleRequest — jokaisen HTTP-pyynnön ylimmän tason span
  • NextNodeServer.findPageComponents — span sen ratkaisemiseen, mikä sivu tai asettelu renderöidään
  • AppRender.getBodyResult — Reactin palvelinrenderöinnin kattava span
  • AppRouteRouteHandler.runHandler — Route Handler -kutsun ympärille sijoitettu span
  • Sisäkkäiset fetch-spanit — jokaisesta palvelinkoodin fetch()-kutsusta tulee lapsispan, joka sisältää URL-osoitteen, metodin ja tilan

Nämä spanit yhdistetään automaattisesti vanhempi–lapsi-puuksi, joten näette koko kutsukaavion trace-käyttöliittymässänne (Jaeger, Grafana Tempo, Honeycomb jne.).

Mukautettujen spanien lisääminen @opentelemetry/api:lla

Automaattinen instrumentointi kattaa HTTP:n ja fetchin. Oma liiketoimintalogiikka — esimerkiksi hidas tietokantakyselyn apufunktio tai monimutkainen laskenta — instrumentoidaan luomalla mukautettuja spaneja @opentelemetry/api-paketilla.

Menettely on aina seuraava:

  1. Hakekaa yleinen tracer: trace.getTracer('your-scope-name')
  2. Kutsukaa tracer.startActiveSpan('span-name', async (span) => { ... })
  3. Asettakaa spanille haettavat metatiedot attribuutteina
  4. Kutsukaa aina span.end()-metodia finally-lohkossa

Mukautetuista spaneista tulee automaattisesti parhaillaan aktiivisen spanin lapsia, joten ne sijoittuvat oikein tracen puuhun.

// lib/db.ts — wrapping a Postgres query with a custom span
import { trace, SpanStatusCode } from '@opentelemetry/api';
import { sql } from '@vercel/postgres'; // or any pg client

const tracer = trace.getTracer('my-nextjs-app/db');

export async function getUserById(id: string) {
  return tracer.startActiveSpan('db.getUserById', async (span) => {
    span.setAttributes({
      'db.system': 'postgresql',
      'db.operation': 'SELECT',
      'app.user.id': id,
    });

    try {
      const result = await sql`SELECT * FROM users WHERE id = ${id} LIMIT 1`;
      span.setStatus({ code: SpanStatusCode.OK });
      return result.rows[0] ?? null;
    } catch (err) {
      span.recordException(err as Error);
      span.setStatus({ code: SpanStatusCode.ERROR, message: (err as Error).message });
      throw err;
    } finally {
      span.end();
    }
  });
}

Jäljitys Server Actionin sisällä

Server Actionit suoritetaan palvelimella, ja Next.js ympäröi ne omalla HTTP-elinkaarellaan. Voitte lisätä mukautettuja span-objekteja Server Actionin sisälle aivan kuten mihin tahansa palvelinfunktioon — aktiivisen spanin konteksti välitetään automaattisesti.

Tässä esimerkissä tietokantakirjoituksen ympärille luodaan span, jotta voitte nähdä erikseen, kuinka kauan validointi kesti ja kuinka kauan varsinainen INSERT kesti:

// app/actions/create-post.ts
'use server';

import { trace, SpanStatusCode } from '@opentelemetry/api';
import { revalidatePath } from 'next/cache';
import { z } from 'zod';

const tracer = trace.getTracer('my-nextjs-app/actions');

const CreatePostSchema = z.object({
  title: z.string().min(1).max(200),
  body: z.string().min(1),
});

export async function createPost(formData: FormData) {
  return tracer.startActiveSpan('action.createPost', async (span) => {
    try {
      // Validation span — nested child
      const parsed = CreatePostSchema.safeParse({
        title: formData.get('title'),
        body: formData.get('body'),
      });

      if (!parsed.success) {
        span.setStatus({ code: SpanStatusCode.ERROR, message: 'Validation failed' });
        return { error: parsed.error.flatten() };
      }

      // Simulate DB insert (replace with real client)
      // await db.posts.create({ data: parsed.data });

      span.setAttributes({ 'post.title': parsed.data.title });
      span.setStatus({ code: SpanStatusCode.OK });

      revalidatePath('/posts');
      return { success: true };
    } finally {
      span.end();
    }
  });
}

Jäljityskontekstin välittäminen fetch()-kutsujen yli

Kun Next.js-palvelimenne kutsuu ulkoista mikropalvelua komennolla fetch(), OTel:n pitäisi lisätä pyyntöön W3C Trace Context -otsakkeet (traceparent, tracestate), jotta alipalvelun spanit näkyvät saman jäljityksen lapsina.

Kun getNodeAutoInstrumentations() on käytössä, paketti @opentelemetry/instrumentation-undici tai @opentelemetry/instrumentation-http huolehtii tästä automaattisesti fetch- ja http-kutsuissa. Otsakkeita ei tarvitse lisätä manuaalisesti.

Voitte varmistaa välityksen toimivuuden tarkistamalla lähtevän pyynnön otsakkeet — niiden pitäisi sisältää:

  • traceparent: 00-<traceId>-<spanId>-01
  • Vastaanottavan palvelun on myös suoritettava OTel:ää ja luettava nämä otsakkeet (W3C-standardi).
// app/api/summary/route.ts — fetch with automatic context propagation
import { NextResponse } from 'next/server';
import { trace } from '@opentelemetry/api';

const tracer = trace.getTracer('my-nextjs-app/api');

export async function GET() {
  return tracer.startActiveSpan('api.getSummary', async (span) => {
    try {
      // OTel auto-instrumentation injects 'traceparent' header automatically.
      // The downstream service will see this request as a child span.
      const response = await fetch('https://internal-api.example.com/data', {
        next: { revalidate: 60 }, // Next.js cache hint
      });

      if (!response.ok) {
        span.setStatus({ code: 2, message: `Upstream ${response.status}` });
        return NextResponse.json({ error: 'upstream failed' }, { status: 502 });
      }

      const data = await response.json();
      span.setStatus({ code: 1 });
      return NextResponse.json(data);
    } finally {
      span.end();
    }
  });
}

Ympäristömuuttujat ja Collectorin määritys

OTel SDK noudattaa OTel:n vakioympäristömuuttujia, joten päätepisteitä tarvitsee harvoin määrittää suoraan koodissa. Asettakaa nämä muuttujat tiedostoon .env.local (kehitys) ja hosting-alustan ympäristömäärityksiin (tuotanto):

  • OTEL_SERVICE_NAME — yksilöi palvelunne tracing-käyttöliittymässä
  • OTEL_EXPORTER_OTLP_ENDPOINT — Collectorin URL-osoite (esimerkiksi http://localhost:4318 paikalliselle Jaeger all-in-one -asennukselle)
  • OTEL_TRACES_SAMPLER — esimerkiksi parentbased_traceidratio, jolla tuotannossa jäljitetään vain osa jäljityksistä
  • OTEL_TRACES_SAMPLER_ARG — esimerkiksi 0.1, jolla jäljitetään 10 % jäljityksistä

Kun käytätte Verceliä, asentakaa Vercel OTel -integraatio tai käyttäkää pakettia @vercel/otel, joka ympäröi SDK:n ja lukee samat ympäristömuuttujat Vercel-hallintapaneelista.

# .env.local — development with a local Jaeger all-in-one container
# docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one

OTEL_SERVICE_NAME=my-nextjs-app
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

# Sample every request in dev, 10% in production
# (set OTEL_TRACES_SAMPLER_ARG=0.1 in prod env)
OTEL_TRACES_SAMPLER=always_on
OTEL_TRACES_SAMPLER_ARG=1

@vercel/otelin käyttö määrityksen yksinkertaistamiseen

Vercel tarjoaa paketin @vercel/otel, joka on Next.js-käyttöönottoihin optimoitu ohut kerros OTel SDK:n ympärillä. Se vähentää toistuvaa koodia yhteen registerOTel()-kutsuun ja huolehtii Edge-ajoympäristön yhteensopivuudesta automaattisesti.

Kun otatte sovelluksen käyttöön Vercelissä, tämä on suositeltu lähestymistapa. Itse ylläpidetyissä tai Docker-käyttöönotossa aiemmissa osioissa esitelty manuaalinen NodeSDK-määritys antaa enemmän hallintamahdollisuuksia.

Molemmat lähestymistavat tuottavat täysin samanlaiset spanit — ero on vain määrityksen monimutkaisuudessa ja Edge-tuessa.

// instrumentation.ts — simplified with @vercel/otel
// npm install @vercel/otel
import { registerOTel } from '@vercel/otel';

export function register() {
  // Works in both Node.js and Edge runtimes.
  // Reads OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT from env automatically.
  registerOTel({
    serviceName: process.env.OTEL_SERVICE_NAME ?? 'my-nextjs-app',
    // Optionally add custom attributes visible on every span:
    attributes: {
      'deployment.environment': process.env.VERCEL_ENV ?? 'development',
      'deployment.region': process.env.VERCEL_REGION ?? 'local',
    },
  });
}

Tietotesti: Mihin SDK:n alustaminen kuuluu?

Olette määrittämässä OpenTelemetry-jäljitystä itse ylläpidetylle Node.js-palvelimelle käyttöön otettuun Next.js 15 App Router -projektiin. Millä tavalla OTel:n NodeSDK alustetaan oikein?

Kertaus: OpenTelemetry-jäljitys tiedostolla instrumentation.ts

Tässä oppitunnissa opitte lisäämään tuotantotasoisen hajautetun jäljityksen Next.js 15 App Router -sovellukseen:

  • Ottakaa hook käyttöön — asettakaa experimental.instrumentationHook: true tiedostossa next.config.ts (vakaa oletusasetus Next.js 15:ssä).
  • Luokaa instrumentation.ts — viekää projektin juuressa olevaan tiedostoon register()-funktio; käyttäkää sitä kaiken palvelinpuolen alustamisen ainoana aloituspisteenä.
  • Rajaatkaa ajonaika — ympäröikää vain Node.js:lle tarkoitetut importit ehdolla process.env.NEXT_RUNTIME === 'nodejs' ja estäkää Edge-paketointi käyttämällä dynaamista import()-tuontia.
  • Alustakaa NodeSDK erillisessä tiedostossa instrumentation.node.ts — antakaa sille Resource, OTLPTraceExporter ja automaattiset instrumentoinnit; kutsukaa sdk.start()-metodia kerran.
  • Automaattiset spanit — Next.js tuottaa spanit sivujen renderöinnille, Route Handlereille, Server Actioneille ja fetch-kutsuille ilman lisäkoodia.
  • Mukautetut spanit — käyttäkää trace.getTracer()- ja startActiveSpan()-metodeja paketista @opentelemetry/api oman liiketoimintalogiikkanne instrumentointiin.
  • Kontekstin välitys — automaattinen instrumentointi lisää W3C:n traceparent-otsakkeet automaattisesti lähteviin fetch-kutsuihin.
  • Määritys — vakioympäristömuuttujat OTEL_* ohjaavat SDK:ta; Collectorin URL-osoitteita ei tarvitse määrittää suoraan lähdekoodissa.
Aloita maksutta

Opi TypeScript tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
22
Oppitunnit
88

Usein kysytyt kysymykset

Onko oppitunti ”OpenTelemetry-jäljitys instrumentation.ts-tiedostolla” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppimispolun 3 oppituntia, myös oppitunnin “OpenTelemetry-jäljitys instrumentation.ts-tiedostolla”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Next.js 15 -fullstack-kehitys (App Router + Server Actions)-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”OpenTelemetry-jäljitys instrumentation.ts-tiedostolla”?

Rekisteröikää OpenTelemetry instrumentation-hookin kautta palvelinpyyntöjen ja spanien jäljittämiseksi. Harjoittelet Next.js 15 -fullstack-kehitys (App Router + Server Actions)-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Next.js 15 -fullstack-kehitys (App Router + Server Actions)-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.

Kuinka kauan ”OpenTelemetry-jäljitys instrumentation.ts-tiedostolla”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppitunnilla?

Kyllä. Jokainen Next.js 15 -fullstack-kehitys (App Router + Server Actions)-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. OpenTelemetry-jäljitys instrumentation.ts-tiedostolla
  2. Hienojakoiset error.tsx- ja global-error-rajat
  3. Rakenteinen lokitus palvelin- ja Edge-ympäristöissä
  4. Server Action -virheiden ja telemetrian kerääminen
← Takaisin: Next.js 15 -fullstack-kehitys (App Router + Server Actions)