logging介紹

  1. logging介紹
    Python的logging模塊提供了通用的日志系統(tǒng)辜窑,可以方便第三方模塊或者是應(yīng)用使用。這個模塊提供不同的日志級別寨躁,并可以采用不同的方式記錄日志穆碎,比如文件,HTTP GET/POST职恳,SMTP所禀,Socket等,甚至可以自己實現(xiàn)具體的日志記錄方式放钦。

     logging模塊與log4j的機制是一樣的色徘,只是具體的實現(xiàn)細(xì)節(jié)不同。模塊提供logger操禀,handler褂策,filter,formatter床蜘。
    
     logger:提供日志接口辙培,供應(yīng)用代碼使用。logger最長用的操作有兩類:配置和發(fā)送日志消息邢锯⊙锶铮可以通過logging.getLogger(name)獲取logger對象,如果不指定name則返回root對象丹擎,多次使用相同的name調(diào)用getLogger方法返回同一個logger對象尾抑。
    
     handler:將日志記錄(log record)發(fā)送到合適的目的地(destination),比如文件蒂培,socket等再愈。一個logger對象可以通過addHandler方法添加0到多個handler,每個handler又可以定義不同日志級別护戳,以實現(xiàn)日志分級過濾顯示翎冲。
    
     filter:提供一種優(yōu)雅的方式?jīng)Q定一個日志記錄是否發(fā)送到handler。
    
     formatter:指定日志記錄輸出的具體格式媳荒。formatter的構(gòu)造方法需要兩個參數(shù):消息的格式字符串和日期字符串抗悍,這兩個參數(shù)都是可選的驹饺。
    
     與log4j類似,logger缴渊,handler和日志消息的調(diào)用可以有具體的日志級別(Level)赏壹,只有在日志消息的級別大于logger和handler的級別。
    

import logging
import logging.handlers

LOG_FILE = 'tst.log'

handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes = 1024*1024, backupCount = 5) # 實例化handler
fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s'

formatter = logging.Formatter(fmt) # 實例化formatter
handler.setFormatter(formatter) # 為handler添加formatter

logger = logging.getLogger('tst') # 獲取名為tst的logger
logger.addHandler(handler) # 為logger添加handler
logger.setLevel(logging.DEBUG)

