21. Error Reporting & Application Monitoring (Sentry & Alternatif)

Dalam lingkungan produksi (production), developer tidak dapat mengamati console log secara langsung dari browser pengguna. Saat terjadi kesalahan (crash atau exception) pada aplikasi frontend, pengguna cenderung menutup tab aplikasi atau me-refresh halaman tanpa melaporkan detail bug tersebut.

Oleh karena itu, sistem Error Reporting & Application Performance Monitoring (APM) sangat krusial bagi tim Frontend Bit Group Asia untuk menangkap, mengelompokkan, dan memprioritaskan perbaikan bug secara real-time sebelum berdampak luas pada pengguna lain.


A. Sentry: Standar Utama Error Tracking

Sentry adalah platform pemantauan kode berbasis cloud yang paling banyak digunakan di ekosistem frontend. Sentry melacak kesalahan runtime JavaScript/TypeScript secara otomatis dan memberikan konteks mendalam mengenai penyebab terjadinya error.

Fitur Utama Sentry untuk Frontend:

  1. Breadcrumbs: Kronologi aktivitas pengguna sebelum terjadi error (e.g., penekanan tombol, navigasi rute halaman, request API, hingga logs konsol). Ini sangat mempermudah reproduksi bug.
  2. Session Replay: Merekam visual interaksi pengguna (seperti video/screen-recording) saat terjadi error dengan fitur sensor otomatis untuk menjaga privasi data sensitif.
  3. Source Maps Integration: Menerjemahkan stack trace yang terkompresi/ter-minify (main.min.js) menjadi baris kode asli beserta nama file yang tepat di repositori Git.
  4. Performance Monitoring: Mengukur waktu pemuatan halaman, performa interaksi (Core Web Vitals), dan mendeteksi request API yang lambat.

B. Cara Integrasi Sentry pada Project Frontend

1. Inisialisasi pada React (dengan Vite)

Pasang paket SDK Sentry:

npm install @sentry/react

Lakukan inisialisasi pada file entri utama aplikasi (e.g., main.tsx atau index.tsx):

import React from "react";
import ReactDOM from "react-dom/client";
import * as Sentry from "@sentry/react";
import App from "./App";

Sentry.init({
  // DSN (Data Source Name) diperoleh dari dashboard proyek Sentry Anda
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.replayIntegration({
      maskAllText: true,      // Masking semua teks teks demi privasi pengguna
      blockAllMedia: true,    // Menyensor gambar/video dalam session replay
    }),
  ],

  // Tracing Performa: 1.0 berarti merekam 100% transaksi performa untuk pengembangan.
  // Kurangi nilainya di production (misal: 0.1 atau 10%) untuk menghemat kuota data.
  tracesSampleRate: 1.0,

  // Session Replay: Rekam sesi error
  replaysSessionSampleRate: 0.1, // Rekam 10% dari sesi pengguna biasa
  replaysOnErrorSampleRate: 1.0, // Selalu rekam dan upload video jika terjadi error
  
  // Menentukan environment rilis
  environment: import.meta.env.MODE || "development",
});

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

2. Inisialisasi pada Next.js

Untuk Next.js, disarankan menggunakan Wizard otomatis Sentry karena ia secara otomatis mengonfigurasi build-step untuk pengunggahan source maps:

npx @sentry/wizard@latest -i nextjs

Wizard ini akan menghasilkan file konfigurasi berikut:

  • sentry.client.config.ts (untuk menangkap error di browser pengguna)
  • sentry.server.config.ts (untuk Server-Side Rendering / API Routes)
  • sentry.edge.config.ts (untuk Middleware / Edge runtime)

Contoh isi dari sentry.client.config.ts:

import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  replaysSessionSampleRate: 0.1,
  integrations: [
    Sentry.replayIntegration({
      maskAllText: true,
    }),
  ],
});

C. Alternatif Lain Selain Sentry

Jika tim membutuhkan fitur yang lebih spesifik atau terkendala regulasi privasi data, berikut adalah alternatif industri terbaik selain Sentry:

1. LogRocket

  • Fokus Utama: Session Replay mendalam, analisis perilaku pengguna (Product Analytics), dan pelacakan state.
  • Kelebihan: Sangat unggul dalam merekonstruksi visual DOM. LogRocket mengizinkan Anda melihat persis apa yang dilakukan pengguna beserta isi log dari State Management (Redux, NgRx, Zustand, Vuex) dan aktivitas Network Request (request/response payload).
  • Kekurangan: Harga relatif mahal dibandingkan tool pelacak error murni. Overhead performa sedikit lebih terasa karena merekam perubahan DOM secara berkelanjutan.
  • Contoh Inisialisasi:
    npm install logrocket logrocket-react
    
    import LogRocket from 'logrocket';
    import setupLogRocketReact from 'logrocket-react';
    
    // Inisialisasi LogRocket
    LogRocket.init('your-app-id/project-name');
    
    // Hubungkan dengan React untuk melacak error component tree
    setupLogRocketReact(LogRocket);
    
    // Mengirim identifikasi user (opsional)
    LogRocket.identify('user_12345', {
      name: 'John Doe',
      email: 'john.doe@example.com',
      role: 'premium_user'
    });
    

