Belajar Symfony - Logging, Profiler & Debugging
Episode 15 of 27

Belajar Symfony - Logging, Profiler & Debugging

Menjadi ahli debugging: Monolog dengan channel & structured logging, Symfony Profiler dan Web Debug Toolbar untuk inspeksi request, var-dumper untuk inspeksi variabel, serta teknik men-debug error dan performa di environment production.

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

Pendahuluan

Aplikasi pasti error — pertanyaannya seberapa cepat kalian menemukannya. Episode 15 membekali kalian dengan tiga senjata debugging: logging (jejak permanen), profiler (mikroskop per request), dan var-dumper (inspeksi nilai). Kemampuan men-debug dengan efisien adalah skill yang paling sering diuji di dunia kerja nyata.

Mengapa topik ini berada di tengah series, sebelum deployment? Karena mulai episode 16 (multi-environment) sampai 26 (production readiness), semua praktik kita bergantung pada kemampuan membaca apa yang terjadi di aplikasi. Kalian tidak bisa mengelola environment atau scaling tanpa bisa melihat log dan profile.

Monolog: Logging Berchannel

Symfony memakai Monolog untuk logging. Konsep penting: channel — alur log yang terpisah per domain. Konfigurasi di config/packages/monolog.yaml:

config/packages/monolog.yaml
monolog:
    channels: ['payment']
 
    handlers:
        main:
            type: stream
            path: '%kernel.logs_dir%/%kernel.environment%.log'
            level: debug
 
        payment:
            type: rotating_file
            path: '%kernel.logs_dir%/payment.log'
            level: info
            max_files: 14

Menulis log di kode:

Logging dengan channel
use Psr\Log\LoggerInterface;
 
public function __construct(
    private readonly LoggerInterface $paymentLogger,
) {
}
 
public function charge(float $amount): void
{
    $this->paymentLogger->info('Pembayaran diproses', [
        'amount' => $amount,
        'currency' => 'IDR',
        'request_id' => $this->requestId,
    ]);
}

Perhatikan dua hal: context (data terstruktur, bukan string gabung) dan channel ($paymentLogger otomatis ter-inject karena tipe variabel $paymentLogger cocok nama channel payment). Log yang bagus adalah log yang bisa difilter dan dicari.

Structured Logging

Log string gabungan ("Charge 150000 IDR") sulit dicari dan diparsing. Structured logging memisahkan pesan dan konteks:

Perbandingan output
# Log lama (string)
[2026-08-16 10:00:00] payment.INFO: Pembayaran 150000 IDR untuk user 42
 
# Structured (JSON)
{"channel":"payment","level":"INFO","message":"Pembayaran diproses","context":{"amount":150000,"currency":"IDR","user_id":42}}

Untuk aggregator log modern, set Monolog keluar sebagai JSON:

Formatter JSON
handlers:
    main:
        type: stream
        path: 'php://stderr'
        level: info
        formatter: monolog.formatter.json

Output JSON siap dikirim ke sistem observability (Elasticsearch/Loki) — di-query dengan bahasa filter, bukan grep manual. Ini fondasi yang dipakai di episode 24 saat kita menambang log untuk scaling.

Symfony Profiler dan Web Debug Toolbar

Di environment dev, Web Debug Toolbar muncul di bawah halaman — tetapi kekuatan sebenarnya adalah Profiler (klik ikonnya). Profiler menyimpan seluruh detail request:

PanelYang diperiksa
RequestHeader, parameter, session
PerformanceTimeline render, waktu per event
DoctrineSemua query + durasinya
TwigTemplate yang dirender & waktu
RoutingRoute yang cocok
LogsSemua log request tersebut

Pola debugging yang paling efektif: buka halaman, klik profiler, lihat panel Doctrine — query N+1 (banyak query identik) terlihat jelas. Ini jalan pintas menemukan masalah yang butuh waktu berjam-jam tanpa profiler.

var-dumper: Inspeksi Variabel

dump() dan dd() adalah cara cepat memeriksa nilai:

dump vs dd
public function show(Article $article): Response
{
    dump($article->getAuthor());   // tampilkan nilai, lanjutkan eksekusi
    dd($article->getTags());       // tampilkan dan hentikan (die)
 
    // ...
}

Di dev, output muncul di Web Debug Toolbar; di CLI, memakai format yang rapi. Kapan memakai yang mana:

PerintahPerilakuCocok untuk
dump()Cetak & lanjutMenebak alur data
dd()Cetak & hentikanInvestigasi titik mati

Warning

Jangan pernah membiarkan dump()/dd() tertinggal di kode production. Konvensi: sebelum commit, pastikan tidak ada dd( tersisa — beberapa tim memakai linter atau CI check. dump() di APP_ENV=prod tidak menampilkan apa pun, tapi tetap membuang waktu eksekusi.

Debugging di Production

Di produksi, profiler tidak aktif — jadi strateginya berubah:

  1. APP_ENV=prod + log level info — log jadi satu-satunya sumber utama.
  2. Baca var/log/prod.log — caranya: filter per request dengan request id yang sudah kita log di context.
  3. bin/console di server — jalankan command yang sama dengan env prod untuk melihat error langsung.
  4. Error tracking — integrasikan dengan Sentry/Bugsnag agar exception terkirim otomatis dengan context (stack trace + user + request).

Untuk error yang hanya muncul sekali-sekali, context yang lengkap (request id, user id, payload) adalah pembeda antara "tahu bahwa error" dan "bisa reproduce error".

Perintah yang Sering Dipakai

Debug tooling
php bin/console lint:twig templates       # syntax template
php bin/console lint:yaml config          # syntax yaml
php bin/console lint:container            # validasi container
php bin/console debug:container           # inspect service
php bin/console debug:router              # inspect route
php bin/console doctrine:query:sql "SELECT 1"  # cek query di DB

Lint commands menangkap kesalahan sebelum masuk runtime — biasakan menjalankannya sebelum commit, terutama saat mengubah file YAML atau Twig.

Common Pitfalls

  • Log di level yang salaherror untuk kegagalan, warning untuk kondisi tidak ideal, info untuk jejak normal. Jangan menumpuk semua di error.
  • Channel tanpa konfigurasi — channel otomatis dibuat saat DI meminta LoggerInterface $paymentLogger, tapi pastikan dideklarasikan di monolog.channels jika butuh handler khusus.
  • Profiler menyesatkan di prod — jangan bandingkan performa dev vs prod; dev memuat profiler yang memperlambat.

Penutup

Pada episode 15 ini, kalian telah menjadi detektif aplikasi.

Inti yang harus dibawa pulang:

  • Monolog dengan channel memisahkan alur log; context menyimpan data terstruktur.
  • Structured logging (JSON) siap untuk observability & aggregator.
  • Profiler & Web Debug Toolbar adalah mikroskop per request di dev.
  • dump() vs dd(); jangan pernah biarkan tertinggal di production.
  • Di prod: log, request id, error tracking — bukan profiler.

Di episode 16 selanjutnya kita mengelola perbedaan lingkungan: Config Management & Environments — .env & Dotenv, env vars, konfigurasi per-environment, dan Symfony Secrets Vault untuk rahasia production. Sampai jumpa di episode 16!

Belajar Symfony - Logging, Profiler & Debugging | Belajar Symfony