Python日志模塊logging用法


1、日志級別

日志一共分成5個等級,從低到高分別是:DEBUG INFO WARNING ERROR CRITICAL。

DEBUG:詳細的信息,通常只出現在診斷問題上
INFO:確認一切按預期運行
WARNING:一個跡象表明,一些意想不到的事情發生了,或表明一些問題在不久的將來(例如。磁盤空間低”)。這個軟件還能按預期工作。
ERROR:更嚴重的問題,軟件沒能執行一些功能
CRITICAL:一個嚴重的錯誤,這表明程序本身可能無法繼續運行

這5個等級,也分別對應5種打日志的方法: debug 、info 、warning 、error 、critical。默認的是WARNING,當在WARNING或之上時才被跟蹤。

2、日志輸出

有兩種方式記錄跟蹤,一種輸出控制台,另一種是記錄到文件中,如日志文件。

2.1、將日志輸出到控制台

比如,編寫一個叫做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中輸出下面信息:
C:\Python27\python.exe C:/Users/liu.chunming/PycharmProjects/Myproject/log.py
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 message

【解析】

通過logging.basicConfig函數對日志的輸出格式及方式做相關配置,上面代碼設置日志的輸出等級是WARNING級別,意思是WARNING級別以上的日志才會輸出。另外還制定了日志輸出的格式。

2.2、將日志輸出到文件

我們還可以將日志輸出到文件,只需要在logging.basicConfig函數中設置好輸出文件的文件名和寫文件的模式。

# 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

2.3、既要把日志輸出到控制台, 還要寫入日志文件

這就需要一個叫作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。后面講對這些概念進行講解。

3、多個模塊中日志輸出順序

通常我們的工作中會有多個模塊都需要輸出日志。那么,具有調用關系的模塊之間,它門的日志輸出順序是怎么樣的?我們來演示下:假設有兩個文件,分別是util.py:

# util.py
__author__ = 'liu.chunming'
import logging
 
def fun():
    logging.info('this is a log in util module')

和main.py

# main.py
# coding=utf-8
__author__ = 'liu.chunming'
import logging
import util
 
logging.basicConfig(level=logging.INFO,
                    filename='./log/log.txt',
                    filemode='w',
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
def main():
    logging.info('main module start')
    util.fun()
    logging.info('main module stop')
 
if __name__ == '__main__':
    main()

運行后打開log.txt,結果如下:
2015-05-21 18:10:34,684 - main.py[line:11] - INFO: main module start
2015-05-21 18:10:34,684 - util.py[line:5] - INFO: this is a log in util module
2015-05-21 18:10:34,684 - main.py[line:13] - INFO: main module stop

【解析】

可以看出,日志的輸出順序就是模塊的執行順序。

4、日志格式說明

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'

這個格式可以輸出日志的打印時間,是哪個模塊輸出的,輸出的日志級別是什么,以及輸入的日志內容。

5、高級進階

接下來學習一些日志組件以及一些高級部分。日志組件包括: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:設置顯示格式

1、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')

2、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

有如下屬性和方法:

  • 1、Logger.propagate

具體參考:http://docs.python.org/2.7/library/logging.html

  • 2、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')
  • 3、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'})
  • 4、同上
Logger.info(msg[ , *args[ , **kwargs] ] )
Logger.warnning(msg[ , *args[ , **kwargs] ] )
Logger.error(msg[ , *args[ , **kwargs] ] )
Logger.critical(msg[ , *args[ , **kwargs] ] )
  • 5、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

  • 6、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: 錯誤異常
  • 7、Logger.addFilter(filt)

指定過濾器

  • 8、Logger.removeFilter(filt)

移除指定的過濾器

  • 9、Logger.filter(record)

原文:https://blog.csdn.net/liuchunming033/article/details/39080457




微信公眾號:AutoML機器學習
MARSGGBO原創
如有意合作或學術討論歡迎私戳聯系~
郵箱:marsggbo@foxmail.com

2019-2-19




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM