关于使用python logging模块的几点总结
生活随笔
收集整理的這篇文章主要介紹了
关于使用python logging模块的几点总结
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
關于使用python logging模塊的幾點總結
使用python的標準日志模塊logging可以非常方便地記錄日志。Python日志系統(tǒng)非常豐富。添加結構化或非結構化日志輸出到python代碼,寫到文件,輸出到控制臺,發(fā)送到系統(tǒng)日志,或者自定義輸出格式都很容易。
業(yè)務場景如下:
2. logging模塊的API
結合上面的例子,我們說下幾個最常使用的API
logging.getLogger([name])
返回一個logger實例,如果沒有指定name,返回root logger。
只要name相同,返回的logger實例都是同一個而且只有一個,即name和logger實例是一一對應的。這意味著,無需把logger實例在各個模塊中傳遞。只要知道name,就能得到同一個logger實例
Logger.setLevel(lvl)
設置logger的level, level有以下幾個級別:
別的日志都輸出
logger.debug("foobar") ? ?# 不輸出 ??
logger.info("foobar") ? ? ? ?# 輸出 ?
logger.warning("foobar") # 輸出 ?
logger.error("foobar") ? ? ?# 輸出 ?
logger.critical("foobar") ? ?# 輸出 ?
?
Logger.addHandler(hdlr)
logger可以雇傭handler來幫它處理日志, handler主要有以下幾種:
StreamHandler: 輸出到控制臺
FileHandler: ? 輸出到文件
handler還可以設置自己的level以及輸出格式。
logging.basicConfig([**kwargs])
* 這個函數用來配置root logger, 為root logger創(chuàng)建一個StreamHandler,
? ?設置默認的格式。
* 這些函數: logging.debug()、logging.info()、logging.warning()、
? ?logging.error()、logging.critical() 如果調用的時候發(fā)現(xiàn)root logger沒有任何
? ?handler, 會自動調用basicConfig添加一個handler
* 如果root logger已有handler, 這個函數不做任何事情
使用basicConfig來配置root logger的輸出格式和level:
3. 日志對象間的層級結構
除了root logger, 實際上logger實例之間還有父子關系, root logger就是處于最頂層的logger, 它是所有l(wèi)ogger的祖先。如下圖:
root logger是默認的logger
如果不創(chuàng)建logger實例, 直接調用logging.debug()、logging.info()logging.warning()、logging.error()、logging.critical()這些函數,
那么使用的logger就是 root logger, 它可以自動創(chuàng)建,也是單實例的。
如何得到root logger
通過logging.getLogger()或者logging.getLogger("")得到root logger實例。
默認的level
root logger默認的level是logging.WARNING
如何表示父子關系
logger的name的命名方式可以表示logger之間的父子關系. 比如:
parent_logger = logging.getLogger('foo')
用父親的level。如果父親也沒有顯示地設置level, 就用父親的父親的level,以此推....
最后到達root logger,一定設置過level。默認為logging.WARNING
child loggers得到消息后,既把消息分發(fā)給它的handler處理,也會傳遞給所有祖先logger處理,
來看一個例子
可見,孩子logger沒有任何handler,所以對消息不做處理。但是它把消息轉發(fā)給了它的父親以及root logger。最后輸出四條日志。
參考文獻
[1].http://kenby.iteye.com/blog/1162698
使用python的標準日志模塊logging可以非常方便地記錄日志。Python日志系統(tǒng)非常豐富。添加結構化或非結構化日志輸出到python代碼,寫到文件,輸出到控制臺,發(fā)送到系統(tǒng)日志,或者自定義輸出格式都很容易。
下面是我實踐過程中遇到的一些經驗和教訓的總結。
1. 一個簡單的日志系統(tǒng)示例業(yè)務場景如下:
開發(fā)一個日志系統(tǒng), 既要把日志輸出到控制臺, 還要寫入日志文件
#!/usr/bin/env python
#encoding: utf-8import logging#創(chuàng)建一個logger實例
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)#創(chuàng)建一個handler,用于寫入日志文件
fh = logging.FileHandler('simple_log.log')
fh.setLevel(logging.DEBUG)#創(chuàng)建一個handler,用于輸出到控制臺
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)#定義handler的輸出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)#給logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)#記錄一條日志
logger.info('foobar')
運行后, 在控制臺和日志文件都有一條日志:
2. logging模塊的API
結合上面的例子,我們說下幾個最常使用的API
logging.getLogger([name])
返回一個logger實例,如果沒有指定name,返回root logger。
只要name相同,返回的logger實例都是同一個而且只有一個,即name和logger實例是一一對應的。這意味著,無需把logger實例在各個模塊中傳遞。只要知道name,就能得到同一個logger實例
Logger.setLevel(lvl)
設置logger的level, level有以下幾個級別:
NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
如果把looger的級別設置為INFO, 那么小于INFO級別的日志都不輸出, 大于等于INFO級別的日志都輸出
logger.debug("foobar") ? ?# 不輸出 ??
logger.info("foobar") ? ? ? ?# 輸出 ?
logger.warning("foobar") # 輸出 ?
logger.error("foobar") ? ? ?# 輸出 ?
logger.critical("foobar") ? ?# 輸出 ?
?
Logger.addHandler(hdlr)
logger可以雇傭handler來幫它處理日志, handler主要有以下幾種:
StreamHandler: 輸出到控制臺
FileHandler: ? 輸出到文件
handler還可以設置自己的level以及輸出格式。
logging.basicConfig([**kwargs])
* 這個函數用來配置root logger, 為root logger創(chuàng)建一個StreamHandler,
? ?設置默認的格式。
* 這些函數: logging.debug()、logging.info()、logging.warning()、
? ?logging.error()、logging.critical() 如果調用的時候發(fā)現(xiàn)root logger沒有任何
? ?handler, 會自動調用basicConfig添加一個handler
* 如果root logger已有handler, 這個函數不做任何事情
使用basicConfig來配置root logger的輸出格式和level:
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
3. 日志對象間的層級結構
除了root logger, 實際上logger實例之間還有父子關系, root logger就是處于最頂層的logger, 它是所有l(wèi)ogger的祖先。如下圖:
root logger是默認的logger
如果不創(chuàng)建logger實例, 直接調用logging.debug()、logging.info()logging.warning()、logging.error()、logging.critical()這些函數,
那么使用的logger就是 root logger, 它可以自動創(chuàng)建,也是單實例的。
如何得到root logger
通過logging.getLogger()或者logging.getLogger("")得到root logger實例。
默認的level
root logger默認的level是logging.WARNING
如何表示父子關系
logger的name的命名方式可以表示logger之間的父子關系. 比如:
parent_logger = logging.getLogger('foo')
child_logger = logging.getLogger('foo.bar')
什么是effective level
logger有一個概念,叫effective level。 如果一個logger沒有顯示地設置level,那么它就用父親的level。如果父親也沒有顯示地設置level, 就用父親的父親的level,以此推....
最后到達root logger,一定設置過level。默認為logging.WARNING
child loggers得到消息后,既把消息分發(fā)給它的handler處理,也會傳遞給所有祖先logger處理,
來看一個例子
#!/usr/bin/env python
#encoding: utf-8import logginglogging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')r = logging.getLogger()ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
r.addHandler(ch)p = logging.getLogger('foo')
p.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(message)s')
ch.setFormatter(formatter)
p.addHandler(ch)c = logging.getLogger('foo.bar')
c.debug('foo')
輸出如下:
可見,孩子logger沒有任何handler,所以對消息不做處理。但是它把消息轉發(fā)給了它的父親以及root logger。最后輸出四條日志。
參考文獻
[1].http://kenby.iteye.com/blog/1162698
總結
以上是生活随笔為你收集整理的关于使用python logging模块的几点总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中logging.confi
- 下一篇: DeprecationWarning: