Python-Log

示例代碼

import logging

LOG_FORMAT = "%(asctime)s====%(levelname)s++++%(message)s"
logging.basicConfig(filename="tulingxueyuan.log", level=logging.DEBUG, format=LOG_FORMAT)
logging.debug("This is a debug log .")
logging.info("This is a info log .")
logging.warning("This is a warning log .")
logging.error("This is a error log .")
logging.critical("This is a critical log .")

# 另一種寫法
logging.log(logging.DEBUG, "This is a debug log .")
logging.log(logging.INFO, "This is a info log .")
logging.log(logging.WARNING, "This is a warning log .")
logging.log(logging.ERROR, "This is a error log .")
logging.log(logging.CRITICAL, "This is a critical log .")

logging模塊的使用方式

logging模塊提供兩種記錄日志的方式:

  • 第一種 使用logging提供的模塊級別的函數(shù)
  • 第二種 使用logging日志系統(tǒng)的四大組件


    常用函數(shù)

其中l(wèi)ogging.basicConfig(**kwargs)函數(shù)用于指定“要記錄的日志級別”瓦胎、“日志格式”赖条、“日志輸出位置”痹束、“日志文件的打開模式”等信息铅忿,其他幾個都是用于記錄各個級別日志的函數(shù)。

logging.basicConfig函數(shù)說明

關(guān)鍵字參數(shù):

  • filename,指定日志輸目標(biāo)文件的文件名,指定后日志不會在控制臺輸出第煮。
  • filemode,指定日志文件的打開模式抑党,默認(rèn)為‘a(chǎn)’空盼,此項必須在filename指定才有效。
  • format新荤,指定日志格式字符串揽趾。
  • datefmt,指定日期時間格式苛骨。
  • level篱瞎,指定日志器的日志級別。
  • stream痒芝,指定日志輸出目標(biāo)stream俐筋,如sys.stdout、sys.stderr以及網(wǎng)絡(luò)stream严衬。需要說明的是澄者,stream和filename不能同時提供,否則會引發(fā) ValueError異常。
  • style粱挡,指定format格式字符串的風(fēng)格赠幕,可取值為'%'、'{'和'$'询筏,默認(rèn)為'%'榕堰。
  • handlers,該選項如果被指定嫌套,它應(yīng)該是一個創(chuàng)建了多個Handler的可迭代對象逆屡,這些handler將會被添加到root logger。需要說明的是:filename踱讨、stream和handlers這三個配置項只能有一個存在满力,不能同時出現(xiàn)2個或3個铡羡,否則會引發(fā)ValueError異常筏餐。
logging模塊定義的格式字符串字段
format格式字段

logging模塊的處理流程

四大組件

  • 日志器(Logger):產(chǎn)生日志的一個接口
  • 處理器(Handler):把產(chǎn)生的日志發(fā)送到相應(yīng)的目的地
  • 過濾器(Filter):更精細(xì)的控制那些日志輸出
  • 格式器(Formatter):對輸出信息進(jìn)行格式化

組件直接的關(guān)系如下:

  • 日志器(logger)需要通過處理器(handler)將日志信息輸出到目標(biāo)位置综液,如:文件、sys.stdout味混、網(wǎng)絡(luò)等;
  • 不同的處理器(handler)可以將日志輸出到不同的位置诫惭;
  • 日志器(logger)可以設(shè)置多個處理器(handler)將同一條日志記錄輸出到不同的位置翁锡;
  • 每個處理器(handler)都可以設(shè)置自己的過濾器(filter)實現(xiàn)日志過濾,從而只保留感興趣的日志夕土;
  • 每個處理器(handler)都可以設(shè)置自己的格式器(formatter)實現(xiàn)同一條日志以不同的格式輸出到不同的地方馆衔。

日志器(logger)是入口,真正干活兒的是處理器(handler)怨绣,處理器(handler)還可以通過過濾器(filter)和格式器(formatter)對要輸出的日志內(nèi)容做過濾和格式化等處理操作角溃。

logging模塊相關(guān)類及常用方法

下面介紹下與logging四大組件相關(guān)的類:Logger, Handler, Filter, Formatter。

Logger類

Logger對象有3個任務(wù):

  • 使應(yīng)用程序可以在運(yùn)行時記錄日志消息
  • 基于日志嚴(yán)重等級或filter對象決定對哪些日志進(jìn)行后續(xù)處理
  • 將日志消息傳給所有感興趣的handlers

logger對象最常用的方法分為兩類:
配置方法和消息發(fā)送方法篮撑。
常用配置方法:

方法 描述
Logger.setLevel() 設(shè)置日志器將會處理的日志消息的最低嚴(yán)重級別
Logger.addHandler() 和 Logger.removeHandler() 為該logger對象添加 和 移除一個handler對象
Logger.addFilter() 和 Logger.removeFilter() 為該logger對象添加 和 移除一個filter對象

創(chuàng)建日志方法:

方法 描述
Logger.debug(), Logger.info()等 用來創(chuàng)建指定等級的日志記錄
Logger.exception() 創(chuàng)建一個類似于Logger.error()的日志消息
Logger.log() 需要獲取一個明確的日志level參數(shù)來創(chuàng)建一個日志記錄
  • Logger.exception()與Logger.error()的區(qū)別在于:Logger.exception()將會輸出堆棧追蹤信息减细,另外通常只是在一個exception handler中調(diào)用該方法。
  • Logger.log()與Logger.debug()赢笨、Logger.info()等方法相比未蝌,雖然需要多傳一個level參數(shù),顯得不是那么方便茧妒,但是當(dāng)需要記錄自定義level的日志時還是需要該方法來完成萧吠。

通過logging.getLogger方法來得到Logger對象,logging.getLogger()方法有一個可選參數(shù)name桐筏,該參數(shù)表示將要返回的日志器的名稱標(biāo)識纸型,如果不提供該參數(shù),則其值為'root'。若以相同的name參數(shù)值多次調(diào)用getLogger()方法狰腌,將會返回指向同一個logger對象的引用除破。

Handler類

Handler對象的作用是(基于日志消息的level)將消息分發(fā)到handler指定的位置(文件、網(wǎng)絡(luò)癌别、郵件等)皂岔。Logger對象可以通過addHandler()方法為自己添加0個或者更多個handler對象。比如展姐,一個應(yīng)用程序可能想要實現(xiàn)以下幾個日志需求:

  • 把所有日志都發(fā)送到一個日志文件中躁垛;
  • 把所有嚴(yán)重級別大于等于error的日志發(fā)送到stdout(標(biāo)準(zhǔn)輸出);
  • 把所有嚴(yán)重級別為critical的日志發(fā)送到一個email郵件地址圾笨。這種場景就需要3個不同的handlers教馆,每個handler復(fù)雜發(fā)送一個特定嚴(yán)重級別的日志到一個特定的位置。
    配置方法:
方法 描述
Handler.setLevel() 設(shè)置handler將會處理的日志消息的最低嚴(yán)重級別
Handler.setFormatter() 為handler設(shè)置一個格式器對象
Handler.addFilter() 和 Handler.removeFilter() 為handler添加 和 刪除一個過濾器對象

需要說明的是擂达,應(yīng)用程序代碼不應(yīng)該直接實例化和使用Handler實例土铺。因為Handler是一個基類,它只定義了素有handlers都應(yīng)該有的接口板鬓,同時提供了一些子類可以直接使用或覆蓋的默認(rèn)行為悲敷。
常用的Handler:

Handler 描述
logging.StreamHandler 將日志消息發(fā)送到輸出到Stream,如std.out, std.err或任何file-like對象俭令。
logging.FileHandler 將日志消息發(fā)送到磁盤文件后德,默認(rèn)情況下文件大小會無限增長
logging.handlers.RotatingFileHandler 將日志消息發(fā)送到磁盤文件,并支持日志文件按大小切割
logging.hanlders.TimedRotatingFileHandler 將日志消息發(fā)送到磁盤文件抄腔,并支持日志文件按時間切割
logging.handlers.HTTPHandler 將日志消息以GET或POST的方式發(fā)送給一個HTTP服務(wù)器
logging.handlers.SMTPHandler 將日志消息發(fā)送給一個指定的email地址
logging.NullHandler 該Handler實例會忽略error messages瓢湃,通常被想使用logging的library開發(fā)者使用來避免'No handlers could be found for logger XXX'信息的出現(xiàn)。
Formater類

Formater對象用于配置日志信息的最終順序赫蛇、結(jié)構(gòu)和內(nèi)容绵患。與logging.Handler基類不同的是,應(yīng)用代碼可以直接實例化Formatter類悟耘。另外落蝙,如果你的應(yīng)用程序需要一些特殊的處理行為,也可以實現(xiàn)一個Formatter的子類來完成暂幼。
Formatter類構(gòu)造方法如下:

logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
Filter類

定義如下:

class logging.Filter(name=“”)
      filter(record)

比如掘殴,一個filter實例化時傳遞的name參數(shù)值為'A.B',那么該filter實例將只允許名稱為類似如下規(guī)則的loggers產(chǎn)生的日志記錄通過過濾:'A.B'粟誓,'A.B,C'奏寨,'A.B.C.D','A.B.D'鹰服,而名稱為'A.BB', 'B.A.B'的loggers產(chǎn)生的日志則會被過濾掉病瞳。如果name的值為空字符串揽咕,則允許所有的日志事件通過過濾。
filter方法用于具體控制傳遞的record記錄是否能通過過濾套菜,如果該方法返回值為0表示不能通過過濾亲善,返回值為非0表示可以通過過濾。

使用logging四大組件記錄日志

1.需求
  • 將所有級別的所有日志寫入磁盤文件
  • all.log中記錄所有的日志信息逗柴,格式為:日期時間-級別-內(nèi)容
  • error.log單獨(dú)記錄error及以上的日志信息蛹头,日期和時間 - 日志級別 - 文件名[:行號] - 日志信息
  • all.log在每天凌晨進(jìn)行日志切割
