【python】封裝自己的日誌書寫器

一、簡介
    日常的python開發中,對於輸出內容的控制是非常重要的,便於進行調試、追溯問題,我專門學習了一下python的日誌模塊logging,接下來介紹一下我如何使用logging封裝我自己的日誌器的,以及如何定製化地設置日誌組成格式。
 
二、demo
# encoding: utf-8
import sys
import logging
from logging.handlers import RotatingFileHandler

class MYLogger(object):
    level_relations = {
        'debug':logging.DEBUG,
        'info':logging.INFO,
        'warning':logging.WARNING,
        'error':logging.ERROR,
        'crit':logging.CRITICAL
    }# 日誌級別關係映射

    def __init__(self, log_filename, log_path="/var/log/", log_level="info", fmt='%(asctime)s %(name)s[%(process)d] %(levelname)s: %(messag
e)s', max_bytes=10485760, backup_count=99, stdfile=True, stdout=False):
        self.logger = logging.getLogger(log_filename.split(".")[0])
        format_str = logging.Formatter(fmt)# 設置日誌格式
        self.logger.setLevel(self.level_relations.get(log_level.lower()))# 設置日誌級別
        if stdout:
            stdout_handler = logging.StreamHandler(sys.stdout)
            stdout_handler.setFormatter(format_str)
            self.logger.addHandler(stdout_handler)
        if stdfile:
            file_handler = RotatingFileHandler(log_path+log_filename, 'a', max_bytes, backup_count)
            file_handler.setFormatter(format_str)
            self.logger.addHandler(file_handler)

if __name__ == '__main__':
    testlog = MYLogger(log_filename="testlog.log", stdout=True)
    testlog.logger.debug('debug test')
    testlog.logger.info('info test')
    testlog.logger.warning('warning test')
    testlog.logger.error('error test')
    testlog.logger.critical('critical test')
測試結果:
 
參數說明:
log_filename:日誌文件文件名
log_path:日誌路徑,默認是/var/log/
log_level:日誌等級,默認是info
fmt:日誌格式,默認是 【時間 日誌名 進程id 日誌等級:日誌內容】
max_bytes:日誌文件最大大小,默認10M
backup_count:日誌文件達到最大大小之後,重命名爲 原日誌名+1,2,3,4,...,當日志數量大於backup_count時,最老的那個日誌將被刪除。默認日誌數量爲99個
std_file:日誌是否輸出到文件,默認是
stdout:日誌是否輸出到屏幕,默認否
 

fmt格式參考:

三、日誌分隔

對於日誌文件的分隔方法在我的demo中使用的是按文件大小自動分隔,根據需求還可以按時間去分隔,簡單介紹一下這結果分隔模式:

日誌句柄參考:

Handlers

負責將適當的日誌消息分派到處理程序的指定目標。Logger 對象可以通過addHandler()方法增加零個或多個handler對象。

舉個例子,一個應用可以將所有的日誌消息發送至日誌文件,所有的錯誤級別(error)及以上的日誌消息發送至標準輸出,所有的嚴重級別(critical)日誌消息發送至某個電子郵箱。在這個例子中需要三個獨立的處理器,每一個負責將特定級別的消息發送至特定的位置。

常用的有4種handler: 

1)    logging.StreamHandler -> 控制檯輸出 

使用這個Handler可以向類似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息。默認是sys.stderr

2)   logging.FileHandler  -> 文件輸出

和StreamHandler類似,用於向一個文件輸出日誌信息。不過FileHandler會幫你打開這個文件。它的構造函數是:

filename是文件名,必須指定一個文件名。

mode是文件的打開方式。默認是’a',即添加到文件末尾。

3)   logging.handlers.RotatingFileHandler -> 按照大小自動分割日誌文件,一旦達到指定的大小重新生成文件 

這個Handler類似於上面的FileHandler,但是它可以管理文件大小。當文件達到一定大小之後,它會自動將當前日誌文件改名,然後創建 一個新的同名日誌文件繼續輸出。比如日誌文件是chat.log。當chat.log達到指定的大小之後,RotatingFileHandler自動把 文件改名爲chat.log.1。不過,如果chat.log.1已經存在,會先把chat.log.1重命名爲chat.log.2。。。最後重新創建 chat.log,繼續輸出日誌信息。

maxBytes用於指定日誌文件的最大文件大小。如果maxBytes爲0,意味着日誌文件可以無限大,這時上面描述的重命名過程就不會發生。

backupCount用於指定保留的備份文件的個數。比如,如果指定爲2,當上面描述的重命名過程發生時,原有的chat.log.2並不會被更名,而是被刪除。

4)   logging.handlers.TimedRotatingFileHandler  -> 按照時間自動分割日誌文件 

這個Handler和RotatingFileHandler類似,不過,它沒有通過判斷文件大小來決定何時重新創建日誌文件,而是間隔一定時間就 自動創建新的日誌文件。重命名的過程與RotatingFileHandler類似,不過新的文件不是附加數字,而是當前時間。它的構造函數是:

TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])

其中filename參數和backupCount參數和RotatingFileHandler具有相同的意義。

interval是時間間隔。

when參數是一個字符串。表示時間間隔的單位,不區分大小寫。它有以下取值:S 秒  | M 分  |  H 小時  |   D 天  |   W 每星期(interval==0時代表星期一) | midnight 每天凌晨

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章