2. Bugsnag (oleh SmartBear)

  • Fokus Utama: Manajemen error yang terfokus, minimalis, dan sangat berorientasi pada developer produktivitas.
  • Kelebihan: Dasbor sangat bersih dan mudah dimengerti. Algoritma pengelompokan error (error grouping) bekerja sangat cerdas untuk mendeteksi apakah bug dipicu oleh rilis tertentu. Penentuan prioritas berdasarkan "User Impact Rate" membantu tim fokus pada bug yang dialami oleh mayoritas pengguna.
  • Kekurangan: Fitur pemantauan performa (APM) dan perekaman sesi visual tidak selengkap Sentry atau LogRocket.
  • Contoh Inisialisasi:
    npm install @bugsnag/js @bugsnag/plugin-react
    
    import React from 'react';
    import Bugsnag from '@bugsnag/js';
    import BugsnagPluginReact from '@bugsnag/plugin-react';
    
    // Mulai Bugsnag
    Bugsnag.start({
      apiKey: 'YOUR-API-KEY-HERE',
      plugins: [new BugsnagPluginReact()]
    });
    
    // Buat Error Boundary React bawaan Bugsnag
    const ErrorBoundary = Bugsnag.getPlugin('react').createErrorBoundary(React);
    export default ErrorBoundary;
    

3. Datadog (RUM - Real User Monitoring)

  • Fokus Utama: Observabilitas sistem skala besar (enterprise-grade full-stack observability).
  • Kelebihan: Integrasi terpadu. Error di frontend dapat dilacak jalurnya secara langsung ke server API backend, database, hingga infrastruktur cloud dalam satu alur visual (end-to-end trace correlation).
  • Kekurangan: Kurva pembelajaran sangat tajam (steep learning curve) dan konfigurasi awal sangat rumit. Harganya mahal dan model lisensinya kompleks untuk startup/skala menengah.
  • Contoh Inisialisasi:
    npm install @datadog/browser-rum
    
    import { datadogRum } from '@datadog/browser-rum';
    
    datadogRum.init({
      applicationId: 'YOUR_APPLICATION_ID',
      clientToken: 'YOUR_CLIENT_TOKEN',
      site: 'datadoghq.com',
      service: 'frontend-docs-portal',
      env: 'production',
      version: '1.0.0',
      sessionSampleRate: 100,             // Rekam 100% dari sesi pengguna
      sessionReplaySampleRate: 20,        // Rekam video replay untuk 20% sesi
      trackUserInteractions: true,
      trackResources: true,
      trackLongTasks: true,
      defaultPrivacyLevel: 'mask-user-input', // Masking input form demi privasi
    });
    

4. Rollbar

  • Fokus Utama: Real-time error tracking dengan penekanan pada otomasi CI/CD dan deteksi regresi instan.
  • Kelebihan: Fitur telemetry yang andal dan integrasi kuat dengan sistem deployment. Sistem notifikasi instan yang sangat adaptif.
  • Kekurangan: Desain dasbor/UI terasa agak kuno. Fitur monitoring performa aplikasi frontend kurang optimal.
  • Contoh Inisialisasi:
    npm install rollbar
    
    import Rollbar from 'rollbar';
    
    // Konfigurasi dan inisialisasi Rollbar
    const rollbar = new Rollbar({
      accessToken: 'POST_CLIENT_ITEM_ACCESS_TOKEN',
      captureUncaught: true,
      captureUnhandledRejections: true,
      payload: {
        environment: 'production'
      }
    });
    

5. OpenReplay / PostHog (Solusi Self-Hosted & Open-Source)

  • Fokus Utama: Privasi data penuh dan analisis produk open-source.
  • Kelebihan: Dapat di-deploy di server internal milik perusahaan (on-premise AWS/GCP sendiri). Ini adalah solusi wajib bagi proyek yang terikat regulasi privasi ketat (seperti sektor perbankan, kesehatan, atau pemerintahan) karena data sesi user tidak pernah keluar ke pihak ketiga.
  • Kekurangan: Membutuhkan biaya infrastruktur server sendiri dan tim DevOps untuk memelihara ketersediaan sistem monitoring tersebut.
  • Contoh Inisialisasi (PostHog):
    npm install posthog-js
    
    import posthog from 'posthog-js';
    
    posthog.init('YOUR_PROJECT_API_KEY', {
      api_host: 'https://us.i.posthog.com',
      person_profiles: 'identified_only', // Melacak profil jika sudah diidentifikasi
      session_recording: {
        maskAllInputFields: true,         // Lindungi input form
      }
    });
    

