Web razvoj
Next.jsObservabilnostSentryOpenTelemetryLogiranjeTracingNadzor

Observabilnost za Next.js App Router u 2026.: Sentry, OpenTelemetry, traceovi i korisna upozorenja

AO
Adrijan Omićević
·16 min čitanja

# Što ćeš izgraditi (i zašto je to važno)#

Ovaj vodič daje ti end-to-end postavku observabilnosti za Next.js App Router: greške, logove i traceove kroz Server Actions, Route Handlers i podjelu Edge naspram Node.js runtimea. Na kraju ćeš imati dashboarde i pragove upozorenja koji hvataju stvarne incidente umjesto da spamaju tim.

Čak i ako već imaš “neko logiranje”, vrlo vjerojatno ti i dalje nedostaju odgovori na pitanja koja su ključna tijekom incidenta: koji je deploy uzrokovao skok, koja je ruta spora, koji je segment korisnika pogođen i koji točno downstream poziv pada. Cilj je smanjiti vrijeme do detekcije i rješavanja tako da probleme učiniš operativno rješivima.

Za šire koncepte observabilnosti pročitaj naš osnovni pregled: Vodič za observabilnost web aplikacija: logovi, metrike, tracing.

# Arhitektura observabilnosti za Next.js App Router#

Praktična postavka za “Next.js logging monitoring Sentry OpenTelemetry” koristi dva komplementarna sloja:

  1. 1
    Sentry za nadzor grešaka, release health, utjecaj na korisnike, session replay i workflowe performansi.
  2. 2
    OpenTelemetry za vendor-neutral distribuirani tracing i izvoz traceova u backend po izboru.

Možeš koristiti samo Sentry i biti produktivan. Dodavanje OpenTelemetryja se isplati kad imaš više servisa, queueova ili ti trebaju konzistentni traceovi kroz infrastrukturu.

Što instrumentirati u App Routeru#

Next.js površinaTipični kvaroviŠto uhvatitiPrimarni alat
Server Actionsspori DB upiti, auth greške, validation greškespanovi oko poslovne logike, greška s kontekstomSentry + OpenTelemetry
Route Handlerstimeouti, upstream HTTP greške, problemi s parsiranjemrequest span, downstream spanovi, status kodoviSentry + OpenTelemetry
RSC renderiranjespori fetch pozivi, serialization greškerender transakcije, fetch spanoviSentry
Navigacija na klijentuJS greške, spore rute, puknuti API pozivisession replay, web vitals, long tasksSentry
Edge runtimecold startovi, upstream latencija, ograničeni Node API-jiminimalni spanovi, hvatanje grešakaSentry + selektivni OTel

Za tradeoffove i ograničenja runtimea vidi: Next.js Edge runtime vs Node.js runtime na Vercelu i Cloudflareu.

ℹ️ Napomena: Logove tretiraj kao dokaz, traceove kao vremensku crtu, a greške kao simptom. Incidente najbrže rješavaš kad možeš skočiti s upozorenja na trace, pa na točnu grešku i njen utjecaj na korisnike.

# Preduvjeti#

ZahtjevVerzijaNapomene
Next.js14 ili 15Pretpostavljen App Router
Node.js18+Node runtime za potpunu server instrumentaciju
Sentry računJedan projekt za frontend plus backend (ili kombinirano)
OpenTelemetry collectoropcionalnoPreporučeno za kontrolu izvoza u produkciji
HostingVercel, AWS, itd.Edge i Node se razlikuju

# Korak 1: Definiraj standarde observabilnosti#

Prije instalacije SDK-ova, postavi standarde kako bi podaci ostali konzistentni kroz timove i servise.

Konvencije imenovanja koje čine podatke pretraživima#

StavkaPreporukaPrimjer
Naziv servisastabilan, neovisan o okruženjuweb-app
Okruženjeproduction, staging, previewpreview
ReleaseCI commit SHA ili semver2026.08.10+sha.abc123
Nazivi transakcijaprema rutama, niska kardinalnostPOST /api/orders
Ključ korisnika/sesijebez PII, stabilansid_9f3...

