Belajar Fullstack Developer - Observability Fullstack
Episode 24 of 28

Belajar Fullstack Developer - Observability Fullstack

Melihat apa yang sebenarnya terjadi di production: tiga pilar observability (logs, metrics, traces), integrasi error tracking dengan Sentry, trace request dari browser hingga database, dan membangun dashboard pemantauan.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Di development, error muncul di layar kalian. Di production, error terjadi pada pengguna — dan kalian tidak ada di sana. Episode ini membahas observability fullstack: kemampuan untuk menjawab pertanyaan tentang sistem yang sedang berjalan — apa yang lambat, apa yang gagal, dan mengapa.

Di episode 11 kita membangun fondasi (structured logging). Sekarang kita lengkapi menjadi sistem penuh dengan tiga pilar observability — logs, metrics, traces — ditambah error tracking dan dashboard. Inilah yang memisahkan aplikasi "yang jalan" dari aplikasi "yang dipahami".

Tiga Pilar Observability

PilarMenjawabContoh
Logs"Apa yang terjadi?"gagal query note 123: koneksi timeout
Metrics"Berapa banyak?"3% error rate, p99 latency 800 ms
Traces"Bagaimana alurnya?"browser → route → DB → LLM, 1,2 detik

Logs memberi detail, metrics memberi angka, traces memberi hubungan antar langkah — termasuk bagaimana satu request mengalir melewati banyak lapisan. Observability penuh berarti ketiganya.

100%

Error Tracking: Sentry

Alat error tracking mengubah "error acak" menjadi data terorganisir: ringkasan, pengelompokan (issue), stack trace asli, dan konteks pengguna. Sentry adalah pilihan paling umum untuk Next.js:

Install Sentry
pnpm add @sentry/nextjs
pnpm sentry/wizard

Wizard mengonfigurasi otomatis: Sentry.init di instrumentation.ts, Sentry.ErrorBoundary untuk UI, dan wrapper route handler. Setelah itu, setiap error — di server atau browser — muncul sebagai issue:

Set user konteks agar error terlacak
import * as Sentry from "@sentry/nextjs"
 
export async function GET(request: Request) {
  const session = await auth()
  if (session) {
    Sentry.setUser({ id: session.user.id, email: session.user.email })
  }
  try {
    // ...
  } catch (error) {
    Sentry.captureException(error)
    return Response.json({ error: "Terjadi kesalahan" }, { status: 500 })
  }
}

Tip

Error tracking bukan pengganti logging — keduanya saling melengkapi. Sentry menjawab "error apa yang paling sering dan siapa terkena"; log detail menjawab "apa yang terjadi tepat sebelum error itu". Sambungkan keduanya: bawa requestId di log dan kirim ke Sentry lewat Sentry.setContext, sehingga dari issue Sentry bisa melompat ke log terkait.

Tracing: Satu Request, Banyak Lapisan

Tracing (OpenTelemetry standar) menangkap perjalanan satu request: waktu di browser, di route handler, di query database, di panggilan LLM. Next.js mendukung OpenTelemetry secara bawaan:

next.config.ts
export default NextConfig({
  experimental: {
    instrumentationHook: true,
  },
})
src/instrumentation.ts
export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    const { initNodeTracing } = await import("@/lib/tracing")
    await initNodeTracing()
  }
}

Dengan tracing aktif, suatu laporan di dashboard bisa menjawab pertanyaan seperti: "kenapa halaman catatan lambat?" → trace menunjukkan 1,1 detik di query database, bukan di render. Tanpa trace, kalian hanya menebak.

Metrics: Mengawasi Kesehatan dari Jauh

Metrics adalah "detak jantung" — angka yang diagregasi dan di-alert. Tiga set yang selalu berguna:

SetContohAlert ketika
Trafficrequest/s, pengguna aktifLonjakan abnormal
Latencyp50, p95, p99p99 > target
Errorserror rate, 5xxRate > 1%

Untuk aplikasi fullstack yang di-host Vercel, metrik platform (request count, latency, error) sudah otomatis. Tambahkan metrik aplikasi yang bermakna bisnis — misal job queue melonjak (episode 13) atau upload gagal (episode 12):

Contoh metrik aplikasi (di worker)
const start = Date.now()
try {
  await processJob(job)
  recordCounter("jobs.processed", { queue: job.queue })
} catch (error) {
  recordCounter("jobs.failed", { queue: job.queue })
}
recordHistogram("jobs.duration_ms", Date.now() - start)

Logs: Menyempurnakan Fondasi

Structured log di episode 11 (Pino) sekarang dialirkan ke sistem terpusat — jangan biarkan log tinggal di stdout container (hilang saat restart). Gunakan penyedia log terkelola atau ekspor sendiri. Kunci yang membuat log berguna di production:

  • requestId per request: satu id yang sama di semua log — untuk menelusuri satu pengguna di seluruh lapisan.
  • Level yang jujur: info untuk kejadian normal, warn untuk anomali, error untuk kegagalan — jangan semua info.
  • Struktur konsisten: konteks di object, bukan string berantai.
Pola requestId di route handler
import { randomUUID } from "node:crypto"
 
export async function GET(request: Request) {
  const requestId = request.headers.get("x-request-id") ?? randomUUID()
  logger = logger.child({ requestId })
  logger.info("request dimulai")
  // ...
}

Warning

Satu peringatan praktis: jangan log seluruh response body — bisa berisi data pribadi pengguna (melanggar episode 20), dan membengkakkan volume log (melanggar anggaran). Log id, status code, dan durasi; simpan body detail hanya saat error dan hanya untuk skema yang sudah disaring.

Dashboard: Menyatukan Semua

Observability tanpa dashboard tidak berguna — kalian tidak akan membuka konsol tiap menit. Buat dashboard minimal (di penyedia pilihan kalian) dengan satu layar yang menjawab tiga pertanyaan:

  1. Apakah sistem sehat sekarang? (error rate, latency p99)
  2. Apa yang berubah? (traffic, perbandingan harian)
  3. Error apa yang paling sering? (top issues dari Sentry)

Mulai dari satu dashboard ini; tambah panel sesuai kebutuhan — bukan sebaliknya.

Praktik: Observability Penuh

Selesaikan dengan urutan berikut:

  1. Setup Sentry dengan wizard; pastikan error di route handler masuk sebagai issue.
  2. Tambahkan Sentry.setUser dan requestId di log pada route handler penting.
  3. Aktifkan tracing (instrumentation) dan lihat trace satu request di dashboard — identifikasi lapisan terlambat.
  4. Buat dashboard: error rate, p99 latency, top issues.
  5. Pasang alert: p99 melebihi 1 detik atau error rate melebihi 1% → notifikasi.
Bangkitkan error uji dan cek muncul di Sentry
curl -s http://localhost:3000/notes/nonexistent -o /dev/null

Penutup

Inti yang harus dibawa pulang:

  • Observability = logs + metrics + traces; ketiganya saling melengkapi.
  • Sentry mengubah error menjadi issue terkelompok dengan konteks pengguna.
  • Tracing menunjukkan perjalanan satu request lintas lapisan — temukan bottleneck sebenarnya.
  • Metrics (p95/p99, error rate) adalah detak jantung yang bisa di-alert.
  • Log dengan requestId + level jujur + struktur konsisten; jangan log data pribadi.
  • Dashboard minimal dulu: sehat, berubah, error apa — lalu perluas.

Di episode 25, episode penutup seri ini, kita membahas performance & optimization lanjutan — profiling, bundle size, dan tuning database untuk produksi. Sampai jumpa di episode 25!

Belajar Fullstack Developer - Observability Fullstack | Belajar Fullstack