2.分析
  • 記錄所有級別的日志,level設(shè)置為DEBUG
  • 日志被發(fā)送給兩個不同的目的地戏溺,需要設(shè)置兩個handler渣蜗,都需要寫入磁盤,都跟filehandler有關(guān)
  • all.log要求按照時間進(jìn)行日志分割旷祸,需要用到logging.handlers.TimedRotatingFileHandler耕拷,而error.log沒有要求日志分割,可以使用FileHandler
  • 兩個日志文件格式不同托享,設(shè)置不同的格式器
3.代碼實現(xiàn)
import logging
import logging.handlers
import datetime


logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)

rf_handler = logging.handlers.TimedRotatingFileHandler('all.log', when='midnight',
                                                       interval=1, backupCount=7,
                                                       atTime=datetime.time(0, 0, 0, 0))
rf_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))

f_handler = logging.FileHandler('error.log')
f_handler.setLevel(logging.ERROR)
f_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(filename)s[:%(lineno)d] - %(message)s"))

logger.addHandler(rf_handler)
logger.addHandler(f_handler)

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

配置logging的幾種方式

作為開發(fā)者骚烧,我們可以通過以下3中方式來配置logging:

  • 使用python代碼顯式的創(chuàng)建loggers,handlers和formatters并分別調(diào)用他們的配置函數(shù)闰围。
  • 創(chuàng)建日志配置文件赃绊,然后使用fileConfig函數(shù)來讀取該文件的內(nèi)容
  • 創(chuàng)建一個包含配置信息的dict,然后把它傳遞給dictConfig函數(shù)

可以參考博客《Python之配置日志的幾種方式》

向日志輸出中添加上下文信息

除了傳遞給日志記錄函數(shù)的參數(shù)外羡榴,有時候我們還想在日志輸出中包含一些額外的上下文信息碧查。比如,在一個網(wǎng)絡(luò)應(yīng)用中炕矮,可能希望在日志中記錄客戶端的特定信息,如:遠(yuǎn)程客戶端的IP地址和用戶名者冤。這里我們來介紹以下幾種實現(xiàn)方式:

  • 通過日志記錄函數(shù)傳遞一個extra參數(shù)引入上下文信息
  • 使LoggerAdapter引入上下文信息
  • 使用Filters引入上下文信息

具體說明請參考另一篇博文《Python之向日志輸出中添加上下文信息》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肤视,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涉枫,更是在濱河造成了極大的恐慌邢滑,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愿汰,死亡現(xiàn)場離奇詭異困后,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)衬廷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門摇予,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吗跋,你說我怎么就攤上這事侧戴∧眩” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵酗宋,是天一觀的道長积仗。 經(jīng)常有香客問我,道長蜕猫,這世上最難降的妖魔是什么寂曹? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮回右,結(jié)果婚禮上隆圆,老公的妹妹穿的比我還像新娘。我一直安慰自己楣黍,他們只是感情好匾灶,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著租漂,像睡著了一般阶女。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哩治,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天秃踩,我揣著相機(jī)與錄音,去河邊找鬼业筏。 笑死憔杨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒜胖。 我是一名探鬼主播消别,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼台谢!你這毒婦竟也來了寻狂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤朋沮,失蹤者是張志新(化名)和其女友劉穎蛇券,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體樊拓,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纠亚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了筋夏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒂胞。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖条篷,靈堂內(nèi)的尸體忽然破棺而出啤誊,到底是詐尸還是另有隱情岳瞭,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布蚊锹,位于F島的核電站瞳筏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏牡昆。R本人自食惡果不足惜姚炕,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丢烘。 院中可真熱鬧柱宦,春花似錦、人聲如沸播瞳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赢乓。三九已至忧侧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牌芋,已是汗流浹背蚓炬。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留躺屁,地道東北人肯夏。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像犀暑,于是被迫代替她去往敵國和親驯击。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

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

  • LOG http://www.cnblogs.com/yyds/p/6901864.html loogging模塊...
    Ericoool閱讀 2,551評論 0 0
  • (一)耐亏、日志相關(guān)概念 1徊都、日志的作用 通過log的分析,可以方便用戶了解系統(tǒng)或軟件苹熏、應(yīng)用的運(yùn)行情況碟贾;如果你的應(yīng)用l...
    Rainy丶Wang閱讀 600評論 0 0
  • 本文章是我大概三年前币喧,在上家單位使用 Python 工作時結(jié)合官方文檔做的整理」煊颍現(xiàn)在 Python 官方文檔聽說已...
    好吃的野菜閱讀 216,538評論 14 232
  • log 參考資料 [http://www.cnblogs.com/yyds/p/6901864.html] log...
    末世狂人閱讀 430評論 0 1
  • 1、添加空格?的方法: (單個空格)輸入 可以得到2個空格 2杀餐、添加代碼的方法:鍵盤ESC下方...
    Lamzz閱讀 238評論 0 0