Kako izgleda “dobro” u produkciji#

Koristi ove početne SLO-ish ciljeve kao startnu točku:

SignalPočetni ciljZašto
5xx stopa (Route Handlers)manje od 0.5%iznad toga korisnici to brzo osjete
P95 latencija API-jamanje od 800 msdrži UI responzivnim pod opterećenjem
P95 latencija Server Actionamanje od 600 msServer Actions su interakcije vidljive korisniku
Regresija grešaka2x baseline unutar 15 minrano hvata loše deployeve
Apdex0.85+brza provjera “je li sporo”

Podesi pragove nakon 2 do 4 tjedna baznih podataka.

# Korak 2: Instaliraj i konfiguriraj Sentry za Next.js App Router#

Sentryjev Next.js SDK pokriva klijent i server te dobro podržava App Router površine kad je ispravno konfiguriran.

Instaliraj ovisnosti#

Bash
npm i @sentry/nextjs
npx @sentry/wizard@latest -i nextjs

Ovo tipično kreira:

  • sentry.client.config.*
  • sentry.server.config.*
  • sentry.edge.config.*
  • ažuriranja u next.config.*

Ključne Sentry postavke koje su važne#

Provjeri da tvoja Sentry konfiguracija uključuje:

  • Releases i environments
  • Traces sampling za performanse
  • Profiles sampling ako ga koristiš (server profiling ovisi o runtime podršci)

Primjer minimalne server konfiguracije:

JavaScript
// sentry.server.config.js
import * as Sentry from "@sentry/nextjs";
 
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.VERCEL_ENV || process.env.NODE_ENV,
  release: process.env.SENTRY_RELEASE,
  tracesSampleRate: 0.1,
});

Klijentska konfiguracija također treba postaviti sampling rate i uključiti session replay samo kad je potrebno, kako bi se kontrolirao trošak.

Preporučena strategija samplinga#

OkruženjeGreškeTraceoviReplay
production100% (uz grupiranje)5% do 15%0.5% sesija, 10% na grešku
staging100%25%2% sesija, 25% na grešku
preview100%10%isključeno ili 0.1%

Prilagodi prema prometu. Primjerice, pri 1000 zahtjeva u minuti, 10% traceova daje 100 traceova u minuti, što je obično dovoljno za trijažu performansi bez prevelikog ingestiona.

💡 Savjet: Kreni s 10% traceova u produkciji, pa dodaj pravila za dynamic sampling: zadrži 100% za spore transakcije (P95+), 5xx odgovore i ključne korisničke tokove poput checkouta.

# Korak 3: Hvataj greške i kontekst u Server Actions#

Server Actions često “tiho” failaju ako se oslanjaš samo na console output. Želiš:

  • iznimku
  • naziv actiona
  • korisnički/sesijski kontekst
  • oblik inputa (sanitiziran)
  • trace koji uključuje downstream pozive

Primjer Server Actiona sa Sentryjem i strukturiranim kontekstom#

TypeScript
// app/actions/createOrder.ts
"use server";
 
import * as Sentry from "@sentry/nextjs";
 
export async function createOrderAction(input: { sku: string; qty: number }) {
  return await Sentry.startSpan(
    { name: "server_action:createOrder", op: "function" },
    async () => {
      try {
        // Your business logic here
        if (input.qty <= 0) throw new Error("Invalid quantity");
 
        return { ok: true };
      } catch (err) {
        Sentry.captureException(err, {
          tags: { surface: "server_action" },
          extra: { sku: input.sku, qty: input.qty },
        });
        throw err;
      }
    }
  );
}

Ovo kreira jasan span i dodaje prave metapodatke za grupiranje i filtriranje.

Što ne logirati u Server Actions#

Izbjegavaj logiranje:

  • email adresa, brojeva telefona, adresa
  • raw access tokena
  • cijelih request headera
  • podataka o plaćanju

