快速上手Python2中l(wèi)ogging使用

日志記錄的重要性

  • 日志記錄更容易排查到問題的所在之處
  • 節(jié)省時間

日志記錄的流程框架

從下圖中我們可以看出看到這幾種 Python 類型途样,LoggerLogRecord佛寿、Filter幌墓、HandlerFormatter冀泻。

類型說明:

Logger:日志常侣,暴露函數(shù)給應(yīng)用程序,基于日志記錄器和過濾器級別決定哪些日志有效弹渔。

LogRecord :日志記錄器胳施,將日志傳到相應(yīng)的處理器處理。

Handler :處理器, 將(日志記錄器產(chǎn)生的)日志記錄發(fā)送至合適的目的地肢专。

Filter :過濾器, 提供了更好的粒度控制,它可以決定輸出哪些日志記錄舞肆。

Formatter:格式化器, 指明了最終輸出中日志記錄的布局焦辅。

img
  1. 判斷 Logger 對象對于設(shè)置的級別是否可用,如果可用椿胯,則往下執(zhí)行筷登,否則,流程結(jié)束哩盲。
  2. 創(chuàng)建 LogRecord 對象前方,如果注冊到 Logger 對象中的 Filter 對象過濾后返回 False,則不記錄日志廉油,流程結(jié)束惠险,否則,則向下執(zhí)行抒线。
  3. LogRecord 對象將 Handler 對象傳入當(dāng)前的 Logger 對象班巩,(圖中的子流程)如果 Handler 對象的日志級別大于設(shè)置的日志級別,再判斷注冊到 Handler 對象中的 Filter 對象過濾后是否返回 True 而放行輸出日志信息嘶炭,否則不放行趣竣,流程結(jié)束。
  4. 如果傳入的 Handler 大于 Logger 中設(shè)置的級別旱物,也即 Handler 有效遥缕,則往下執(zhí)行,否則宵呛,流程結(jié)束单匣。
  5. 判斷這個 Logger 對象是否還有父 Logger 對象,如果沒有(代表當(dāng)前 Logger 對象是最頂層的 Logger 對象 root Logger)宝穗,流程結(jié)束户秤。否則將 Logger 對象設(shè)置為它的父 Logger 對象,重復(fù)上面的 3逮矛、4 兩步鸡号,輸出父類 Logger 對象中的日志輸出,直到是 root Logger 為止须鼎。

日志輸出格式

  • 日志的輸出格式可以認(rèn)為設(shè)置鲸伴,默認(rèn)格式為下圖所示。
img

日志基本使用

logging 使用非常簡單晋控,使用 basicConfig() 方法就能滿足基本的使用需要汞窗,如果方法沒有傳入?yún)?shù),會根據(jù)默認(rèn)的配置創(chuàng)建Logger 對象赡译,默認(rèn)的日志級別被設(shè)置為 WARNING仲吏,默認(rèn)的日志輸出格式如上圖,該函數(shù)可選的參數(shù)如下表所示。

參數(shù)名稱 參數(shù)描述
filename 日志輸出到文件的文件名
filemode 文件模式裹唆,r[+]誓斥、w[+]、a[+]
format 日志輸出的格式
datefat 日志附帶日期時間的格式
style 格式占位符许帐,默認(rèn)為 "%" 和 “{}”
level 設(shè)置日志輸出級別
stream 定義輸出流岖食,用來初始化 StreamHandler 對象,不能 filename 參數(shù)一起使用卷哩,否則會ValueError 異常
handles 定義處理器把将,用來創(chuàng)建 Handler 對象,不能和 filename 、stream 參數(shù)一起使用吃谣,否則也會拋出 ValueError 異常

示例代碼如下:

import logging

logging.basicConfig()
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

傳入常用的參數(shù),示例代碼如下(這里日志格式占位符中的變量放到后面介紹):

import logging

logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

生成的日志文件 test.log 烙博,內(nèi)容如下:

13-10-18 21:10:32 root:DEBUG:This is a debug message
13-10-18 21:10:32 root:INFO:This is an info message
13-10-18 21:10:32 root:WARNING:This is a warning message
13-10-18 21:10:32 root:ERROR:This is an error message
13-10-18 21:10:32 root:CRITICAL:This is a critical message

但是當(dāng)發(fā)生異常時百揭,直接使用無參數(shù)的 debug()、info()奕剃、warning()衷旅、error()、critical() 方法并不能記錄異常信息纵朋,需要設(shè)置 exc_info 參數(shù)為 True 才可以柿顶,或者使用 exception() 方法,還可以使用 log() 方法操软,但還要設(shè)置日志級別和 exc_info 參數(shù)嘁锯。

import logging

logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
a = 5
b = 0
try:
    c = a / b
