Python中使用logging模組列印log日誌詳解

來源:互聯網
上載者:User
學一門新技術或者新語言,我們都要首先學會如何去適應這們新技術,其中在適應過程中,我們必須得學習如何偵錯工具並打出相應的log資訊來,正所謂“只要log打的好,沒有bug解不了”,在我們熟知的一些資訊技術中,log4xxx系列以及開發Android app時的android.util.Log包等等都是為了開發人員更好的得到log資訊服務的。在Python這門語言中,我們同樣可以根據自己的程式需要打出log。

log資訊不同於使用打樁法列印一定的標記資訊,log可以根據程式需要而分出不同的log層級,比如info、debug、warn等等層級的資訊,只要即時控制log層級開關就可以為開發人員提供更好的log資訊,與log4xx類似,logger,handler和日誌訊息的調用可以有具體的記錄層級(Level),只有在日誌訊息的層級大於logger和handler的設定的層級,才會顯示。下面我就來談談我在Python中使用的logging模組一些方法。

logging模組介紹

Python的logging模組提供了通用的日誌系統,熟練使用logging模組可以方便開發人員開發第三方模組或者是自己的Python應用。同樣這個模組提供不同的記錄層級,並可以採用不同的方式記錄日誌,比如檔案,HTTP、GET/POST,SMTP,Socket等,甚至可以自己實現具體的日誌記錄方式。下文我將主要介紹如何使用檔案方式記錄log。

logging模組包括logger,handler,filter,formatter這四個基本概念。

logger:提供日誌介面,供應用代碼使用。logger最長用的操作有兩類:配置和發送日誌訊息。可以通過logging.getLogger(name)擷取logger對象,如果不指定name則返回root對象,多次使用相同的name調用getLogger方法返回同一個logger對象。
handler:將日誌記錄(log record)發送到合適的目的地(destination),比如檔案,socket等。一個logger對象可以通過addHandler方法添加0到多個handler,每個handler又可以定義不同記錄層級,以實現日誌分級過濾顯示。
filter:提供一種優雅的方式決定一個日誌記錄是否發送到handler。
formatter:指定日誌記錄輸出的具體格式。formatter的構造方法需要兩個參數:訊息的格式字串和日期文字,這兩個參數都是可選的。

基本使用方法

一些小型的程式我們不需要構造太複雜的log系統,可以直接使用logging模組的basicConfig函數即可,代碼如下:
複製代碼 代碼如下:


'''
Created on 2012-8-12

@author: walfred
@module: loggingmodule.BasicLogger
'''
import logging

log_file = "./basic_logger.log"

logging.basicConfig(filename = log_file, level = logging.DEBUG)

logging.debug("this is a debugmsg!")
logging.info("this is a infomsg!")
logging.warn("this is a warn msg!")
logging.error("this is a error msg!")
logging.critical("this is a critical msg!")

運行程式時我們就會在該檔案的目前的目錄下發現basic_logger.log檔案,查看basic_logger.log內容如下:

複製代碼 代碼如下:


INFO:root:this is a info msg!
DEBUG:root:this is a debug msg!
WARNING:root:this is a warn msg!
ERROR:root:this is a error msg!
CRITICAL:root:this is a critical msg!

需要說明的是我將level設定為DEBUG層級,所以log日誌中只顯示了包含該層級及該層級以上的log資訊。資訊層級依次是:notset、debug、info、warn、error、critical。如果在多個模組中使用這個配置的話,只需在主模組中配置即可,其他模組會有相同的使用效果。

較進階版本

上述的基礎使用比較簡單,沒有顯示出logging模組的厲害,適合小程式用,現在我介紹一個較進階版本的代碼,我們需要依次設定logger、handler、formatter等配置。

複製代碼 代碼如下:


'''
Created on 2012-8-12

@author: walfred
@module: loggingmodule.NomalLogger
'''
import logging

log_file = "./nomal_logger.log"
log_level = logging.DEBUG

logger = logging.getLogger("loggingmodule.NomalLogger")
handler = logging.FileHandler(log_file)
formatter = logging.Formatter("[%(levelname)s][%(funcName)s][%(asctime)s]%(message)s")

handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(log_level)

#test
logger.debug("this is a debug msg!")
logger.info("this is a info msg!")
logger.warn("this is a warn msg!")
logger.error("this is a error msg!")
logger.critical("this is a critical msg!")

這時我們查看目前的目錄的nomal_logger.log記錄檔,如下:

複製代碼 代碼如下:


[DEBUG][][2012-08-12 17:43:59,295]this is a debug msg!
[INFO][][2012-08-12 17:43:59,295]this is a info msg!
[WARNING][][2012-08-12 17:43:59,295]this is a warn msg!
[ERROR][][2012-08-12 17:43:59,295]this is a error msg!
[CRITICAL][][2012-08-12 17:43:59,295]this is a critical msg!

這個對照前面介紹的logging模組,不難理解,下面的最終版本將會更加完整。

完善版本

這個最終版本我用singleton設計模式來寫一個Logger類,代碼如下:
複製代碼 代碼如下:


'''
Created on 2012-8-12

@author: walfred
@module: loggingmodule.FinalLogger
'''

import logging.handlers

class FinalLogger:

logger = None

levels = {"n" : logging.NOTSET,
"d" : logging.DEBUG,
"i" : logging.INFO,
"w" : logging.WARN,
"e" : logging.ERROR,
"c" : logging.CRITICAL}

log_level = "d"
log_file = "final_logger.log"
log_max_byte = 10 * 1024 * 1024;
log_backup_count = 5

@staticmethod
def getLogger():
if FinalLogger.logger is not None:
return FinalLogger.logger

FinalLogger.logger = logging.Logger("oggingmodule.FinalLogger")
log_handler = logging.handlers.RotatingFileHandler(filename = FinalLogger.log_file,\
maxBytes = FinalLogger.log_max_byte,\
backupCount = FinalLogger.log_backup_count)
log_fmt = logging.Formatter("[%(levelname)s][%(funcName)s][%(asctime)s]%(message)s")
log_handler.setFormatter(log_fmt)
FinalLogger.logger.addHandler(log_handler)
FinalLogger.logger.setLevel(FinalLogger.levels.get(FinalLogger.log_level))
return FinalLogger.logger

if __name__ == "__main__":
logger = FinalLogger.getLogger()
logger.debug("this is a debug msg!")
logger.info("this is a info msg!")
logger.warn("this is a warn msg!")
logger.error("this is a error msg!")
logger.critical("this is a critical msg!")

目前的目錄下的 final_logger.log內容如下:
複製代碼 代碼如下:


[DEBUG][][2012-08-12 18:12:23,029]this is a debug msg!
[INFO][][2012-08-12 18:12:23,029]this is a info msg!
[WARNING][][2012-08-12 18:12:23,029]this is a warn msg!
[ERROR][][2012-08-12 18:12:23,029]this is a error msg!
[CRITICAL][][2012-08-12 18:12:23,029]this is a critical msg!


這個final版本,也是我一直用的,讀者朋友也可以再加上其他的一些Handler,比如StreamHandler等等來擷取更多的log資訊,當然也可以將你的log資訊通過設定檔來完成。
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.