Umjesto toga logiraj stabilne identifikatore: userId, tenantId, orderId, sessionId.

# Korak 4: Instrumentiraj Route Handlers (API) s traceovima i request ID-jevima#

Route Handlers su mjesto gdje želiš korelaciju kroz:

  • inbound request
  • outbound fetch pozive
  • DB pozive
  • slanje u queue
  • status i latenciju odgovora

Dodaj stabilan request ID i propagiraj trace headere#

U Next.js možeš implementirati middleware koji dodaje request ID header. Neka bude niske kardinalnosti i jedinstven po requestu.

TypeScript
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
 
export function middleware(req: NextRequest) {
  const requestId = crypto.randomUUID();
 
  const res = NextResponse.next();
  res.headers.set("x-request-id", requestId);
 
  return res;
}

Zatim u Route Handleru logiraj i tagiraj s x-request-id, te proslijedi trace headere kada zoveš downstream servise.

TypeScript
// app/api/orders/route.ts
import * as Sentry from "@sentry/nextjs";
import { NextRequest, NextResponse } from "next/server";
 
export async function POST(req: NextRequest) {
  const requestId = req.headers.get("x-request-id") || "missing";
 
  return await Sentry.startSpan(
    { name: "POST /api/orders", op: "http.server" },
    async () => {
      try {
        const body = await req.json();
 
        const traceHeaders = {
          "sentry-trace": req.headers.get("sentry-trace") || "",
          baggage: req.headers.get("baggage") || "",
          "x-request-id": requestId,
        };
 
        const upstream = await fetch(process.env.ORDERS_SERVICE_URL!, {
          method: "POST",
          headers: { "content-type": "application/json", ...traceHeaders },
          body: JSON.stringify(body),
        });
 
        if (!upstream.ok) {
          throw new Error(`Upstream failed with status ${upstream.status}`);
        }
 
        return NextResponse.json({ ok: true }, { headers: { "x-request-id": requestId } });
      } catch (err) {
        Sentry.captureException(err, {
          tags: { surface: "route_handler" },
          extra: { requestId },
        });
        return NextResponse.json({ ok: false }, { status: 500, headers: { "x-request-id": requestId } });
      }
    }
  );
}

Ovo stvara end-to-end lanac: browser event → Route Handler trace → upstream servis, uz request ID za logove.

# Korak 5: Dodaj OpenTelemetry tracing (vendor-neutral) za server runtime#

Sentry ti daje odličan workflow, ali OpenTelemetry donosi prenosivost i konzistentnost kroz infrastrukturu. Najrobustnija priča za Next.js OpenTelemetry i dalje je na Node runtimeu, jer exporter-i i auto-instrumentation tipično ovise o Node API-jima.

Preporučena produkcijska topologija#

KomponentaGdje radiOdgovornost
Next.js appNode runtimekreiranje spanova, dodavanje konteksta
OpenTelemetry Collectorsidecar ili zaseban servisbatchanje, sampling, export
Trace backendTempo, Honeycomb, Datadog, New Relicpohrana, upiti, dashboardi

Instaliraj osnovne OpenTelemetry pakete#

Drži minimalno kako bi izbjegao bundle bloat.

Bash
npm i @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
npm i @opentelemetry/exporter-trace-otlp-http

Minimalni OTel init za Node runtime#

Napravi server-only datoteku i učitaj je rano. Točna strategija učitavanja ovisi o deploymentu, ali srž konfiguracije izgleda ovako:

TypeScript
// otel-node.ts
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
 
const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
    headers: { "x-otlp-api-key": process.env.OTEL_API_KEY || "" },
  }),
  instrumentations: [getNodeAutoInstrumentations()],
});
 
sdk.start();

Zadrži OTel export isključivo na server strani. Ne pokušavaj ovo pokretati na Edgeu.

