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 userLog::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
| Tool | Tipe | Hosting | Biaya | Cocok untuk |
|---|---|---|---|---|
| Laravel Telescope | Request inspector | Self-hosted | Gratis | Development + Production |
| Laravel Debugbar | Page overlay | Self-hosted | Gratis | Development only |
| Sentry | Error tracking | SaaS/self-hosted | Freemium | Error monitoring production |
| New Relic | APM | SaaS | Berbayar | Enterprise monitoring |
| Datadog | Full observability | SaaS | Berbayar | Large 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:
- Buka Telescope → Jobs tab
- Filter: Status =
failed - 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
- Exception:
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:
| Artikel | Topik |
|---|---|
| 11 | Queue & Jobs — Background Processing |
| 12 | Midtrans Payment Gateway |
| 13 | Livewire 3 — UI Dinamis Tanpa JS |
| 14 | N+1 Query & Redis Cache |
| 15 | File Upload — Local, S3, R2 |
| 16 | Testing dengan PHPUnit & Pest |
| 17 | Real-time dengan Laravel Reverb |
| 18 | Keamanan API Laravel |
| 19 | CI/CD dengan GitHub Actions |
| 20 | Debugging 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! 🇮🇩🚀