6. GlitchTip (Alternatif Sentry yang Sangat Ringan & Kompatibel)

  • Fokus Utama: Pemantauan error open-source sederhana yang kompatibel penuh dengan SDK Sentry.
  • Kelebihan: Merupakan drop-in replacement untuk Sentry. Anda bisa menggunakan library SDK Sentry resmi (seperti @sentry/react atau @sentry/nextjs) tetapi mengarahkan DSN ke server GlitchTip sendiri. Proses deploy mandiri sangat ringan karena hanya memerlukan PostgreSQL (tidak seperti Sentry Self-Hosted resmi yang memerlukan RAM minimal 8GB-16GB untuk menjalankan Kafka & Clickhouse).
  • Kekurangan: Dasbor/UI-nya sangat sederhana dan tidak memiliki visualisasi replay/UX secanggih Sentry atau LogRocket.
  • Contoh Inisialisasi: Cukup gunakan SDK Sentry, lalu ubah DSN-nya ke alamat host GlitchTip Anda:
    import * as Sentry from "@sentry/react";
    
    Sentry.init({
      dsn: "https://your-glitchtip-key@your-glitchtip-domain.com/1",
    });
    

D. Tabel Perbandingan Cepat

PlatformFokus UtamaKekuatan UtamaDukungan Self-HostedOpsi Gratis / Free TierTarget Pengguna Ideal
SentryError Tracking & APMDeteksi error akurat, breadcrumbs lengkap, setup cepatYa (Sentry Self-Hosted)Ada (SaaS: 5K events/bln)Proyek menengah-besar yang butuh tool all-in-one
LogRocketSession Replay & UX AnalyticsRekonstruksi DOM & integrasi state management (Zustand/Redux)Tidak (SaaS saja)Ada (SaaS: 1K sesi/bln)Aplikasi kompleks (SaaS/E-commerce) yang sering mendapati "bug misterius"
BugsnagDiagnostic & Crash ReportingPrioritas bug berdasarkan dampak user, dasbor bersihTidak (SaaS saja)Ada (SaaS: 2K events/bln, 1 user)Tim developer yang fokus pada perbaikan bug yang cepat tanpa gangguan noise
DatadogFull-Stack ObservabilityKorelasi frontend error langsung ke log server/databaseTidak (SaaS saja)Tidak Ada (Hanya 14 hari trial)Skala Enterprise besar dengan arsitektur Microservices rumit
PostHogProduct Analytics & Session ReplayFitur lengkap (feature flags, replay, analytics), kuota melimpahYa (Community Edition gratis)Sangat Generous (1M events + 15K replay/bln)Startup yang menginginkan analytics & session recording gratis kuota besar
OpenReplaySession Replay DeveloperKeamanan & kepemilikan data penuh, open-sourceYa (100% gratis tanpa batas sesi)Ada (SaaS: 1K sesi/bln)Perusahaan dengan regulasi privasi ketat (Fintech/Gov)
GlitchTipSentry-compatible Error TrackingSangat ringan, menggunakan API Sentry (drop-in replacement)Ya (100% gratis & ringan via Docker)Ada (SaaS: 1K events/bln)Tim yang ingin self-host Sentry-like tool tapi memiliki server berspesifikasi kecil

E. Opsi Gratis & Skema Harga (Free Tier & Open-Source Options)

Jika anggaran (budget) adalah pertimbangan utama tim, berikut adalah panduan memilih berdasarkan skema gratisnya:

  1. PostHog (Rekomendasi Utama untuk SaaS Gratis): PostHog adalah opsi SaaS gratis terbaik karena memberikan 1 juta events per bulan gratis dan 15.000 session recordings per bulan gratis secara permanen. Angka ini sangat mencukupi untuk mayoritas aplikasi skala kecil hingga menengah tanpa harus mengeluarkan biaya berlangganan.

  2. Self-Hosted Open-Source (100% Gratis Tanpa Batasan Sesi):

    • OpenReplay: Jika Anda butuh Session Replay gratis tanpa batas, Anda bisa menginstalnya di server VPS (seperti AWS EC2 atau DigitalOcean) milik sendiri. Anda hanya perlu membayar biaya sewa server tersebut.
    • GlitchTip: Jika Anda ingin menggunakan SDK Sentry (@sentry/react) tapi tidak ingin membayar biaya langganan Sentry SaaS, Anda dapat menjalankan GlitchTip di VPS Anda. GlitchTip sangat ringan karena hanya membutuhkan PostgreSQL, berbeda dengan Sentry Self-Hosted resmi yang membutuhkan RAM besar.
  3. SaaS Free Tier Klasik (Kapasitas Terbatas):

    • Sentry: Memberikan 5.000 event error per bulan pada paket Developer. Ini sangat cepat habis jika aplikasi Anda memiliki traffic menengah atau banyak error yang berisik.
    • LogRocket: Memberikan 1.000 sesi per bulan (maksimal 1-month data retention).
    • Bugsnag: Memberikan 2.000 event error per bulan (terbatas untuk 1 user).