⚠️ Upozorenje: Auto-instrumentation može stvarati spanove visoke kardinalnosti ako hvataš pune URL-ove s ID-jevima. Normaliziraj nazive transakcija i izbjegavaj stavljati korisničke identifikatore u nazive spanova. Identifikatore stavljaj u atribute samo kad je nužno, i tek nakon privacy reviewa.

Dodaj ručne spanove tamo gdje auto-instrumentation ne pomaže#

Auto-instrumentation često propušta granice poslovne logike poput “checkout validacija” ili “credit check”.

TypeScript
// app/lib/pricing.ts
import { trace } from "@opentelemetry/api";
 
const tracer = trace.getTracer("web-app");
 
export async function calculatePrice(sku: string) {
  return await tracer.startActiveSpan("pricing:calculate", async (span) => {
    try {
      span.setAttribute("sku", sku);
      // ... do work
      return 1999;
    } finally {
      span.end();
    }
  });
}

Koristi ručne spanove štedljivo, oko top-level operacija koje stvarno upituješ tijekom incidenta.

# Korak 6: Observabilnost Edge runtimea bez razbijanja buildova#

Edge runtime je odličan za latenciju, ali ograničava Node API-je i neke SDK-ove. Siguran pristup je:

  • držati Edge instrumentaciju laganom
  • ne oslanjati se na Node-only OTel SDK na Edgeu
  • tagirati eventove s runtime=edge kako bi se dashboardi čisto razdvajali

Čest obrazac je osloniti se na Sentry Edge config za greške i osnovni tracing, a OpenTelemetry rezervirati za Node runtime putanje.

Za odluku što treba ići na Edge ponovno pogledaj: Next.js Edge runtime vs Node.js runtime na Vercelu i Cloudflareu.

Praktično pravilo za timove#

WorkloadPreporučeni runtimeZašto
Auth gating, redirecti, A/B routingEdgebrzo, blizu korisniku
Plaćanja, teški DB pristup, generiranje PDF-aNodepuna SDK podrška, dulje CPU vrijeme
Kompleksna observabilnost s OTelNodekompatibilnost exportera i instrumentacije

# Korak 7: Strategija logiranja koja radi u serverlessu#

U serverlessu logovi su često najbrži “prvi pogled”, ali samo ako su strukturirani i korelirani.

Što logirati (i kako)#

Logiraj događaje na tri razine:

RazinaKada koristitiPrimjer polja
infoključne poslovne prekretniceevent, orderId, durationMs
warnneočekivano, ali oporavljivoevent, reason, retry
errorkvarovi i iznimkeevent, requestId, traceId

Koristi JSON logove kako bi platforma i log backend mogli parsirati polja. Na Node runtimeu možeš koristiti bilo koji logger, ali drži ga jednostavnim i izbjegavaj velike ovisnosti na Edgeu.

Minimalni JSON logger s poljima za korelaciju#

TypeScript
// app/lib/log.ts
export function log(level: "info" | "warn" | "error", message: string, data: Record<string, unknown> = {}) {
  const payload = {
    level,
    message,
    ts: new Date().toISOString(),
    ...data,
  };
  console.log(JSON.stringify(payload));
}

Zatim u Route Handleru:

TypeScript
// app/api/health/route.ts
import { NextRequest, NextResponse } from "next/server";
import { log } from "@/app/lib/log";
 
export async function GET(req: NextRequest) {
  const requestId = req.headers.get("x-request-id") || "missing";
  log("info", "health_check", { requestId, surface: "route_handler" });
  return NextResponse.json({ ok: true });
}

Ako tvoj tracing backend izlaže trace ID, uključi ga u logove kao traceId. Za Sentry možeš uključiti i sentryTrace iz inbound headera.

# Korak 8: Poveži korisničke sesije s backend traceovima#

Korelacija je ono što observabilnost pretvara iz grafova u root cause analizu.

Strategija identifikatora sesije#

Koristi stabilan, ne-PII identifikator sesije:

  • generiran na klijentu
  • spremljen u first-party cookie
  • proslijeđen kao header prema API rutama

