Langsung ke konten
KamusNgoding
Terapan Laravel 6 menit baca

Debugging Laravel dengan Telescope: Monitoring Request, Query, Job, dan Exception

#laravel #telescope #debugging #monitoring #production #logging #applied

Pendahuluan

“Di local jalan, di production error.”

Kalimat ini adalah nightmare setiap developer Laravel. Di local kamu punya dd(), dump(), dan Debugbar. Tapi di production?

  • dd() crash halaman untuk semua user
  • Log::info() tersebar di file teks yang susah dibaca
  • Query lambat tidak terdeteksi sampai user komplain

Laravel Telescope adalah panel monitoring yang berjalan di dalam aplikasi Laravel-mu sendiri. Seperti “black box recorder” pesawat — merekam semua yang terjadi:

  • Setiap HTTP request yang masuk + waktu respons
  • Semua query SQL yang dieksekusi + durasinya
  • Semua Queue job dengan status dan payload
  • Semua exception dengan full stack trace
  • Email yang terkirim (bisa preview di browser!)
  • Cache hit/miss statistics

Telescope vs Alternatif

ToolTipeHostingBiayaCocok untuk
Laravel TelescopeRequest inspectorSelf-hostedGratisDevelopment + Production
Laravel DebugbarPage overlaySelf-hostedGratisDevelopment only
SentryError trackingSaaS/self-hostedFreemiumError monitoring production
New RelicAPMSaaSBerbayarEnterprise monitoring
DatadogFull observabilitySaaSBerbayarLarge scale

Telescope adalah titik awal sempurna — gratis, self-hosted, dan sudah terintegrasi penuh dengan Laravel.


Langkah 1: Instalasi Telescope

# Install package
composer require laravel/telescope

# Publish assets dan migration
php artisan telescope:install

# Jalankan migration (buat tabel telescope_entries)
php artisan migrate
# Verifikasi — akses dashboard di browser
php artisan serve
# Buka: http://localhost:8000/telescope

Seharusnya dashboard Telescope langsung muncul! Coba buka beberapa halaman aplikasi, lalu refresh Telescope — semua request akan terekam.


Langkah 2: Tour Dashboard — Fitur-fitur Utama

📡 Requests — Monitor Semua HTTP Request

Setiap request masuk ke aplikasi tercatat lengkap:

  • URL, Method (GET/POST/DELETE)
  • Status code (200, 422, 500)
  • Response time (ms)
  • Memory usage
  • Semua parameter request
  • Full response body

Cara pakai: Kalau ada user yang bilang “halaman error”, langsung cek Requests di Telescope — cari request dari IP user tersebut dan lihat error detail.

🗄️ Queries — Temukan Query Lambat

Semua SQL query tercatat dengan:

  • Query lengkap (sudah terisi binding parameter)
  • Durasi (ms)
  • Connection yang digunakan

Fitur killer: Klik tab “Slow Queries” (> 100ms) — langsung terlihat query mana yang menjadi bottleneck. Cocok untuk menemukan N+1 yang terlewat di proses optimasi query.

// config/telescope.php — sesuaikan threshold slow query
'watchers' => [
    Watchers\QueryWatcher::class => [
        'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
        'slow'    => 100, // ms — query di atas ini ditandai "slow"
    ],
],

⚙️ Jobs — Pantau Queue Worker

Status setiap job Queue tercatat:

  • Nama Job class
  • Queue yang digunakan
  • Status: pending, processed, failed
  • Payload lengkap
  • Durasi eksekusi
  • Exception jika gagal

Cara pakai: Job SendWelcomeEmail tidak terkirim? Buka Jobs di Telescope → filter “failed” → lihat exception message dan stack trace lengkap.

💥 Exceptions — Full Stack Trace

Setiap exception yang tidak tertangkap dicatat:

  • Exception class dan message
  • File dan line number
  • Full stack trace
  • Request yang menyebabkan exception
  • User yang mengalaminya

Jauh lebih informatif dari sekadar [2024-01-01] production.ERROR: ... di log file.

📧 Mail — Preview Email Sebelum Terkirim

Semua email yang dikirim tersimpan di Telescope — bisa di-preview langsung di browser, tanpa perlu buka inbox:

// Ini akan muncul di Telescope > Mail
Mail::to($user)->send(new WelcomeMail($user));

Sangat berguna untuk debugging template email tanpa harus punya inbox test.

📊 Cache — Hit/Miss Statistics

Setiap operasi cache dicatat: Cache::get(), Cache::put(), Cache::forget(). Bisa langsung lihat berapa persen cache hit vs miss untuk mengukur efektivitas strategi caching.


Langkah 3: Deteksi Slow Queries di Production

// app/Providers/TelescopeServiceProvider.php

use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\Telescope;

