Python logging 學習

基本用法:
import logging

#初始化logger 對象
logger = logging.getLogger("main")
#設置logger對象基礎級別,後面的handle的級別是基於此級別上的:及若是基礎級別爲 warning,則後面的handle最小級別就是handle了;若是基礎是info,後面handle的級別是warning,則是warning
logger.setLevel(logging.WARNING)

# 創建一個filehandler來把日誌記錄在文件裏,級別爲debug以上
filehandle = logging.FileHandler("test.log")
filehandle.setLevel(logging.DEBUG)

# 創建一個streamhandler來把日誌打在CMD窗口上,級別爲info以上
consolehandle = logging.StreamHandler()
consolehandle.setLevel(logging.INFO)

# 分別爲兩個handle設置日誌格式
formatter = logging.Formatter("%(asctime)s - %(name)s - %(module)s - %(funcName)s - %(levelname)s - %(message)s")
filehandle.setFormatter(formatter)
consolehandle.setFormatter(formatter)

#將兩個handler添加在logger對象中
logger.addHandler(consolehandle)
logger.addHandler(filehandle)

# 開始打日誌
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
注:

1. logger:提供日誌接口,供應用代碼使用。logger最長用的操做有兩類:配置和發送日誌消息。能夠經過logging.getLogger(name)獲取logger對象,若是不指定name則返回root對象,屢次使用相同的name調用getLogger方法返回同一個logger對象。socket

2. handler:將日誌記錄(log record)發送到合適的目的地(destination),好比文件,socket等。一個logger對象能夠經過addHandler方法添加0到多個handler,每一個handler又能夠定義不一樣日誌級別,以實現日誌分級過濾顯示。函數

3. filter:提供一種優雅的方式決定一個日誌記錄是否發送到handler。this

4. formatter:指定日誌記錄輸出的具體格式。formatter的構造方法須要兩個參數:消息的格式字符串和日期字符串,這兩個參數都是可選的。spa

 
5. format:定義了最終log信息的順序,結構和內容:
 
%(message)s', '%Y-%m-%d %H:%M:%S'
%(name)s Logger的名字
%(levelname)s 文本形式的日誌級別
%(message)s 用戶輸出的消息
%(asctime)s 字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒
%(levelno)s 數字形式的日誌級別
%(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有
%(filename)s 調用日誌輸出函數的模塊的文件名
%(module)s  調用日誌輸出函數的模塊名
%(funcName)s 調用日誌輸出函數的函數名
%(lineno)d 調用日誌輸出函數的語句所在的代碼行
%(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d 輸出日誌信息時的,自Logger建立以 來的毫秒數
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名。可能沒有
%(process)d 進程ID。可能沒有
===========================================================
當一個項目比較大的時候,不一樣的文件中都要用到Log,能夠考慮將其封裝爲一個類來使用:
class Logger(object):
    def __init__(self,loggerName,fileLog):
        basic_level = logging.DEBUG
        console_level = logging.INFO
        file_level = logging.INFO

        formatter = logging.Formatter("%(asctime)s - %(name)s - %(module)s - %(funcName)s - %(levelname)s - %(message)s")

        self.logger = logging.getLogger(loggerName)
        self.logger.setLevel(basic_level)

        file_handle = logging.FileHandler(fileLog)
        file_handle.setLevel(file_level)
        file_handle.setFormatter(formatter)

        console_handle = logging.StreamHandler()
        console_handle.setLevel(console_level)
        console_handle.setFormatter(formatter)

        self.logger.addHandler(file_handle)
        self.logger.addHandler(console_handle)

    def debug(self, message):
        self.logger.debug(message)

    def info(self, message):
        self.logger.info(message)

    def warn(self, message):
        self.logger.warn(message)

    def error(self, message):
        self.logger.error(message)

    def critical(self, message):
        self.logger.critical(message)

if __name__ == '__main__':
    import datetime
    dt = datetime.datetime.now()
    logfilename = "../logs/test_%s.log" % dt.strftime('%Y%m%d')
    logger = Logger("Python.utils.Log",logfilename)
    logger.debug("this is a test for debug")
    logger.info("this is a test for info")
    logger.warn("this is a test for warn")
    logger.error("this is a test for error")
在另一個 .py 文件裏,只要導入這個模塊,並實例化類 Logger 就能夠在整個project 範圍內 輸出日誌了。
 
另外注意一點的是:自定義Logger類能夠和 logging 混合運用,也能夠在整個project 範圍內用。但有一點要注意的是 當自定義Logger類和 logging 混用,在實例化logger時 ( = logging.getLogger(loggerName) ) loggerName 要有一個規範: 就是必需有層級關係,譬如 按照 project.package.module的 形式, 當在不一樣的 py文件 中 loggerName 中的 project 是同樣時,
均可以用logger 來輸出日誌。譬如 在 main.py 中 = logging.getLogger("pytest.test.main") 以及另一個文件中的 =logging.getLogger("pytest.utils.ApiTestRunner")
 
相關文章
相關標籤/搜索