Membekali aplikasi dengan observabilitas: menulis log dengan kategori yang tepat lewat Yii::info, error, warning, dan trace; mengirim log ke target file, database, atau email; membedah request dengan Yii Debug Toolbar; serta profiling dengan beginProfile dan endProfile untuk menemukan bottleneck performa.

Aplikasi yang sudah berjalan bukan berarti masalahnya selesai — masalah justru muncul saat production: halaman lambat, error sporadis, data tidak konsisten. Dan tanpa observabilitas, kalian menebak-nebak di dalam kegelapan. Logging, debugging, dan profiling adalah lampu yang menerangi kegelapan itu.
Yii menyediakan ketiganya sebagai bagian inti framework: logger terpusat dengan target fleksibel, Debug Toolbar yang membedah setiap request, dan profiler untuk mengukur waktu eksekusi per bagian kode. Di episode ini kita mengaktifkan semuanya dan mempraktikkannya pada aplikasi nyata.
Semua log Yii mengalir lewat Yii::log dengan empat level:
use Yii;
Yii::trace('Mulai memproses order #123', 'app\order');
Yii::info('Order #123 disimpan', 'app\order');
Yii::warning('Disk usage di atas 80%', 'app\system');
Yii::error('Gagal menghubungi API pembayaran', 'app\payment');Perhatikan kategori (argumen kedua). Ini bukan formalitas: kategori adalah cara memfilter log — di target, di Debug Toolbar, dan saat kalian menelusuri jejak satu alur bisnis. Konvensi yang lazim: gunakan __METHOD__ atau nama class sebagai kategori agar setiap log bisa dilacak ke sumbernya.
public function actionPay(int $orderId): string
{
Yii::info("Mulai pembayaran order $orderId", __METHOD__);
// ... logika pembayaran ...
Yii::info("Pembayaran order $orderId selesai", __METHOD__);
}Logger menampung pesan di memori; log target yang menulisnya ke tujuan akhir. Konfigurasi di config/web.php:
'components' => [
'log' => [
'traceLevel' => 3,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
'logFile' => '@runtime/logs/app.log',
],
[
'class' => 'yii\log\FileTarget',
'categories' => ['app\payment'],
'logFile' => '@runtime/logs/payment.log',
],
[
'class' => 'yii\log\DbTarget',
'levels' => ['error'],
'logTable' => '{{%log}}',
],
[
'class' => 'yii\log\EmailTarget',
'levels' => ['error'],
'message' => [
'from' => ['monitoring@example.com'],
'to' => ['admin@example.com'],
'subject' => 'Error aplikasi Yii',
],
],
],
],
],| Target | Gunakan Untuk |
|---|---|
FileTarget | Log standar, pisahkan per kategori di file berbeda |
DbTarget | Log yang ingin dicari/difilter lewat SQL |
EmailTarget | Peringatan kritis yang harus langsung diketahui admin |
SyslogTarget | Integrasi dengan syslog server |
TelegramTarget / custom | Notifikasi ke chat ops (via ekstensi) |
traceLevel => 3 membuat setiap log menyertakan 3 level stack trace — informasi krusial saat menelusuri error. Untuk database target, buat tabel log-nya:
php yii migrate/up --migrationPath=@yii/log/migrationsTip
Level trace biasanya tidak ditulis ke file production karena terlalu banyak. Pola yang umum: di production simpan error + warning ke file dan error ke email; aktifkan info/trace hanya di development. Atur lewat levels per target — Yii memberi kontrol penuh tanpa mengubah kode.
Debug Toolbar adalah panoptikon request: ia menampilkan semua yang terjadi dalam satu request — query SQL, durasi, log, variabel, dan banyak lagi. Pasang sebagai module dev:
composer require yiisoft/yii2-debug --dev'modules' => [
'debug' => [
'class' => 'yii\debug\Module',
'allowedIPs' => ['127.0.0.1', '::1'],
],
],Toolbar muncul sebagai bar di sudut halaman. Klik untuk membuka Debug Panel dengan informasi per request:
Ini mengubah debugging dari print_r dan trial-error menjadi pemeriksaan sistematis — setiap request punya "black box recorder" sendiri.
Saat Toolbar menunjukkan halaman lambat, langkah berikutnya: menemukan bagian mana yang lambat. Profiling menjawabnya dengan mengukur waktu eksekusi potongan kode:
use Yii;
Yii::beginProfile('build_dashboard');
$stats = Order::find()
->select(['status', 'COUNT(*) AS total'])
->groupBy('status')
->asArray()
->all();
Yii::endProfile('build_dashboard');Pasangan beginProfile/endProfile mengukur durasi blok di antara keduanya. Hasilnya muncul di Toolbar (panel Timeline), sehingga kalian bisa membandingkan durasi tiap blok dan menemukan yang dominan.
Query database sudah otomatis di-profil oleh Yii. Di panel Database, perhatikan kolom durasi:
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=blog',
'enableQueryLog' => true, // catat semua query
],
],Di production, jangan biarkan enableQueryLog selalu nyala (boros memori) — nyalakan hanya saat investigasi, atau log query di atas ambang durasi tertentu lewat profiling database bawaan.
Praktik terbaik: beri setiap alur bisnis penting jejak log yang konsisten. Contoh alur pembayaran:
public function actionPay(int $orderId): string
{
Yii::info("Mulai pembayaran order $orderId", 'app\payment');
Yii::beginProfile('payment_' . $orderId);
$order = Order::findOne($orderId);
if ($order === null) {
Yii::warning("Order $orderId tidak ditemukan", 'app\payment');
throw new NotFoundHttpException();
}
try {
$this->charge($order);
Yii::info("Order $orderId berhasil dibayar", 'app\payment');
} catch (\Throwable $e) {
Yii::error("Order $orderId gagal: {$e->getMessage()}", 'app\payment');
throw $e;
}
Yii::endProfile('payment_' . $orderId);
return $this->render('success', ['order' => $order]);
}Dengan pola ini, setiap masalah pembayaran bisa ditelusuri: kategori app\payment memfilter semua pesan, profil mengukur durasi, dan level error/warning memicu notifikasi.
Inti yang harus dibawa pulang:
__METHOD__ atau nama alur) — kunci untuk menelusuri masalah.beginProfile/endProfile mengukur waktu blok kode untuk menemukan bottleneck.traceLevel => 3 melampirkan stack trace ke setiap log.Di episode 14 selanjutnya, kita membongkar mekanisme internal yang sudah dipakai sejak episode 2: events, behaviors & extensions — mendefinisikan event dan handler, mengaitkan behavior ke komponen, lalu mempublikasikan extension Yii sendiri sebagai package Composer yang bisa dipakai lintas project. Sampai jumpa di episode 14!