except Exception as e:
    # 下面三種方式三選一,推薦使用第一種
    logging.exception("Exception occurred")
    logging.error("Exception occurred", exc_info=True)
    logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)

logging等級使用

級別 何時使用
DEBUG 詳細(xì)信息聂薪,一般只在調(diào)試問題時使用家乘。
INFO 證明事情按預(yù)期工作。
WARNING 某些沒有預(yù)料到的事件的提示藏澳,或者在將來可能會出現(xiàn)的問題提示仁锯。例如:磁盤空間不足。但是軟件還是會照常運行翔悠。
ERROR 由于更嚴(yán)重的問題业崖,軟件已不能執(zhí)行一些功能了。
CRITICAL 嚴(yán)重錯誤蓄愁,表明軟件已不能繼續(xù)運行了腻要。
級別 數(shù)字值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

打印到控制臺

import logging
logging.debug('debug 信息')
logging.warning('只有這個會輸出。涝登。雄家。')
logging.info('info 信息')

由于默認(rèn)設(shè)置的等級是warning,所有只有warning的信息會輸出到控制臺。

WARNING:root:只有這個會輸出趟济。乱投。。

需求:

輸出log到控制臺以及將日志寫入log文件顷编。
保存2種類型的log戚炫, all.log 保存debug, info, warning, critical 信息, error.log則只保存error信息媳纬,同時按照時間自動分割日志文件双肤。

import logging
from logging import handlers

class Logger(object):
    level_relations = {
        'debug':logging.DEBUG,
        'info':logging.INFO,
        'warning':logging.WARNING,
        'error':logging.ERROR,
        'crit':logging.CRITICAL
    }#日志級別關(guān)系映射
    def __init__(self,filename,level='info',when='D',backCount=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
        self.logger = logging.getLogger(filename)
        format_str = logging.Formatter(fmt)#設(shè)置日志格式
        self.logger.setLevel(self.level_relations.get(level))#設(shè)置日志級別
        sh = logging.StreamHandler()#往屏幕上輸出
        sh.setFormatter(format_str) #設(shè)置屏幕上顯示的格式
        th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8')#往文件里寫入#指定間隔時間自動生成文件的處理器
        #實例化TimedRotatingFileHandler
        #interval是時間間隔,backupCount是備份文件的個數(shù)钮惠,如果超過這個個數(shù)茅糜,就會自動刪除,when是間隔的時間單位素挽,單位有以下幾種:
        # S 秒
        # M 分
        # H 小時蔑赘、
        # D 天、
        # W 每星期(interval==0時代表星期一)
        # midnight 每天凌晨
        th.setFormatter(format_str)#設(shè)置文件里寫入的格式
        self.logger.addHandler(sh) #把對象加到logger里
        self.logger.addHandler(th)
if __name__ == '__main__':
    log = Logger('all.log',level='debug')
    log.logger.debug('debug')
    log.logger.info('info')
    log.logger.warning('警告')
    log.logger.error('報錯')
    log.logger.critical('嚴(yán)重')
    Logger('error.log', level='error').logger.error('error')
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末预明,一起剝皮案震驚了整個濱河市缩赛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撰糠,老刑警劉巖酥馍,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異阅酪,居然都是意外死亡物喷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門遮斥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峦失,“玉大人,你說我怎么就攤上這事术吗∥炯” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵较屿,是天一觀的道長隧魄。 經(jīng)常有香客問我,道長隘蝎,這世上最難降的妖魔是什么购啄? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮嘱么,結(jié)果婚禮上狮含,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好几迄,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布蔚龙。 她就那樣靜靜地躺著,像睡著了一般映胁。 火紅的嫁衣襯著肌膚如雪木羹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天解孙,我揣著相機與錄音坑填,去河邊找鬼。 笑死弛姜,一個胖子當(dāng)著我的面吹牛脐瑰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娱据,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盅惜!你這毒婦竟也來了中剩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤抒寂,失蹤者是張志新(化名)和其女友劉穎结啼,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屈芜,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡郊愧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了井佑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片属铁。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖躬翁,靈堂內(nèi)的尸體忽然破棺而出焦蘑,到底是詐尸還是另有隱情,我是刑警寧澤盒发,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布例嘱,位于F島的核電站,受9級特大地震影響宁舰,放射性物質(zhì)發(fā)生泄漏拼卵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一蛮艰、第九天 我趴在偏房一處隱蔽的房頂上張望腋腮。 院中可真熱鬧,春花似錦、人聲如沸低葫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘿悬。三九已至实柠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間善涨,已是汗流浹背窒盐。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钢拧,地道東北人蟹漓。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像源内,于是被迫代替她去往敵國和親葡粒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容