Cara Membuat Sistem Logging yang Rapi, Biar Gak Pusing Debugging
Pernahkah kamu mengalami aplikasi tiba-tiba error di production, dan satu-satunya petunjuk adalah file log yang berantakan? Isinya campur aduk antara info biasa, warning kecil, dan error fatal. Mencari sumber masalahnya seperti mencari jarum di tumpukan jerami. Rasanya frustasi banget, kan?
Makanya, punya sistem logging yang rapi itu bukan sekadar keren-kerenan, tapi kebutuhan yang bisa menyelamatkan waktu dan mentalmu. Bayangkan log seperti buku harian aplikasi. Kalau isinya acak-acakan, kamu sendiri yang bakal kesusahan saat butuh data.
Yuk, kita bahas cara membuat sistem logging yang rapi dan mudah dipahami.
1. Tentukan Level Log yang Jelas
Pertama-tama, jangan asal log. Kamu harus punya hierarki level log. Ini standar banget sebenarnya:
– ERROR: Ada yang benar-benar salah. Gagal koneksi database, file tak ditemukan, atau exception. Langsung butuh intervensi.
– WARN: Ada yang mencurigakan tapi belum kritis. Misalnya, batas kuota hampir habis, atau respon API lambat.
– INFO: Catatan peristiwa penting. User login, transaksi berhasil, atau start/stop server.
– DEBUG: Informasi detail untuk debugging. Biasanya diaktifkan saat development, jangan sampai nyala di production karena bisa banjir log.
Buatlah aturan di team: “Semua ERROR harus bisa di-cari dan di-track. DEBUG gak perlu muncul di production file utama.” Ini akan mengubah log dari sampah digital menjadi alat investigasi.
2. Gunakan Format yang Konsisten
Pernah lihat log seperti ini?
`2025-03-26 14:30:01 user login`
`ERROR something terrible happened`
Formatnya tidak seragam, sulit parsing. Idealnya, setiap baris log memiliki struktur baku. Contoh format yang umum:
“`
[2025-03-26T14:30:01.123Z] [INFO] [auth-service] User ID 123 logged in successfully
“`
– Timestamp dengan timezone (format ISO 8601 lebih baik).
– Level log dalam kurung siku.
– Nama service/modul (terutama jika microservices).
– Pesan yang jelas, termasuk ID, nama, atau konteks.
Dengan format rapi, kamu bisa langsung grep atau filter di terminal. Misalnya:
`grep “ERROR” app.log` atau `grep “auth-service” app.log`.
3. Jangan Log Password atau Data Sensitif
Naluri developer kadang ingin log semua parameter. Bahaya banget! Jangan pernah log password, token, nomor kartu kredit, atau data pribadi. Ini bisa menyebabkan kebocoran serius. Jika perlu debug data sensitif, gunakan masking atau log di level debug khusus yang tidak boleh masuk ke production.
Gunakan filter otomatis di library logging. Contoh di Python menggunakan `logging.Filter` untuk sensor kata-kata tertentu.
4. Gunakan Struktur Data, Bukan Sekadar String
Coba hindari log seperti:
`User ID 123 melakukan pembelian produk seharga 50000`
Lebih baik jika log berupa data terstruktur, misalnya JSON:
“`json
{
“timestamp”: “2025-03-26T14:30:01.123Z”,
“level”: “INFO”,
“service”: “payment”,
“event”: “purchase”,
“userId”: 123,
“productId”: 456,
“amount”: 50000
}
“`
Kenapa? Karena dengan format terstruktur, kamu bisa mengirimkannya ke sistem monitoring seperti Elasticsearch, Datadog, atau Grafana. Nanti tinggal pakai query visual, bukan lagi grepping manual.
5. Atur Rotasi dan Retensi Log
Aplikasi yang berjalan lama bisa menghasilkan file log puluhan GB. Tanpa rotasi, harddisk bisa penuh, dan aplikasi bisa crash. Solusinya:
– Rotasi berdasarkan ukuran: Misal setiap 10 MB, file log dipotong dan disimpan sebagai arsip.
– Retensi: Simpan log hanya untuk 30 hari terakhir. Hapus otomatis yang lebih lama.
Banyak library seperti `logrotate` di Linux atau `RotatingFileHandler` di Python yang siap pakai. Pastikan konfigurasinya pas.
6. Tambahkan Correlation ID untuk Request
Jika aplikasimu melayani banyak user secara paralel (web server misalnya), log dari berbagai request akan tercampur. Sulit melacak alur satu request dari awal hingga akhir.
Solusi: ketika sebuah request masuk, buat unique ID (correlation ID / trace ID). Teruskan ID ini ke semua komponen yang terlibat (service, database call, API eksternal). Sertakan ID di setiap baris log. Contoh:
“`
[INFO] [request-id: a1b2c3] Started processing order
[INFO] [request-id: a1b2c3] Validating inventory
[ERROR] [request-id: a1b2c3] Out of stock for product 456
“`
Dengan begitu, kamu bisa `grep “a1b2c3″` untuk melihat keseluruhan cerita request tersebut.
7. Hindari Blocking I/O di Logging
Tahukah kamu? Operasi logging bisa menjadi bottleneck jika dilakukan secara sinkron. Setiap kali log ditulis ke file atau ke jaringan, thread aplikasi harus menunggu. Untuk performa tinggi, gunakan async logging atau kirim log ke server secara background.
Library seperti `log4j` di Java atau `aiologger` di Python punya mode non-blocking. Atau kamu bisa menggunakan `fluentd`/`logstash` sebagai buffer dan pengirim.
Contoh Implementasi Simpel
Misalnya di Python dengan logging bawaan:
“`python
import logging
import json
logger = logging.getLogger(‘myapp’)
logger.setLevel(logging.DEBUG)
Handler file dengan rotasi
handler = logging.handlers.RotatingFileHandler(
‘app.log’, maxBytes=10485760, backupCount=5
)
formatter = logging.Formatter(
‘[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s’
)
handler.setFormatter(formatter)
logger.addHandler(handler)
Fungsi log dalam JSON
def log_json(level, event, **kwargs):
log_data = {
“event”: event,
**kwargs
}
logger.log(level, json.dumps(log_data))
Penggunaan
log_json(logging.INFO, “purchase”, userId=123, amount=50000)
“`
Penutup
Logging yang rapi bukanlah fitur tambahan yang bisa diabaikan. Dengan sedikit disiplin dan standarisasi, log bisa bertransformasi dari sampah menjadi aset berharga untuk troubleshooting, audit, dan monitoring.
Mulailah dari hal kecil: tentukan level log, format, dan jangan log data sensitif. Setelah itu, tingkatkan dengan struktur data dan correlation ID. Seiring berjalannya waktu, kamu akan berterima kasih pada dirimu sendiri saat aplikasi bermasalah dan log langsung menunjuk hidung masalahnya.
Selamat mencoba, dan semoga aplikasimu semakin tangguh!