Mengapa Logging Penting?
Logging adalah cara utama untuk memahami apa yang terjadi di aplikasi kita, terutama di production dimana kita tidak bisa attach debugger.
Log Levels
Level Kapan Dipakai
─────────────────────────────────────────────
DEBUG Detail untuk debugging (jangan di production)
INFO Event normal: user login, order created
WARN Sesuatu tidak ideal tapi app masih berjalan
ERROR Ada yang gagal, perlu perhatian
FATAL App crash, tidak bisa lanjut
Structured Logging
Jangan log string biasa — gunakan structured logging (JSON) agar mudah di-search dan di-filter:
// ❌ Kurang baik
console.log("User 123 purchased item 456 for $99");
// ✅ Structured logging
logger.info("purchase_completed", {
userId: 123,
itemId: 456,
amount: 99,
currency: "USD",
timestamp: "2024-01-15T10:30:00Z"
});
Logging di Node.js (Pino)
import pino from "pino";
const logger = pino({
level: process.env.LOG_LEVEL || "info",
transport: {
target: "pino-pretty", // hanya untuk development
},
});
logger.info({ userId: 123 }, "User logged in");
logger.error({ err, orderId: 456 }, "Payment failed");
Logging di Laravel
use Illuminate\Support\Facades\Log;
Log::info("Order created", ["order_id" => 123, "user_id" => 456]);
Log::error("Payment failed", ["error" => $e->getMessage()]);
// config/logging.php — channel: daily, stack, stderr
// Log ke file: storage/logs/laravel.log
Log Aggregation: Dari Banyak Server ke Satu Tempat
Aplikasi di production biasanya jalan di banyak container/instance. SSH ke tiap server untuk tail -f tidak scalable. Solusinya: log aggregation — ship semua log ke satu sistem terpusat.
Struktur Pipeline
App (JSON log to stdout)
│
▼
Log Shipper (sidecar/agent)
- Fluentd / Fluent Bit
- Vector
- Filebeat (Elastic stack)
│
▼
Backend Aggregator
- Loki (Grafana) — murah, label-based
- Elasticsearch — full-text search
- CloudWatch Logs — managed AWS
- Datadog Logs — SaaS lengkap
│
▼
Query & Dashboard (Grafana, Kibana)
Kenapa Structured JSON Wajib?
// BURUK: plain text, sulit di-parse di backend
console.log(`User ${userId} purchased ${itemId} for ${amount}`);
// BAIK: JSON — backend bisa filter {userId: 123, amount: {gt: 100}}
logger.info({
event: "purchase_completed",
userId: 123,
itemId: 456,
amount: 99.50,
trace_id: "abc123xyz"
});
Dengan JSON, log aggregator bisa index setiap field → query cepat, visualisasi kaya, alerting presisi.
PII Redaction Sebelum Shipping
# Fluent Bit filter untuk redact email, kartu kredit, dll
[FILTER]
Name modify
Match *
Remove_wildcard password
Remove_wildcard token
[FILTER]
Name lua
Match *
script redact.lua
call redact_pii
Redact di source (sebelum keluar server), bukan di backend — agar PII tidak pernah sampai ke sistem third-party. GDPR/kepatuhan sering mewajibkan ini.
Log Level Strategy per Environment
- Development:
DEBUG— lihat semua detail - Staging:
INFO— mirip production tapi verbose - Production:
INFOuntuk business events,WARN/ERRORuntuk masalah - Cost control: log volume = biaya storage + ingestion. Matikan
DEBUGdi production atau sample-kan (1 dari 100 request)
Rasional Centralization
- Correlate: trace satu request yang lewat 5 service via
trace_id - Retain: server container bisa hilang, log tetap ada
- Audit: compliance butuh log disimpan 30-365 hari
- Alerting: bangun alert dari log pattern (misal "ERROR payment_*" spike)
Best Practices
- Selalu sertakan request ID / trace ID untuk tracing lintas service
- Jangan log data sensitif (password, token, PII) — redact di source
- Set log level via environment variable, jangan hardcode
- Rotate log files lokal agar disk tidak penuh (
logrotate) - Kirim log ke
stdout(12-factor); biarkan platform yang urusi shipping