Module logging mengelompokkan setiap pesan ke dalam salah satu dari lima tingkat kepentingan. Pengelompokan ini yang membuat ratusan baris log tetap terkelola: saat produksi kita hanya menampilkan yang penting, saat menyelidiki bug kita menurunkan saringan dan detail internal ikut mengalir. Pada Chapter ini kita akan memetakan kelima level tersebut beserta nilai numeriknya, membedah mekanisme penyaringan pesan, lalu memahami bagaimana sebuah logger tanpa level mewarisi level dari leluhurnya.
Lima Level dan Kapan Dipakai #
| Level | Nilai | Dipakai untuk |
|---|---|---|
DEBUG | 10 | detail internal saat investigasi: isi variabel, langkah algoritma |
INFO | 20 | kejadian rutin yang mengonfirmasi program berjalan normal |
WARNING | 30 | keadaan tidak normal tetapi program masih bisa melanjutkan |
ERROR | 40 | operasi gagal dan butuh perhatian; fitur tertentu terganggu |
CRITICAL | 50 | kegagalan parah; seluruh aplikasi berisiko berhenti |
Level bukan konstanta simbolis semata — setiap level adalah angka bulat yang benar-benar bisa diperiksa:
import logging
print(logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
print(logging.getLevelName(logging.DEBUG))
print(logging.getLevelName(30))Output yang Dihasilkan:
10 20 30 40 50
DEBUG
WARNINGFungsi logging.getLevelName() bekerja dua arah: menerjemahkan konstanta menjadi nama, dan angka menjadi nama. Jarak antar level sengaja dibuat 10 agar ada ruang untuk level kustom di tengahnya, misalnya logging.addLevelName(25, "NOTICE").
Panduan cepat memilih level: INFO menjawab “apa yang sedang terjadi”, WARNING menjawab “apa yang mulai janggal”, ERROR menjawab “apa yang gagal”, dan DEBUG menjawab “apa isi variabelnya saat ini”.
Penyaringan Berdasarkan Level #
Mekanisme penyaringannya sederhana: sebuah pesan diproses hanya bila nilai level pesan lebih besar atau sama dengan level saringan. Parameter level pada basicConfig() memasang saringan tersebut di root logger:
import logging
logging.basicConfig(level=logging.WARNING)
logging.debug("detail internal")
logging.info("pesan informasi")
logging.warning("perlu perhatian")
logging.error("terjadi error")
logging.critical("sistem kritis")Output yang Dihasilkan (dicetak module logging ke stderr):
WARNING:root:perlu perhatian
ERROR:root:terjadi error
CRITICAL:root:sistem kritisDua panggilan pertama (DEBUG bernilai 10 dan INFO bernilai 20) keduanya lebih kecil daripada saringan WARNING (30) sehingga dibuang sebelum sempat diformat. Inilah alasan pesan DEBUG yang banyak tidak memberatkan program produksi — string pesannya tidak dirangkai dan tidak dikirim ke handler mana pun.
Bagaimana bila basicConfig() tidak dipanggil sama sekali? Root logger tetap bekerja dengan saringan bawaan WARNING:
import logging
logging.warning("tampil tanpa konfigurasi apa pun")
logging.info("tidak akan tampil")Output yang Dihasilkan (dicetak module logging ke stderr):
WARNING:root:tampil tanpa konfigurasi apa punLevel Efektif dan Warisan #
Logger yang tidak pernah diatur levelnya menyandang nilai NOTSET (angka 0), dan artinya adalah “warisi level dari leluhur terdekat yang punya level”. Perhatikan demonstrasi berikut:
import logging
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
anak = logging.getLogger("toko.kasir")
print(anak.level)
print(anak.getEffectiveLevel())
logging.getLogger("toko").setLevel(logging.DEBUG)
print(anak.getEffectiveLevel())Output yang Dihasilkan:
0
20
10Mari kita telaah tiga angka tersebut:
- Baris 6 (
print(anak.level)): loggertoko.kasirtidak pernah diatur levelnya, jadi nilainyaNOTSETalias0. - Baris 7 (
anak.getEffectiveLevel()): level efektif dicari dengan menaiki hierarki — loggertokojugaNOTSET, sampai akhirnya root logger yang menetapkanINFO(20) lewatbasicConfig. - Baris 9 (
setLevel(logging.DEBUG)): begitu loggertokodiberi levelDEBUG(10), logger anak langsung mewarisi nilai itu karenatokokini menjadi leluhur terdekat yang berglevel.
Dua saringan berbeda sedang bekerja di sini dan penting tidak dicampuradukkan: level logger memutuskan pesan mana yang diizinkan masuk sistem logging, sedangkan level handler (yang akan kita bahas pada Chapter Logging Formatters dan Handlers) memutuskan pesan mana yang diteruskan ke tujuan output tertentu. Sebuah pesan harus lolos keduanya untuk sampai ke layar atau berkas.
Dengan pemahaman level, kita siap mengatur wajah dan tujuan dari setiap baris log — format isian maupun kemana pesan dikirim.