public function register(): void
{
    // Hanya rekam slow queries (> 100ms) di production
    // Mengurangi noise dan ukuran database Telescope
    Telescope::filter(function (IncomingEntry $entry) {
        if ($entry->type === EntryType::QUERY) {
            return $entry->content['slow'] === true;
        }
        return true;
    });
}

Langkah 4: Debugging Failed Jobs

Saat job gagal di Queue:

  1. Buka Telescope → Jobs tab
  2. Filter: Status = failed
  3. Klik job yang gagal → lihat detail:
    • Exception: Connection refused to Redis
    • Stack trace: menunjuk ke baris yang gagal
    • Payload: data yang dikirim ke job
    • Attempts: sudah dicoba berapa kali

Dari sini langsung bisa debug tanpa perlu php artisan queue:failed + parse log manual.


Langkah 5: Konfigurasi Aman untuk Production

Di production, jangan biarkan semua orang mengakses Telescope — ini berisi data sensitif!

<?php
// app/Providers/TelescopeServiceProvider.php

namespace App\Providers;

use App\Models\User;
use Illuminate\Support\Facades\Gate;
use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\Telescope;
use Laravel\Telescope\TelescopeApplicationServiceProvider;

class TelescopeServiceProvider extends TelescopeApplicationServiceProvider
{
    public function register(): void
    {
        // Konfigurasi per environment
        Telescope::night(); // Dark mode

        $this->hideSensitiveRequestDetails();

        // Filter: di production, hanya rekam hal penting
        if ($this->app->isProduction()) {
            Telescope::filter(function (IncomingEntry $entry) {
                return $entry->isReportableException()   // Semua exception
                    || $entry->isFailedRequest()          // Request yang gagal (5xx)
                    || $entry->isFailedJob()              // Job yang gagal
                    || $entry->isScheduledTask()          // Cron job
                    || $entry->hasMonitoredTag();         // Entry yang di-tag manual
            });
        }
    }

    // PENTING: hanya izinkan user tertentu mengakses dashboard
    protected function gate(): void
    {
        Gate::define('viewTelescope', function (User $user) {
            // Ganti dengan logic authorization kamu
            return in_array($user->email, [
                '[email protected]',
                '[email protected]',
            ]);
            // Atau berdasarkan role: return $user->hasRole('admin');
        });
    }

    // Sembunyikan data sensitif dari log Telescope
    protected function hideSensitiveRequestDetails(): void
    {
        if ($this->app->isLocal()) {
            return;
        }

        Telescope::hideRequestParameters(['password', 'password_confirmation', 'token']);
        Telescope::hideRequestHeaders(['cookie', 'x-csrf-token', 'authorization']);
    }
}

Langkah 6: Menambahkan Tag Manual

Tandai entry Telescope untuk mudah ditemukan nanti:

use Laravel\Telescope\Telescope;

// Di Job class
public function handle(): void
{
    Telescope::tag(fn() => ['order:' . $this->order->id, 'user:' . $this->order->user_id]);

    // Proses job...
}

// Di Controller
public function processPayment(Request $request)
{
    Telescope::tag(fn() => ['payment', 'user:' . auth()->id()]);

    // Proses pembayaran...
}

Sekarang bisa filter di Telescope: “tampilkan semua entries terkait user:42” atau “semua entries terkait order:123”.


Langkah 7: Pembersihan Data Otomatis

Telescope menyimpan data di database — tanpa pembersihan, tabel bisa sangat besar:

# Hapus entries lebih dari 48 jam
php artisan telescope:prune

# Hapus entries lebih dari 7 hari
php artisan telescope:prune --hours=168

Setup prune otomatis di scheduler:

// routes/console.php atau app/Console/Kernel.php

use Illuminate\Support\Facades\Schedule;

Schedule::command('telescope:prune --hours=48')->daily();

Untuk production dengan traffic tinggi, pertimbangkan menggunakan Redis sebagai storage (bukan MySQL):

// config/telescope.php
'driver' => env('TELESCOPE_DRIVER', 'database'),
// Bisa diganti: 'redis'

Contoh Workflow Debugging Production Issue

Skenario: User melaporkan “pembayaran saya error” tanpa detail lebih lanjut.

Langkah debug dengan Telescope:

1. Buka Telescope → Requests
2. Filter: Status = 5xx, Time = 30 menit terakhir
3. Temukan POST /api/orders/checkout dengan status 500
4. Klik request → lihat Exception:
   "SQLSTATE[HY000]: General error: 1364 Field 'snap_token' doesn't have a default value"
5. Lihat Query tab di request yang sama:
   INSERT INTO orders (user_id, total_amount) VALUES (42, 150000)
   -- snap_token field hilang!
6. Cek kode → ternyata lupa isi snap_token setelah dapat response Midtrans
7. Fix → deploy → konfirmasi selesai

Total debug time: 5 menit vs berjam-jam parse log file.


