From 1a1bed5e78dd6c420c8528f9fba186d99b7b131b Mon Sep 17 00:00:00 2001 From: Ahmet Sezgin Duran Date: Tue, 15 Jul 2014 09:30:48 +0300 Subject: [PATCH] SH-40 #time 5m Finish Python logging blog post --- .../2014-07-07-pythonda-etkili-log-tutma.md | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 source/posts/2014-07-07-pythonda-etkili-log-tutma.md diff --git a/source/posts/2014-07-07-pythonda-etkili-log-tutma.md b/source/posts/2014-07-07-pythonda-etkili-log-tutma.md new file mode 100644 index 00000000..72fa601b --- /dev/null +++ b/source/posts/2014-07-07-pythonda-etkili-log-tutma.md @@ -0,0 +1,148 @@ +--- +title: Python'da Etkili Log Tutma +date: 2014-07-07 +author: marjinal1st +tags: python, log, logging, tr +--- + +Bu yazıda Python kullanarak, bir uygulama için etkili bir şekilde log (kayıt) tutma yöntemlerine göz atacağız. + +Bunun için **logging** adlı bir Python modülünü kullanacağız. Bu modül Python'la beraber standart olarak geliyor. Özel bir Python sistemi kullanmıyorsanız, kurmanıza gerek yoktur, doğrudan Python konsolundan içe aktararak kullanabilirsiniz. + +```python +import logging +``` + +En basit haliyle, hiç bir örnekleme (initializing) bile yapmadan konsoldan şu şekilde log oluşturmaya başlayabilirsiniz. + +```python +>>> logging.warning("Uyarıyorum bak, demedi deme!") +WARNING:root:Uyarıyorum bak, demedi deme! + +>>> logging.error("Hatasız kul olmaz!") +ERROR:root:Hatasız kul olmaz! + +>>> logging.debug("Debug ediyorum, gözlerim kapalı.") + +``` + +Büyük ihtimalle üçüncü komutta çıktı görmeyeceksiniz zira **logging** modülünün varsayılan log seviyesi **warning**. Yani sadece mevcut seviye olan **warning** veya daha üst seviyelerin mesajları çıkacak. Tabi bunun için de bir sıralama var: + +DEBUG << INFO << WARNING << ERROR << CRITICAL + +Eğer log seviyesini değiştirmek isterseniz, şöyle bir kullanım gerecek: + +```python +>>> logging.getLogger().setLevel(logging.DEBUG) +``` + +Bu şekilde log seviyesini **debug** yapmış olduk. (Diğer seçenekleriniz: logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) Artık debug ve üstü log seviyelerinin mesajları gözükecek. + +```python +>>> logging.debug("Debug ediyorum, gözlerim kapalı.") +DEBUG:root:Debug ediyorum, gözlerim kapalı. +``` + +Logların mesajlarını daha düzgün bir biçimde (formatting) yazdırmamız da mümkün. Bunun için **basicConfig** adlı bir fonksiyon kullanacağız: + +```python +>>> logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%d/%m/%Y %H:%M:%S') +>>> logging.warning("Uyarıyorum bak, demedi deme!") +11/07/2014 09:40:53 Uyarıyorum bak demedi deme! +``` + +**datefmt** için istediğiniz tarzda tarih saat biçimi verebilirsiniz. **format** için ise ekstra seçenekler de mevcut. Örneğin **%(name)s** ekleyince, kullanıcı ismi; **%(levelname)s** ekleyince de log seviyesinin ismi çıkacak. + +```python +>>> logging.basicConfig(format='%(asctime)s %(name)s %(levelname)s %(message)s', datefmt='%d/%m/%Y %H:%M:%S') +>>> logging.warning("Uyarıyorum bak, demedi deme!") +11/07/2014 09:48:01 root WARNING Uyarıyorum bak, demedi deme! +``` + +**basicConfig** fonksiyonuna log seviyesi de ekleyebilirsiniz. + +```python +logging.basicConfig(format='%(asctime)s %(name)s %(levelname)s %(message)s', datefmt='%d/%m/%Y %H:%M:%S', level=logging.INFO) +``` + +Hatta daha da güzeli, bir seçenek daha ekleyip, logların dosyaya yazılmasını sağlayabilirsiniz: + +```python +logging.basicConfig(format='%(asctime)s %(name)s %(levelname)s %(message)s', datefmt='%d/%m/%Y %H:%M:%S', level=logging.INFO, filename="dosyaismi.log") +``` + +Bu şekilde loglarınız dosyaya yazılacak. Şimdi log tutma olayını biraz daha üst bir seviyeye çıkartıp, tek bir yerden birden fazla log tutmaya gözatalım. Bunların tamamını bir fonksiyona ekleyip, log kurulumu için sonradan da kullanabilmeniz mümkün. + +İlk iş olarak bir değişkene, temel log mekanizmasını atamamız gerekecek. + +```python +logger = logging.getLogger() +``` + +Ve her yerde çıkması için ortak bir log formatı: + +```python +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', '%d/%m/%Y %H:%M:%S') +``` + +Şimdi logları konsola çıkartacak bir log handler'ı oluşturalım. Ardından seviye ve formatı belirleyeceğiz. Son olarak da temel log tutan mekanizmaya bunu kaydettireceğiz. + +```python +console_logger = logging.StreamHandler() +console_logger.setLevel(logging.WARNING) +console_logger.setFormatter(formatter) +logger.addHandler(console_logger) +``` + +Şimdi de logları dosyaya yazacak ayrı bir handler oluşturalım. Yine seviye ve format belirtip, kaydetme işlemlerini yapacağız. + +```python +file_logger = logging.FileHandler("dosyaismi.log") +file_logger.setLevel(logging.DEBUG) +file_logger.setFormatter(formatter) +logger.addHandler(file_logger) +``` + +Dikkat ettiyseniz, iki farklı log tutucu için de farklı log seviyeleri verdik. Bundan sonra istediğimiz yerde log oluşturmaya başlayabiliriz: + +```python +>>> logging.warning("Uyarıyorum bak, demedi deme!") +11/07/2014 10:11:41 - root - WARNING - Uyarıyorum bak, demedi deme! +>>> logging.debug("Debug ediyorum, gözlerim kapalı.") +``` + +Konsoldaki log tutucu için temel seviye **warning** olduğundan, **debug** türü log mesajları çıkmadı. Ama dosyayı kontrol ettiğimiz de, iki mesajın da çıktığını göreceksiniz: + +``` +11/07/2014 10:11:41 - root - WARNING - Uyarıyorum bak, demedi deme! +11/07/2014 10:11:43 - root - DEBUG - Debug ediyorum, gözlerim kapalı. +``` + +Gördüğünüz gibi, tek bir log mesajıyla, birden fazla yerde log tutabiliyoruz. İhtiyaca göre birden fazla, farklı seviyelerde dosya log tutucu ekleyebilirsiniz. Ayrıca log türünü mesajlara ekleyerek, ileride gerekebilecek bir ayrıştırma (parsing) işlemini de kolaylaştırdığımız söylenebilir. + +Şimdi tüm bu log ayarları için kullandığımız kodları tek bir fonksiyona ekleyelim: + +```python +def setup_log_system(): + logger = logging.getLogger() + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', + '%d/%m/%Y %H:%M:%S') + + # Konsol log tutucu + console_logger = logging.StreamHandler() + console_logger.setLevel(logging.WARNING) + console_logger.setFormatter(formatter) + logger.addHandler(console_logger) + + # Dosya log tutucu + file_logger = logging.FileHandler("dosyaismi.log") + file_logger.setLevel(logging.DEBUG) + file_logger.setFormatter(formatter) + logger.addHandler(file_logger) +``` + +Bu şekilde kullandığınız uygulama içinde, **setup_log_system** fonksiyonunu çağırarak, hızlıca log sisteminizi kurabilirsiniz. + +**Logging** modülü ile ilgili daha fazla örnek için: + +https://docs.python.org/2/howto/logging.html \ No newline at end of file