F. Best Practices Penerapan Error Reporting

Untuk mencegah membengkaknya tagihan layanan monitoring (alert fatigue dan quota usage), serta menjaga privasi pengguna, ikuti praktik terbaik berikut:

1. Pengunggahan Source Maps Secara Aman

Agar stack trace dapat dibaca dengan jelas di Sentry/alternatifnya, aplikasi memerlukan file .map (source maps). Namun, jangan pernah membiarkan file .map dapat diakses publik di server produksi karena pihak luar dapat merekonstruksi ulang seluruh source code frontend Anda.

  • Solusi: Gunakan plugin bundler (seperti @sentry/vite-plugin atau Next.js Webpack configuration) untuk mengunggah source maps ke server Sentry saat proses build di CI/CD, lalu konfigurasikan script build Anda untuk menghapus/mendelete semua file .map dari folder dist/ atau .next/ sebelum proses deployment selesai.

2. Sensor Data Sensitif (PII - Personally Identifiable Information)

Secara bawaan, pastikan data sensitif seperti password, nomor kartu kredit, NIK, token otorisasi, dan email pengguna tidak ikut terkirim ke platform error reporting.

Gunakan filter beforeSend pada konfigurasi SDK untuk menyensor data sensitif:

Sentry.init({
  dsn: "your-dsn",
  beforeSend(event) {
    // Menghapus header Authorization agar token JWT tidak bocor ke log
    if (event.request && event.request.headers) {
      delete event.request.headers["authorization"];
      delete event.request.headers["cookie"];
    }
    
    // Contoh penyensoran payload data bermasalah
    const stringified = JSON.stringify(event);
    if (stringified.includes("password") || stringified.includes("credit_card")) {
      // Modifikasi event payload sebelum dikirim
      event.extra = { ...event.extra, redacted: "Data disensor demi keamanan" };
    }
    
    return event;
  },
});

3. Memfilter Error yang Tidak Perlu (Noise Filtering)

Sering kali, error yang dilaporkan ke dashboard disebabkan oleh ekstensi browser pengguna (seperti AdBlocker yang memblokir script eksternal), bot/crawler, atau koneksi internet pengguna yang terputus di tengah jalan. Hal ini memicu alert fatigue bagi tim.

Saring error tersebut dengan parameter ignoreErrors:

Sentry.init({
  dsn: "your-dsn",
  ignoreErrors: [
    // Error umum akibat kegagalan jaringan pengguna
    "Network Error",
    "Failed to fetch",
    "TypeError: Failed to fetch",
    "Load failed",
    // Error yang dipicu ekstensi browser
    "webkit-masked-image",
    "ResizeObserver loop limit exceeded",
  ],
  // Abaikan URL script luar (misal iklan atau plugin browser yang menyuntikkan script)
  denyUrls: [
    /extensions\//i,
    /^chrome:\/\//i,
    /google-analytics/i,
  ],
});

4. Gunakan React Error Boundary untuk Fail-Safe UI

Gunakan component Error Boundary untuk menangkap error pada sub-component tree, menampilkan antarmuka ramah pengguna (fallback UI) agar aplikasi tidak blank putih secara keseluruhan, serta melaporkan kejadian tersebut secara otomatis.

import React, { Component, ErrorInfo, ReactNode } from "react";
import * as Sentry from "@sentry/react";

interface Props {
  children?: ReactNode;
}

interface State {
  hasError: boolean;
}

class SafeErrorBoundary extends Component<Props, State> {
  public state: State = {
    hasError: false
  };

  public static getDerivedStateFromError(_: Error): State {
    return { hasError: true };
  }

  public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // Kirim error detail ke Sentry
    Sentry.captureException(error, { extra: errorInfo });
  }

  public render() {
    if (this.state.hasError) {
      return (
        <div style={{ padding: "2rem", textAlign: "center" }}>
          <h2>Oops, terjadi kesalahan sistem.</h2>
          <p>Tim kami telah mendapatkan notifikasi. Silakan muat ulang halaman atau coba kembali nanti.</p>
          <button onClick={() => window.location.reload()}>Muat Ulang Halaman</button>
        </div>
      );
    }

    return this.children;
  }
}

export default SafeErrorBoundary;

Wrap komponen utama aplikasi Anda (atau modul-modul penting seperti Dashboard, Checkout) menggunakan SafeErrorBoundary ini.

© 2026 Bit Group Asia. All rights reserved.

ArchitectureSecurityGuidelines