Troubleshooting: Error yang Sering Muncul

Telescope menyebabkan database tumbuh terlalu cepat

Penyebab: Semua request direkam, termasuk health check, asset request, dll.

Solusi:

// Di TelescopeServiceProvider, filter entry yang tidak perlu
Telescope::filter(function (IncomingEntry $entry) {
    // Skip health check endpoint
    if ($entry->type === EntryType::REQUEST) {
        $url = $entry->content['uri'] ?? '';
        if (str_contains($url, '/health') || str_contains($url, '/ping')) {
            return false;
        }
    }
    return true;
});

// Jalankan prune lebih sering
Schedule::command('telescope:prune --hours=24')->twiceDaily();

Telescope dashboard 403 Forbidden

Penyebab: Gate viewTelescope tidak mengizinkan user saat ini, atau APP_ENV != local.

Solusi:

// Cek gate definition di TelescopeServiceProvider
Gate::define('viewTelescope', function ($user) {
    \Log::info('Telescope auth check', ['email' => $user?->email]);
    return in_array($user?->email, config('telescope.allowed_emails', []));
});

// Tambahkan di .env untuk production
TELESCOPE_ENABLED=true

// Untuk testing sementara tanpa auth (HANYA development!):
// Hapus atau comment gate definition

Telescope memperlambat response time di production

Penyebab: Telescope merekam terlalu banyak data per request.

Solusi:

// Batasi data yang direkam
Telescope::filter(function (IncomingEntry $entry) {
    // Di production: hanya rekam errors dan slow items
    if (app()->isProduction()) {
        return match($entry->type) {
            EntryType::REQUEST   => $entry->content['response_status'] >= 400,
            EntryType::QUERY     => $entry->content['slow'] === true,
            EntryType::JOB       => $entry->content['status'] === 'failed',
            EntryType::EXCEPTION => true,
            default              => false,
        };
    }
    return true;
});

Pertanyaan yang Sering Diajukan

Telescope apakah aman untuk production?

Ya, jika dikonfigurasi dengan benar. Wajib setup Gate authorization agar hanya admin yang bisa akses. Wajib aktifkan filter untuk mengurangi data yang direkam. Wajib setup telescope:prune agar database tidak penuh. Tanpa konfigurasi yang benar, Telescope bisa jadi security risk (data sensitif terbuka) dan performance issue.

Telescope vs Sentry, kapan menggunakan yang mana?

Gunakan Telescope untuk debugging harian di development dan investigasi issue di production (query lambat, job gagal). Gunakan Sentry untuk error alerting — Sentry bisa kirim notifikasi real-time ke Slack/email saat exception terjadi di production, dan memiliki grouping error yang lebih canggih. Idealnya: gunakan keduanya bersama.

Berapa lama data Telescope harus disimpan?

Development: 1–7 hari cukup. Production: 24–48 jam untuk traffic normal, 7 hari untuk aplikasi kritis yang perlu audit trail lebih panjang. Sesuaikan dengan kapasitas database dan kebutuhan debugging timmu.

Apakah Telescope bisa monitoring multiple server?

Telescope by default menyimpan data di database aplikasi masing-masing server. Untuk monitoring terpusat dari multiple server, konfigurasi semua instance untuk menulis ke satu database Telescope yang sama, atau gunakan solusi monitoring terpusat seperti Sentry/Datadog.


Kesimpulan

Dengan Laravel Telescope, kamu tidak lagi buta di production. Setiap request, query, job, dan exception tercatat dan mudah ditelusuri.

Kita sudah membangun monitoring yang solid:

  • Requests: tahu persis apa yang user lakukan dan mengapa error
  • Queries: deteksi query lambat sebelum user komplain
  • Jobs: pastikan background process berjalan dengan benar
  • Exceptions: debug production issue dalam menit, bukan jam

Rangkuman Seri Laravel Lanjutan (Order 11–20)

Selamat! Kamu telah menyelesaikan seri Laravel lanjutan yang mencakup seluruh gap yang jarang dibahas dalam bahasa Indonesia:

ArtikelTopik
11Queue & Jobs — Background Processing
12Midtrans Payment Gateway
13Livewire 3 — UI Dinamis Tanpa JS
14N+1 Query & Redis Cache
15File Upload — Local, S3, R2
16Testing dengan PHPUnit & Pest
17Real-time dengan Laravel Reverb
18Keamanan API Laravel
19CI/CD dengan GitHub Actions
20Debugging dengan Telescope

Kamu sekarang bukan hanya bisa membangun aplikasi Laravel — kamu bisa mengoptimalkan, mengamankan, men-test, dan memonitor-nya di production. Itulah yang membedakan developer junior dan senior.

Teruslah belajar, teruslah membangun, dan bagikan ilmumu kepada komunitas developer Indonesia! 🇮🇩🚀

Artikel Terkait