Python Yazılımı İçin Log Oluşturma

 Python kodunuzun loglarını takip etmek istiyorsanız program çalışırken oluşan hataları veya mesajları bir log dosyasına yardırabilirsiniz. Bu log dosyası yazılımınızın geçmişe dönük çalışmasıyla ilgili size bilgi verecektir. Python'da en popüler log oluşturma kütüphanesi logger kütüphanesidir. Logger yazılımını bilgisayarımıza yükleyerek başlayalım.

pip install logger

Modülü yükledikten sonra yazılıma import edelim.

import logging

İlk olarak oluşturduğumuz log için bir isim tanımı yapalım.

logger = logging.getLogger("Log_adı")

Mesaj seviyesi belirleyelim, bu seviye ve üzerindeki loglar alınır. Örneğin: Error seçilirse sadece error ve critical logları alınır.

Seviyeler:

  1. debug
  2. info
  3. warning
  4. error
  5. critical

logger.setLevel(logging.DEBUG)

Logların yazılacağı dosyanın belirlenmesi;

logging.basicConfig(filename='dosya_adi.log', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', filemode="w", level=logging.DEBUG)

Burada filemode="w" ise her çalıştırmada eski dosya silinerek yeni dosya oluşturulur. filemode="a" ise bilgiler eski dosyaya eklenerek kaydedilir. Ekrana yazdırma parametreleri;

ch = logging.StreamHandler()

ch.setLevel(logging.DEBUG)

Log formatı;

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s:%(lineno)d')

asctime = Çalışma zamanı

name = Log adı

levelname = Log level

message = Yazdığınız veya sistemden okuduğu hata mesajı.

pathname = Dosyanın bulunduğu dizin.

lineno = Kodun çalıştırdığı satır.

Ekrana yazılacak veriye format uygulanması

ch.setFormatter(formatter)

logger.addHandler(ch)

Yazılır.

#Uygulama mesaj formatları;

Print komutunu kullanır gibi aşağıdaki formatta yazdığınız tüm mesajlar log dosyasında oluşacaktır.

logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

Kodun tamamı

import logging
logger = logging.getLogger('Log_adı')
logger.setLevel(logging.DEBUG)
logging.basicConfig(filename='dosya_adi.log', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s:%(lineno)d', filemode="w", level=logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s:%(lineno)d')
ch.setFormatter(formatter)
logger.addHandler(ch)

Tavsiye edilen kullanım:

import logging
import os
logger_name=os.path.basename(__file__)
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
logging.basicConfig(filename=logger_name+'.log', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s:%(lineno)d', filemode="w", level=logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s:%(lineno)d')
ch.setFormatter(formatter)
logger.addHandler(ch)

Python Log'larını otomatik olarak mail atmak için

Koda aşağıdaki satırları da ekleyerek mail atma işlemini de gerçekleştirebilirsiniz.

import logging.handlers

Mail_sender = "email_user@domain.com"
Sender_pwd = "passWord" #Password kullanımı opsiyoneldir...
smtpHandler = logging.handlers.SMTPHandler(
    mailhost=("localhost", 25),
    fromaddr="noreply@domain.com",
    toaddrs="user@email.com",
    subject="Dikkat!",
    credentials=(Mail_sender, Sender_pwd))
smtpHandler.setLevel(logging.DEBUG)
smtpHandler.setFormatter(formatter)
logger.addHandler(smtpHandler)

Not: Mail atarken alarm seviyesini warning olarak ayarlayın, yoksa çok fazla mail ile karşı karşıya kalabilirsiniz.


Python Yazılımı İçin Konfigürasyon Dosyası

 Python yazılımı için bir konfigürasyon dosyası nasıl oluşturulur?

Yazılım kodunda sürekli değişiklik yapmamak için veya kod üzerinde başkaları ile çalışırken kullanıcı adı ve şifre bilgilerinin açık bir şekilde görünmemesi için bir konfigürasyon dosyası hazırlayıp değişkenleri burada tanımlamak çok kullanışlı olacaktır. Bu değişkenler username, password, host, port, ve IP gibi sürekli değişecek bilgiler olabilir. İlk olarak config.py isimli bir dosya oluşturalım ve içeriğini gerekli bilgiler ile aşağıdaki örnekteki gibi dolduralım.

#### Konfigürasyon Dosyası ###
host = 'localhost'
port = '8080'
username = 'user'
password = 'password'

Dosyaya bilgileri yazdıktan sonra config.py ismi ile yazılımımızın dosyalarının olduğu klasöre kaydedelim. Konfigürasyonun import edilebilmesi için main.py dosyası ile config.py dosyası aynı klasörde olmalıdır. Yazdığımız kod içinden bu değişkenleri çağırmak için aşağıdaki örnek koda uygun bir şekilde değişkenleri çağıralım. Bu dosya adı main.py olsun.

import config
host = config.host
port = config.port
username = config.username
password = config.password

Main.py isimli kodu çalıştırdığınızda config.py isimli dosyadaki değişkenler yüklenecektir. Kod çalıştığında konsol'da aşağıdaki gibi bir mesaj görünür.

Reloaded modules: config 

Böylece konfigürasyonları yazdığımız dosya config.py ana dosyayı main.py çalıştırdığımızda yüklenecektir ve içerdiği bilgileri kullanabileceğiz. Özellikle password içeren kodlarda başkaları ile beraber çalışıyorsanız veya eğitim veriyorsanız bilgileri bu şekilde kod içinde görünmez hale getirebilirsiniz. Yazdığınız kodu başkaları da çalıştırabiliyorsa veya dosyalara erişebiliyorsa bu yöntem size güvenlik sağlamaz.

Konfigürasyon bilgilerini güvenli bir şekilde saklamak.

Güvenli bir şekilde konfigürasyon bilgilerini saklamak istiyorsanız cryptography modülünden faydalanabilirsiniz. İlk olarak bir konfigürasyon dosyası hazırlayıp bu dosyayı şifrelemek ve şifreli dosyayı kullanmak en güvenli yollardan biri olacaktır. İlk olarak yukarıda anlatıldığı gibi bir konfigürasyon dosyası oluşturun ve adını config.py olarak kaydedin. Pythn cryptography modülünü kurun;

pip install cryptography

Hazırladığınız config.py dosyasını şifrelemek için bir key oluşturun ve bu key bilgisini sonra kullanmak üzere bir dosyaya yazdırın. Daha sonra konfigürasyon dosyanızın şifreli bir halini oluşturun. Aşağıdaki kod key dosyası ve şifrelenmiş bir konfigürasyon dosyası oluşturmamızı sağlar.

from cryptography.fernet import Fernet

key = Fernet.generate_key()
print(key)

#Oluşturduğunuz key bilgisini dosyaya kaydeder.
with open('mykey.key', 'wb') as mykey:
    mykey.write(key)
    
f = Fernet(key)

with open('config.py', 'rb') as original_file:
    original = original_file.read()
encrypted = f.encrypt(original)

with open ('encrypted.py', 'wb') as encrypted_file:
    encrypted_file.write(encrypted)

Bu kod iki adet çıktı elde eder. mykey.key oluşturulan key bilgisinin içinde bulunduğu dosya, encrypted.py config.py dosyasının şifrelenmiş versiyonudur. 

İşlemden sonra mykey.key dosyasını mutlaka saklamalısınız, bu dosya şifreli encrypted.py dosyasını düzgün bir şekilde açmanızı sağlayacaktır. Artık bilgilerin açık bir şekilde yazılı olduğu config.py dosyasını başka bir güvenli yere taşıyabilir veya silebilirsiniz. Oluşturduğunuz şifreli konfigürasyon dosyasındaki bilgileri kullanmak için aşağıdaki kod size yardımcı olacaktır. 

from cryptography.fernet import Fernet

with open('mykey.key', 'rb') as filekey:
    key = filekey.read()
print(key)
f = Fernet(key)

with open('encrypted.py', 'rb') as encrypted_file:
    encrypted = encrypted_file.read()

decrypted = f.decrypt(encrypted)
data=decrypted.decode('UTF-8')

for line in data.splitlines():
    print(line)
    if "host" in line:
        host=re.split("'", line)[1]
    elif "port" in line:
        port=re.split("'", line)[1]
    elif "username" in line:
        username=re.split("'", line)[1]
    elif "password" in line:
        password=re.split("'", line)[1]

print(host, port, username, password )

config.py dosyasını tekrar oluşturmak isterseniz yukarıdaki koda aşağıdaki kod parçacığını eklemeniz yeterlidir.

with open('config.py', 'wb') as dec_file:
    dec_file.write(decrypted)




Google