日誌一共分紅5個等級,從低到高分別是:DEBUG INFO WARNING ERROR CRITICAL。html
DEBUG:詳細的信息,一般只出如今診斷問題上
INFO:確認一切按預期運行
WARNING:一個跡象代表,一些意想不到的事情發生了,或代表一些問題在不久的未來(例如。磁盤空間低」)。這個軟件還能按預期工做。
ERROR:更嚴重的問題,軟件沒能執行一些功能
CRITICAL:一個嚴重的錯誤,這代表程序自己可能沒法繼續運行python
這5個等級,也分別對應5種打日誌的方法: debug 、info 、warning 、error 、critical。默認的是WARNING,當在WARNING或之上時才被跟蹤。
安全
好比,編寫一個叫作log.py的文件,以下:函數
# coding=utf-8 __author__ = 'liu.chunming' import logging logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') # use logging logging.info('this is a loggging info message') logging.debug('this is a loggging debug message') logging.warning('this is loggging a warning message') logging.error('this is an loggging error message') logging.critical('this is a loggging critical message')
執行上面的代碼將在Console中輸出下面信息:學習
2015-05-21 17:25:22,572 - log.py[line:10] - WARNING: this is loggging a warning message
2015-05-21 17:25:22,572 - log.py[line:11] - ERROR: this is an loggging error message
2015-05-21 17:25:22,572 - log.py[line:12] - CRITICAL: this is a loggging critical messageui
【解析】this
經過logging.basicConfig函數對日誌的輸出格式及方式作相關配置,上面代碼設置日誌的輸出等級是WARNING級別,意思是WARNING級別以上的日誌纔會輸出。另外還制定了日誌輸出的格式。spa
咱們還能夠將日誌輸出到文件,只須要在logging.basicConfig函數中設置好輸出文件的文件名和寫文件的模式。.net
# coding=utf-8 __author__ = 'liu.chunming' import logging logging.basicConfig(level=logging.WARNING, filename='./log/log.txt', filemode='w', format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') # use logging logging.info('this is a loggging info message') logging.debug('this is a loggging debug message') logging.warning('this is loggging a warning message') logging.error('this is an loggging error message') logging.critical('this is a loggging critical message')
運行以後,打開該文件./log/log.txt,效果以下:線程
2015-05-21 17:30:20,282 - log.py[line:12] - WARNING: this is loggging a warning message
2015-05-21 17:30:20,282 - log.py[line:13] - ERROR: this is an loggging error message
2015-05-21 17:30:20,282 - log.py[line:14] - CRITICAL: this is a loggging critical message
這就須要一個叫做Logger 的對象來幫忙,下面將對他進行詳細介紹,如今這裏先學習怎麼實現把日誌既要輸出到控制檯又要輸出到文件的功能。
# coding=utf-8 __author__ = 'liu.chunming' import logging # 第一步,建立一個logger logger = logging.getLogger() logger.setLevel(logging.INFO) # Log等級總開關 # 第二步,建立一個handler,用於寫入日誌文件 logfile = './log/logger.txt' fh = logging.FileHandler(logfile, mode='w') fh.setLevel(logging.DEBUG) # 輸出到file的log等級的開關 # 第三步,再建立一個handler,用於輸出到控制檯 ch = logging.StreamHandler() ch.setLevel(logging.WARNING) # 輸出到console的log等級的開關 # 第四步,定義handler的輸出格式 formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s") fh.setFormatter(formatter) ch.setFormatter(formatter) # 第五步,將logger添加到handler裏面 logger.addHandler(fh) logger.addHandler(ch) # 日誌 logger.debug('this is a logger debug message') logger.info('this is a logger info message') logger.warning('this is a logger warning message') logger.error('this is a logger error message') logger.critical('this is a logger critical message')
執行這段代碼以後,在console中,能夠看到:
C:\Python27\python.exe C:/Users/liu.chunming/PycharmProjects/Myproject/log.py
2015-05-21 17:47:50,292 - log.py[line:30] - WARNING: this is a logger warning message
2015-05-21 17:47:50,292 - log.py[line:31] - ERROR: this is a logger error message
2015-05-21 17:47:50,293 - log.py[line:32] - CRITICAL: this is a logger critical message
在logger.txt中,能夠看到:
2015-05-21 17:47:50,292 - log.py[line:29] - INFO: this is a logger info message
2015-05-21 17:47:50,292 - log.py[line:30] - WARNING: this is a logger warning message
2015-05-21 17:47:50,292 - log.py[line:31] - ERROR: this is a logger error message
2015-05-21 17:47:50,293 - log.py[line:32] - CRITICAL: this is a logger critical message
【解析】
能夠發現,實現這個功能一共分5步:
第一步,建立一個logger;第二步,建立一個handler,用於寫入日誌文件;第三步,再建立一個handler,用於輸出到控制檯;第四步,定義handler的輸出格式;第五步,將logger添加到handler裏面。這段代碼裏面提到了好多概念,包括:Logger,Handler,Formatter。後面講對這些概念進行講解。
logging.basicConfig函數中,能夠指定日誌的輸出格式format,這個參數能夠輸出不少有用的信息,如上例所示:
%(levelno)s: 打印日誌級別的數值
%(levelname)s: 打印日誌級別名稱
%(pathname)s: 打印當前執行程序的路徑,其實就是sys.argv[0]
%(filename)s: 打印當前執行程序名
%(funcName)s: 打印日誌的當前函數
%(lineno)d: 打印日誌的當前行號
%(asctime)s: 打印日誌的時間
%(thread)d: 打印線程ID
%(threadName)s: 打印線程名稱
%(process)d: 打印進程ID
%(message)s: 打印日誌信息
我在工做中給的經常使用格式在前面已經看到了。就是:
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
這個格式能夠輸出日誌的打印時間,是哪一個模塊輸出的,輸出的日誌級別是什麼,以及輸入的日誌內容。
接下來學習一些日誌組件以及一些高級部分。日誌組件包括:loggers、handlers,filters,formatters.
Logger 對象扮演了三重角色.首先,它暴露給應用幾個方法以便應用能夠在運行時寫log.其次,Logger對象按照log信息的嚴重程度或者根據filter對 象來決定如何處理log信息(默認的過濾功能).最後,logger還負責把log信息傳送給相關的loghandlers.
Handler對象負責分配合適的log信息(基於log信息的嚴重 程度)到handler指定的目的地.Logger對象能夠用addHandler()方法添加零個或多個handler對象到它自身.一個常見的場景 是,一個應用可能但願把全部的log信息都發送到一個log文件中去,全部的error級別以上的log信息都發送到stdout,全部critical 的log信息經過email發送.這個場景裏要求三個不一樣handler處理,每一個handler負責把特定的log信息發送到特定的地方.
filter:細緻化,選擇哪些日誌輸出
format:設置顯示格式
一、logging.basicConfig([**kwargs]):
Does basic configuration for the logging system by creating a StreamHandler with a defaultFormatter and adding it to the root logger. The functionsdebug(),info(),warning(),error() andcritical() will callbasicConfig() automatically if no handlers are defined for the root logger.
This function does nothing if the root logger already has handlers configured for it.
爲日誌模塊配置基本信息。kwargs 支持以下幾個關鍵字參數:
filename :日誌文件的保存路徑。若是配置了些參數,將自動建立一個FileHandler做爲Handler;
filemode :日誌文件的打開模式。 默認值爲'a',表示日誌消息以追加的形式添加到日誌文件中。若是設爲'w', 那麼每次程序啓動的時候都會建立一個新的日誌文件;
format :設置日誌輸出格式;
datefmt :定義日期格式;
level :設置日誌的級別.對低於該級別的日誌消息將被忽略;
stream :設置特定的流用於初始化StreamHandler;
演示以下:
import logging import os FILE=os.getcwd() logging.basicConfig(level=logging.DEBUG, format='%(asctime)s:%(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename = os.path.join(FILE,'log.txt'), filemode='w') logging.info('msg') logging.debug('msg2')
二、logging.getLogger([name])
建立Logger對象。日誌記錄的工做主要由Logger對象來完成。在調用getLogger時要提供Logger的名稱(注:屢次使用相同名稱 來調用getLogger,返回的是同一個對象的引用。),Logger實例之間有層次關係,這些關係經過Logger名稱來體現,如:
p = logging.getLogger("root")
c1 = logging.getLogger("root.c1")
c2 = logging.getLogger("root.c2")
例子中,p是父logger, c1,c2分別是p的子logger。c1, c2將繼承p的設置。若是省略了name參數, getLogger將返回日誌對象層次關係中的根Logger。
import logging '''命名''' log2=logging.getLogger('BeginMan') #生成一個日誌對象 print log2 #<logging.Logger object at 0x00000000026D1710> '''無名''' log3 = logging.getLogger() print log3 #<logging.RootLogger object at 0x0000000002721630> 若是沒有指定name,則返回RootLogger '''最好的方式''' log = logging.getLogger(__name__)#__name__ is the module’s name in the Python package namespace. print log #<logging.Logger object at 0x0000000001CD5518> Logger對象 print __name__ #__main__
3、Logger對象
經過logging.getLogger(nam)來獲取Logger對象,
Class logging.Logger
有以下屬性和方法:
一、Logger.propagate
print log.propagate #1
具體參考:http://docs.python.org/2.7/library/logging.html
二、Logger.setLevel(lvl)
設置日誌的級別。對於低於該級別的日誌消息將被忽略.
import logging import os logging.basicConfig(format="%(levelname)s,%(message)s",filename=os.path.join(os.getcwd(),'log.txt'),level=logging.DEBUG) log = logging.getLogger('root.set') #Logger對象 print log.propagate #1 log.setLevel(logging.WARN) #日誌記錄級別爲WARNNING log.info('msg') #不會被記錄 log.debug('msg') #不會被記錄 log.warning('msg') log.error('msg')
三、Logger.debug(msg [ ,*args [, **kwargs]])
記錄DEBUG級別的日誌信息。參數msg是信息的格式,args與kwargs分別是格式參數。
import logging logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG) log = logging.getLogger('root') log.debug('%s, %s, %s', *('error', 'debug', 'info')) log.debug('%(module)s, %(info)s', {'module': 'log', 'info': 'error'})
四、同上
五、Logger.log(lvl, msg[ , *args[ , **kwargs]] )
記錄日誌,參數lvl用戶設置日誌信息的級別。參數msg, *args, **kwargs的含義與Logger.debug同樣。
log.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日誌','info':'error'}) #ERROR,log日誌 error log.log(logging.ERROR,'再來一遍:%s,%s',*('log日誌','error')) #ERROR,再來一遍:log日誌,error
六、Logger.exception(msg[, *args])
以ERROR級別記錄日誌消息,異常跟蹤信息將被自動添加到日誌消息裏。Logger.exception經過用在異常處理塊中,如:
import logging import os logging.basicConfig(format="%(levelname)s,%(message)s",filename=os.path.join(os.getcwd(),'log.txt'),level=logging.DEBUG) log = logging.getLogger('root') #Logger對象 try: raise Exception,u'錯誤異常' except: log.exception('exception') #異常信息被自動添加到日誌消息中 打開文件,顯示以下: '''ERROR,exception Traceback (most recent call last): File "E:\project\py\src\log3.py", line 12, in <module> raise Exception,u'錯誤異常' Exception: 錯誤異常 '''
七、Logger.addFilter(filt)
指定過濾器
八、Logger.removeFilter(filt)
移除指定的過濾器
九、Logger.filter(record)
....其餘的後面介紹
4、 Handler對象、Formatter對象、Filter對象、Filter對象
這裏簡要介紹
#coding=utf8 ''' Created on 2013年9月23日 Function : Handler對象、Formatter對象、Filter對象、Filter對象 @author : BeginMan ''' import logging import os '''Logger''' l = logging.Logger('root') #建立Logger對象 log = logging.getLogger('root') #經過logging.getLogger建立Logger對象 print l #<logging.Logger object at 0x0000000001DF5B70> print log #<logging.Logger object at 0x00000000022A16D8> '''Handler''' handler = logging.Handler() #建立Handler對象 handler.__init__(logging.DEBUG) #經過設置level來初始化Handler實例 handler.createLock() #初始化一個線程鎖能夠用來序列化訪問底層I / O功能,這可能不是線程安全的。 handler.acquire() #獲取線程鎖經過handler.createLock() handler.release() #釋放線程鎖經過獲取handler.acquire() handler.setLevel(logging.DEBUG) #設置臨界值,若是Logging信息級別小於它則被忽視,當一個handler對象被建立,級別沒有被設置,致使全部的信息會被處理。 handler.setFormatter("%(levelname)s,%(message)s") #設置格式 # handler.addFilter(filter) #添加指定的過濾器 # handler.removeFilter(filter) #移除指定的過濾器 # handler.filter(record) #經過設置過濾器適用於記錄並返回真值若是要處理的記錄 handler.flush() #確保全部的日誌輸出已經被刷新 handler.close() #收拾任何所使用資源處理程序, # handler.handle(record) #有條件地發出指定的日誌記錄,這取決於過濾器可能被添加處處理程序。 # handler.handlerError(record) #處理錯誤 # handler.format(record) #格式輸出 # handler.emit(record) #Formatter:http://docs.python.org/2.7/library/logging.html#logging.Formatter '''Formatter: the base Formatter allows a formatter string to be specified,is none ,used default value '%(message)s' class logging.Formatter(fmt=None,datefmt=None) If no fmt is specified, '%(message)s' is used. If no datefmt is specified, the ISO8601 date format is used. ''' fm = logging.Formatter('%(levelname)s:%(message)s','%m/%d/%Y %I:%M:%S %p') print fm #<logging.Formatter object at 0x0000000002311828> #有以下方法:format()、formatTime()、formatException() #http://docs.python.org/2.7/library/logging.html#formatter-objects '''Filter''' ''' class logging.Filter(name=''): 返回Filter實例,If name is specified, it names a logger which, together with its children, will have its events allowed through the filter. If name is the empty string, allows every event. 用於Loggers、Handlers等過濾的設置 若是一個過濾器初始化爲'A.B',則容許'A.B/A.B.C/A.B.C.D/A.B.D'等,但不容許'A.BB/B.A'等經過 若是初始化爲空字符串,則沒有過濾。 它有filter()方法 ''' '''LogRecord ''' '''class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None) LogRecord 實例能夠被Logger自動建立.也能夠經過makeLogRecord()來建立''' #http://docs.python.org/2.7/library/logging.html#logrecord-objects