logger.info('first info message')
logger.debug('first debug message')
輸出:
2012-03-04 23:21:59,682 - log_test.py:16 - tst - first info message
2012-03-04 23:21:59,682 - log_test.py:17 - tst - first debug message
關(guān)于formatter的配置衔沼,采用的是%(<dict key>)s的形式蝌借,就是字典的關(guān)鍵字替換。提供的關(guān)鍵字包括:
Format Description
%(name)s Name of the logger (logging channel).
%(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL).
%(levelname)s Text logging level for the message ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
%(pathname)s Full pathname of the source file where the logging call was issued (if available).
%(filename)s Filename portion of pathname.
%(module)s Module (name portion of filename).
%(funcName)s Name of function containing the logging call.
%(lineno)d Source line number where the logging call was issued (if available).
%(created)f Time when the LogRecord was created (as returned by time.time()).
%(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.
%(asctime)s Human-readable time when the LogRecord was created. By default this is of the form “2003-07-08 16:49:45,896” (the numbers after the comma are millisecond portion of the time).
%(msecs)d Millisecond portion of the time when the LogRecord was created.
%(thread)d Thread ID (if available).
%(threadName)s Thread name (if available).
%(process)d Process ID (if available).
%(message)s The logged message, computed as msg % args.
這個是摘自官網(wǎng)指蚁,提供了很多信息菩佑。

  1. logging的配置
    logging的配置可以采用python代碼或是配置文件。python代碼的方式就是在應(yīng)用的主模塊中凝化,構(gòu)建handler擎鸠,handler,formatter等對象缘圈。而配置文件的方式是將這些對象的依賴關(guān)系分離出來放在文件中劣光。比如前面的例子就類似于python代碼的配置方式。這里看一下采用配置文件的方式糟把。

import logging
import logging.config

logging.config.fileConfig("logging.conf") # 采用配置文件

create logger

logger = logging.getLogger("simpleExample")

"application" code

logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
loggin.conf采用了模式匹配的方式進(jìn)行配置绢涡,正則表達(dá)式是r'^[(.*)]$',從而匹配出所有的組件遣疯。對于同一個組件具有多個實例的情況使用逗號‘雄可,’進(jìn)行分隔。對于一個實例的配置采用componentName_instanceName配置塊缠犀。使用這種方式還是蠻簡單的数苫。
[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
在指定handler的配置時,class是具體的handler類的類名辨液,可以是相對logging模塊或是全路徑類名虐急,比如需要RotatingFileHandler,則class的值可以為:RotatingFileHandler或者logging.handlers.RotatingFileHandler滔迈。args就是要傳給這個類的構(gòu)造方法的參數(shù)止吁,就是一個元組,按照構(gòu)造方法聲明的參數(shù)的順序燎悍。

    輸出:

2012-03-06 00:09:35,713 - simpleExample - DEBUG - debug message
2012-03-06 00:09:35,713 - simpleExample - INFO - info message
2012-03-06 00:09:35,714 - simpleExample - WARNING - warn message
2012-03-06 00:09:35,714 - simpleExample - ERROR - error message
2012-03-06 00:09:35,714 - simpleExample - CRITICAL - critical message
這里還要明確一點敬惦,logger對象是有繼承關(guān)系的,比如名為a.b和a.c的logger都是名為a的子logger谈山,并且所有的logger對象都繼承于root俄删。如果子對象沒有添加handler等一些配置,會從父對象那繼承。這樣就可以通過這種繼承關(guān)系來復(fù)用配置畴椰。

  1. 多模塊使用logging
    logging模塊保證在同一個python解釋器內(nèi)举哟,多次調(diào)用logging.getLogger('log_name')都會返回同一個logger實例,即使是在多個模塊的情況下迅矛。所以典型的多模塊場景下使用logging的方式是在main模塊中配置logging,這個配置會作用于多個的子模塊潜叛,然后在其他模塊中直接通過getLogger獲取Logger對象即可秽褒。
    這里使用上面配置文件:

[loggers]
keys=root,main

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=fmt

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_main]
level=DEBUG
qualname=main
handlers=fileHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=fmt
args=(sys.stdout,)

[handler_fileHandler]
class=logging.handlers.RotatingFileHandler
level=DEBUG
formatter=fmt
args=('tst.log','a',20000,5,)

[formatter_fmt]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
主模塊main.py:

import logging
import logging.config

logging.config.fileConfig('logging.conf')
root_logger = logging.getLogger('root')
root_logger.debug('test root logger...')

logger = logging.getLogger('main')
logger.info('test main logger')
logger.info('start import module 'mod'...')
import mod

logger.debug('let's test mod.testLogger()')
mod.testLogger()

root_logger.info('finish test...')
子模塊mod.py:
import logging
import submod

logger = logging.getLogger('main.mod')
logger.info('logger of mod say something...')

def testLogger():
logger.debug('this is mod.testLogger...')
submod.tst()
子子模塊submod.py:
import logging

logger = logging.getLogger('main.mod.submod')
logger.info('logger of submod say something...')

def tst():
logger.info('this is submod.tst()...')
然后運行python main.py,控制臺輸出:
2012-03-09 18:22:22,793 - root - DEBUG - test root logger...
2012-03-09 18:22:22,793 - main - INFO - test main logger
2012-03-09 18:22:22,809 - main - INFO - start import module 'mod'...
2012-03-09 18:22:22,809 - main.mod.submod - INFO - logger of submod say something...
2012-03-09 18:22:22,809 - main.mod - INFO - logger say something...
2012-03-09 18:22:22,809 - main - DEBUG - let's test mod.testLogger()
2012-03-09 18:22:22,825 - main.mod - DEBUG - this is mod.testLogger...
2012-03-09 18:22:22,825 - main.mod.submod - INFO - this is submod.tst()...
2012-03-09 18:22:22,841 - root - INFO - finish test...
可以看出威兜,和預(yù)想的一樣销斟,然后在看一下tst.log,logger配置中的輸出的目的地:
2012-03-09 18:22:22,793 - main - INFO - test main logger
2012-03-09 18:22:22,809 - main - INFO - start import module 'mod'...
2012-03-09 18:22:22,809 - main.mod.submod - INFO - logger of submod say something...
2012-03-09 18:22:22,809 - main.mod - INFO - logger say something...
2012-03-09 18:22:22,809 - main - DEBUG - let's test mod.testLogger()
2012-03-09 18:22:22,825 - main.mod - DEBUG - this is mod.testLogger...
2012-03-09 18:22:22,825 - main.mod.submod - INFO - this is submod.tst()...
tst.log中沒有root logger輸出的信息椒舵,因為logging.conf中配置了只有main logger及其子logger使用RotatingFileHandler蚂踊,而root logger是輸出到標(biāo)準(zhǔn)輸出。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笔宿,一起剝皮案震驚了整個濱河市犁钟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泼橘,老刑警劉巖涝动,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異炬灭,居然都是意外死亡醋粟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門重归,熙熙樓的掌柜王于貴愁眉苦臉地迎上來米愿,“玉大人,你說我怎么就攤上這事鼻吮∮叮” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵椎木,是天一觀的道長宙搬。 經(jīng)常有香客問我,道長拓哺,這世上最難降的妖魔是什么勇垛? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮士鸥,結(jié)果婚禮上闲孤,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好讼积,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布肥照。 她就那樣靜靜地躺著,像睡著了一般勤众。 火紅的嫁衣襯著肌膚如雪舆绎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天们颜,我揣著相機與錄音吕朵,去河邊找鬼。 笑死窥突,一個胖子當(dāng)著我的面吹牛努溃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阻问,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼梧税,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了称近?” 一聲冷哼從身側(cè)響起第队,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刨秆,沒想到半個月后斥铺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡坛善,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年晾蜘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眠屎。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡剔交,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出改衩,到底是詐尸還是另有隱情岖常,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布葫督,位于F島的核電站竭鞍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏橄镜。R本人自食惡果不足惜偎快,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洽胶。 院中可真熱鬧晒夹,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至读跷,卻和暖如春梗搅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背效览。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工无切, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钦铺。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像肢预,于是被迫代替她去往敵國和親矛洞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

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

  • From:Python之日志處理(logging模塊) - 云游道士 - 博客園 https://www.cnbl...
    vigny的先生閱讀 2,684評論 3 5
  • 常用模塊 認(rèn)識模塊 什么是模塊 什么是模塊? 常見的場景:一個模塊就是一個包含了python定義和聲明的文件锭沟,文...
    go以恒閱讀 1,947評論 0 6
  • 寫在前面的話 代碼中的# > 表示的是輸出結(jié)果 輸入 使用input()函數(shù) 用法 注意input函數(shù)輸出的均是字...
    FlyingLittlePG閱讀 2,753評論 0 8
  • 在應(yīng)用程序中添加日志記錄總的來說基于三個目的:監(jiān)視代碼中變量的變化情況抽兆,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計分析...
    時待吾閱讀 5,038評論 1 13
  • 只有在拼命之后, 才能看到更多的風(fēng)景族淮, 才能得到更多的機會辫红。...
    飛熊1閱讀 202評論 0 2