Primjer: postavi cookie sid i šalji ga kao x-session-id na fetch pozivima.

Kreiranje session ID-ja na klijentu (lagano)#

TypeScript
// app/lib/session.ts
export function getOrCreateSessionId() {
  const key = "sid";
  const existing = window.localStorage.getItem(key);
  if (existing) return existing;
 
  const sid = `sid_${crypto.randomUUID()}`;
  window.localStorage.setItem(key, sid);
  return sid;
}

Zatim ga dodaj requestovima:

TypeScript
// app/lib/http.ts
import { getOrCreateSessionId } from "@/app/lib/session";
 
export async function apiFetch(path: string, init: RequestInit = {}) {
  const sid = getOrCreateSessionId();
  const headers = new Headers(init.headers);
  headers.set("x-session-id", sid);
  return fetch(path, { ...init, headers });
}

Uhvati isti session ID u Sentryju#

U klijentskom kodu postavi user context tako da uključuje session ID. Drži ga odvojenim od user.id ako imaš i autentificirane korisnike.

TypeScript
// sentry-session.ts
import * as Sentry from "@sentry/nextjs";
import { getOrCreateSessionId } from "@/app/lib/session";
 
export function attachSentrySession() {
  const sid = getOrCreateSessionId();
  Sentry.setUser({ id: sid });
  Sentry.setTag("session_id", sid);
}

Pozovi ovo jednom pri startu aplikacije u client komponenti.

Koristi session ID u backend spanovima i logovima#

U Route Handlerima i Server Actions, čitaj x-session-id iz headera kada je dostupan i dodaj ga:

  • kao Sentry tag
  • kao OTel attribute
  • kao log polje

Ovo omogućuje upite poput “prikaži sve greške za sesiju X” i “otvori trace za sporu checkout sesiju”.

🎯 Ključna poruka: Korelacija zahtijeva da isti identifikator postoji na tri mjesta: browser telemetry, backend telemetry i logovi. Bez toga se ne možeš pouzdano prebaciti s “korisničke prijave” na “trace” u par minuta.

# Korak 9: Dashboardi koje tim stvarno koristi#

Dashboardi trebaju odgovoriti na operativna pitanja u manje od 30 sekundi. Napravi odvojene dashboarde za:

  • dostupnost i greške
  • latenciju i regresije
  • runtime podjelu: Edge vs Node
  • kritične tokove: login, checkout, search

Preporučeni widgeti za dashboard#

DashboardWidgetPredloženi breakdown
Dostupnost5xx stopa, broj grešakapo ruti, po releaseu
PerformanseP50, P95 latencijapo ruti, po runtimeu
Utjecaj na korisnikepogođeni korisnici, sesijepo državi, po pregledniku
Regresijagreške uvedene u zadnjem releaseupo releaseu, po endpointu
Ovisnostiupstream latencija i greškepo hostnameu

U Sentryju posebno konfiguriraj:

  • Releases i commit tracking
  • Performance prikaze s breakdownom transakcija
  • Alerts vezane uz release verziju

Ako imaš background jobove, tretiraj ih kao zaseban servis s vlastitim dashboardom i alertima. Next.js projekti često skrivaju kritičan rad u cronu ili queueovima, pa instrumentiraj i to: Next.js background jobovi, queueovi i cron na Vercelu.

# Korak 10: Korisna upozorenja i pragovi (bez buke)#

Većina alert fatiguea dolazi iz dva problema: alertanje na sirove brojeve umjesto na stope, i neodvajanje “simptoma” od “utjecaja”.

Praktični pragovi upozorenja za početak#

UpozorenjeUvjetProzorAkcija
Skok API 5xx5xx stopa veća od 1%10 minpage on-call
Regresija latencijeP95 veći od 1.5x baseline15 minobavijesti dev kanal
Regresija grešaka na releaseubroj novih issueva veći od 2030 min nakon deployablokiraj rollout
Checkout failurestopa neuspjeha POST /api/orders veća od 0.5%10 minpage on-call
Edge anomalijaEdge greške veće od 2x baseline15 ministraži runtime konfiguraciju

