logging modülü, Python için standart bir günlük kaydı aracıdır. Logger hiyerarşisini uygular ve günlükleme seviyelerini (severity levels) destekler: DEBUG, INFO, WARNING, ERROR, CRITICAL. Doğru kullanımı, çıktıların merkezi olarak yönetilmesine, günlüklerin dosyalara kaydedilmesine, e-posta ile gönderilmesine, seviyeye göre filtrelenmesine vb. olanak tanır.
Ana fikir, her modülde isimlerle (logging.getLogger(__name__)) logger'lar oluşturmaktır; her yerde sıfırdan küresel bir root logger oluşturmaktan kaçınılmalıdır. Yapılandırma (format, işleyiciler, seviye) uygulamanın başlangıcında merkezi olarak yapılır.
Yapılandırma örneği:
import logging logging.basicConfig(format='%(levelname)s:%(name)s:%(message)s', level=logging.INFO) logger = logging.getLogger(__name__) def foo(): logger.info('Bilgilendirme mesajı') logger.error('Hata!') foo()
Neden her modülde logging.basicConfig() çağrılmamalıdır? Bunu yaparsak ne olur?
Cevap: logging.basicConfig() sadece bir kez Python oturumu boyunca root logger'ı yapılandırır. Eğer root logger zaten başlatıldıysa, tekrar çağrılar görmezden gelinir. Sonuç olarak, farklı modüller kendi formatları/seviyeleriyle basicConfig() çağırmaya çalışırsa, sadece ilk çağrı etkili olur!
Hikaye
Büyük bir projede her geliştirici logging'i kendi isteğine göre basicConfig ve yerel işleyiciler aracılığıyla yapılandırdı. Bu nedenle bazı günlükler hiç yazılmadı, diğerleri 10 kat fazla tekrarlandı ve farklı modüllerin mesajları bir dosyaya sığmadı.
Hikaye
Web hizmeti çok seviyeli günlüklemeye geçiş yaparken, getLogger(__name__) ile logger adını belirtmeyi unuttular, her yerde root logger'a yazdılar. Sonuç olarak, belirli bir günlüğün nereden geldiği belirlenemedi.
Hikaye
Tüm mesajları, hata olmayanları bile kaydetmek için logger.error() fonksiyonu kullanıldı. Sonuç olarak, otomatik izleme sistemleri sürekli "alarm yükseltiyordu", çünkü yüksek hata seviyeleri görüyorlardı, oysa bu yalnızca debug/bilgilendirme mesajlarıydı.