Koristi različite kanale po ozbiljnosti. Paging treba biti rezerviran za uvjete koji utječu na prihod ili osnovnu funkcionalnost.

Učini upozorenja operativno rješivima uz kontekst#

Svako upozorenje treba uključiti:

  • okruženje
  • release
  • top 3 pogođene transakcije
  • link na primjer tracea
  • pogođene korisnike ili sesije

U Sentryju veži upozorenja na:

  • Issue alerts za skokove grešaka i nove regresije
  • Metric alerts za latenciju i throughput

# Česte zamke (i kako ih izbjeći)#

  1. 1
    Tagovi visoke kardinalnosti — Izbjegavaj tagiranje punim URL-ovima koji sadrže ID-jeve ili emailove. Normaliziraj rute i koristi sigurne identifikatore.
  2. 2
    Bez runtime podjele — Ako ne tagiraš runtime=edge naspram runtime=node, krivo ćeš dijagnosticirati performanse i okriviti pogrešan sloj.
  3. 3
    Sampling bez strategije — Sampling svega ravno na 1% često promaši baš spore traceove koje trebaš. Zadrži veći sampling za spore i failing zahtjeve.
  4. 4
    Logiranje bez korelacije — Logovi koji ne uključuju requestId, sessionId i trace kontekst su skupa buka tijekom incidenta.
  5. 5
    Tretiranje background jobova kao “sporednih” — neuspjeli cron runovi često uzrokuju incidente vidljive korisniku satima kasnije. Instrumentiraj jobove kao servise prvog reda.

# Ključni zaključci#

  • Instrumentiraj Next.js App Router end-to-end pokrivajući Server Actions, Route Handlers i navigaciju na klijentu, a zatim razdvoji dashboarde po Edge vs Node runtimeu.
  • Koristi Sentry za brzo trijažiranje grešaka i utjecaj na korisnike, a dodaj OpenTelemetry na Node runtimeu za vendor-neutral distribuirane traceove.
  • Standardiziraj polja za korelaciju: x-request-id, x-session-id, plus trace headere poput sentry-trace i baggage, pa ih stavi u logove, spanove i error eventove.
  • Izgradi dashboarde koji brzo odgovaraju na operativna pitanja: 5xx stopa, P95 latencija, regresije po releaseu i zdravlje ovisnosti po hostnameu.
  • Kreni s pragovima upozorenja temeljenima na stopama i baselineu (ne na sirovim brojevima) i rutiraj upozorenja po ozbiljnosti kako bi izbjegao alert fatigue.

# Zaključak#

Dobra postavka “Next.js logging monitoring Sentry OpenTelemetry” nije u prikupljanju više podataka — nego u tome da kvarove možeš dijagnosticirati u minutama. Instrumentiraj Sentry kroz klijent, server i edge, dodaj OpenTelemetry na Node runtimeu za prenosiv tracing, standardiziraj korelacijske ID-jeve i isporuči dashboarde i upozorenja koja mapiraju na utjecaj na korisnike i poslovni rizik.

Ako želiš da Samioda ovo implementira end-to-end u tvojoj Next.js codebaseu, uključujući strategiju runtime podjele, dashboarde i fino podešavanje upozorenja, kontaktiraj nas i isporučit ćemo observability postavku koju tvoj tim stvarno može operativno koristiti u produkciji.

FAQ

Share
A
Adrijan OmićevićOsnivač i senior developer

Osnivač i senior developer u Samiodi. 8+ godina iskustva u izradi React, Next.js, Flutter i n8n rješenja za klijente diljem Europe.

Trebate pomoć s projektom?

Gradimo prilagođena rješenja koristeći tehnologije iz ovog članka. Senior tim, fiksne cijene.