python的logging日誌模組(二)

studywell發表於2017-04-24
轉自:http://blog.csdn.net/langb2014/article/details/53397307

1.簡單的將日誌列印到螢幕

 

import logging

logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

螢幕上列印:
WARNING:root:This is warning message

預設情況下,logging將日誌列印到螢幕,日誌級別為WARNING;
日誌級別大小關係為:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,當然也可以自己定義日誌級別。

2.透過logging.basicConfig函式對日誌的輸出格式及方式做相關配置

import logging

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='myapp.log',
                filemode='w')
    
logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

./myapp.log檔案中內容為:
Sun, 24 May 2009 21:48:54 demo2.py[line:11] DEBUG This is debug message
Sun, 24 May 2009 21:48:54 demo2.py[line:12] INFO This is info message
Sun, 24 May 2009 21:48:54 demo2.py[line:13] WARNING This is warning message

logging.basicConfig函式各引數:
filename: 指定日誌檔名
filemode: 和file函式意義相同,指定日誌檔案的開啟模式,'w'或'a'
format: 指定輸出的格式和內容,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: 列印日誌資訊
datefmt: 指定時間格式,同time.strftime()
level: 設定日誌級別,預設為logging.WARNING
stream: 指定將日誌的輸出流,可以指定輸出到sys.stderr,sys.stdout或者檔案,預設輸出到sys.stderr,當stream和filename同時指定時,stream被忽略

3.將日誌同時輸出到檔案和螢幕

import logging

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='myapp.log',
                filemode='w')

#################################################################################################
#定義一個StreamHandler,將INFO級別或更高的日誌資訊列印到標準錯誤,並將其新增到當前的日誌處理物件#
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
#################################################################################################

logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

螢幕上列印:
root        : INFO     This is info message
root        : WARNING  This is warning message

./myapp.log檔案中內容為:
Sun, 24 May 2009 21:48:54 demo2.py[line:11] DEBUG This is debug message
Sun, 24 May 2009 21:48:54 demo2.py[line:12] INFO This is info message
Sun, 24 May 2009 21:48:54 demo2.py[line:13] WARNING This is warning message

4.logging之日誌回滾

import logging
from logging.handlers import RotatingFileHandler

#################################################################################################
#定義一個RotatingFileHandler,最多備份5個日誌檔案,每個日誌檔案最大10M
Rthandler = RotatingFileHandler('myapp.log', maxBytes=10*1024*1024,backupCount=5)
Rthandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
Rthandler.setFormatter(formatter)
logging.getLogger('').addHandler(Rthandler)
################################################################################################

從上例和本例可以看出,logging有一個日誌處理的主物件,其它處理方式都是透過addHandler新增進去的。
logging的幾種handle方式如下:

 

logging.StreamHandler: 日誌輸出到流,可以是sys.stderr、sys.stdout或者檔案
logging.FileHandler: 日誌輸出到檔案

日誌回滾方式,實際使用時用RotatingFileHandler和TimedRotatingFileHandler
logging.handlers.BaseRotatingHandler
logging.handlers.RotatingFileHandler
logging.handlers.TimedRotatingFileHandler

logging.handlers.SocketHandler: 遠端輸出日誌到TCP/IP sockets
logging.handlers.DatagramHandler:  遠端輸出日誌到UDP sockets
logging.handlers.SMTPHandler:  遠端輸出日誌到郵件地址
logging.handlers.SysLogHandler: 日誌輸出到syslog
logging.handlers.NTEventLogHandler: 遠端輸出日誌到Windows NT/2000/XP的事件日誌
logging.handlers.MemoryHandler: 日誌輸出到記憶體中的制定buffer
logging.handlers.HTTPHandler: 透過"GET"或"POST"遠端輸出到HTTP伺服器

 

由於StreamHandler和FileHandler是常用的日誌處理方式,所以直接包含在logging模組中,而其他方式則包含在logging.handlers模組中,
上述其它處理方式的使用請參見python2.5手冊!

5.透過logging.config模組配置日誌

#logger.conf

###############################################

[loggers]
keys=root,example01,example02

[logger_root]
level=DEBUG
handlers=hand01,hand02

[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0

[logger_example02]
handlers=hand01,hand03
qualname=example02
propagate=0

###############################################

[handlers]
keys=hand01,hand02,hand03

[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('myapp.log', 'a')

[handler_hand03]
class=handlers.RotatingFileHandler
level=INFO
formatter=form02
args=('myapp.log', 'a', 10*1024*1024, 5)

###############################################

[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
datefmt=%a, %d %b %Y %H:%M:%S

[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)s
datefmt=

上例3:

import logging
import logging.config

logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example01")

logger.debug('This is debug message')
logger.info('This is info message')
logger.warning('This is warning message')

上例4:

import logging
import logging.config

logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example02")

logger.debug('This is debug message')
logger.info('This is info message')
logger.warning('This is warning message')

6.logging是執行緒安全的

from:http://blog.csdn/yatere/article/details/6655445

原文地址:

一、Logging簡介

Logging是一種當軟體執行時對事件的追蹤記錄方式,軟體開發者透過在程式碼中呼叫Logging的相關方法來提示某些事件的發生。事件可以透過描述資訊描述,當然描述資訊中也可以包含變數,因為對於事件的每次觸發,描述資訊可能不同。

二、簡單的例子

一個簡單的例子:

import logging
logging.warning('Watch out!')  # 資訊會列印到控制檯
logging.info('I told you so')  # 不會列印任何資訊,因為預設級別高於info 

如果你將上述程式碼存入檔案,然後執行:

WARNING:root:Watch out! 

INFO的資訊沒有出現在控制檯,因為預設的級別為WARNING高於INFO。日誌資訊包含日誌級別和事件描述資訊,暫且別太在意輸出中的root,稍後會有介紹。實際的輸出可以讓你任意的定製,格式設定會在稍後介紹。

三、將日誌資訊存入檔案

在應用中我們常常需要將日誌資訊存入檔案。請重新建立一個新檔案,不要接在上面的檔案中。

import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too') 

執行他,然後會生成一個日誌檔案example.log,開啟它就能看到具體的日誌資訊:

DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too 

在這個例子中,我們看到了如何設定日誌級別,這是一個閾值,用於控制日誌的輸出。
如果你想要透過命令列來設定日誌級別,你可以這樣做:

--log=INFO 

並且 你也可以獲取傳遞給–log的引數,你可以這樣做:

getattr(logging, loglevel.upper()) 

你可以透過basicConfig()方法來設定日誌級別——傳遞level引數。你可能想要檢查level引數值的合法性,可以像下面這樣:

# assuming loglevel is bound to the string value obtained from the
# command line argument. Convert to upper case to allow the user to
# specify --log=DEBUG or --log=debug
numeric_level = getattr(logging, loglevel.upper(), None)
if not isinstance(numeric_level, int):
    raise ValueError('Invalid log level: %s' % loglevel)
logging.basicConfig(level=numeric_level, ...) 

basicConfig()方法的呼叫先於debug(),info()等方法。因為它是一次性的工作:第一次呼叫是有效的,後面的呼叫都是無效的空操作。

如果你多次執行上面的程式碼,日誌資訊會追加到原有的日誌資訊上。如果你想要每次的日誌資訊都覆蓋掉之前的,那麼可以透過配置filemode引數為’w’即可:

logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG) 

新的日誌資訊會覆蓋掉舊的。

四、多模組Logging

如果你的工程包含多個模組,你可以像下面的這種方式組織logging:

# myapp.py
import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main() 

# mylib.py
import logging

def do_something():
    logging.info('Doing something') 

如果你執行myapp.py,你會在myqpp.log中看到如下資訊:

INFO:root:Started
INFO:root:Doing something
INFO:root:Finished 

這正是你想要看到的。你可以將他們組織到你的多個模組中,透過使用mylib.py的模板。注意:使用這種方式,除了透過檢視事件描述,你不能判斷這個資訊從何而來。如果你想要追蹤資訊來源,你需要參照更加高階的教程-

五、Logging變數資訊

為了生成包含變數的日誌,你需要使用格式化的字串,透過將變數當成引數傳遞給描述資訊,例如:

import logging
logging.warning('%s before you %s', 'Look', 'leap!') 

會生成:

WARNING:root:Look before you leap! 

正如你看到的,透過使用格式化字元創將變數合併到描述資訊中。這種方式是向後相容的:logging包中有更新的格式化可選方法,例如str.format() and string.Template。這些新的格式化方法都是支援的,但是研究它們的使用不在本文的討論範圍內。

六、修改顯示日誌資訊的格式

你可以更改顯示日誌資訊的格式,像這樣:

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too') 

執行程式碼會列印出:

DEBUG:This message should appear on the console
INFO:So should this
WARNING:And this, too 

注意到沒有?先前出現在日誌資訊中的root不見了!你可以透過格式化方式生成幾乎全部的東西,這部分內容你可以參考LogRecord的文件。但是對於簡單的應用,你只需要知道日誌級別,日誌資訊(包含變數的日誌資訊),或者再加上事件的發生時間。這些將在下一節中講到。

七、在日誌資訊中顯示日期時間

為了在日誌資訊中顯示日期時間,你需要使用%(asctime)s格式字串。例如:

import logging
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.') 

執行會生成:

2010-12-12 11:41:42,612 is when this event was logged. 

預設的日期時間顯示標準是ISO8601。如果你想要定製自己的格式,可以透過傳遞引數datefmt給basicConfig()方法,如下:

import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.') 

會生成:

12/12/2010 11:46:36 AM is when this event was logged. 

datefmt引數的格式和是相似的。

以上是Logging 的基礎教程,如果你的需求比較簡單,上面介紹的用法應該能夠滿足你的需求。

如果想更深入瞭解Logging模組請轉到Logging高階教程。

常用handlers的使用

一、StreamHandler

流handler——包含在logging模組中的三個handler之一。

能夠將日誌資訊輸出到sys.stdout, sys.stderr 或者類檔案物件(更確切點,就是能夠支援write()和flush()方法的物件)。

只有一個引數:

class logging.StreamHandler(stream=None) 

日誌資訊會輸出到指定的stream中,如果stream為空則預設輸出到sys.stderr。

二、FileHandler

logging模組自帶的三個handler之一。繼承自StreamHandler。將日誌資訊輸出到磁碟檔案上。

構造引數:

class logging.FileHandler(filename, mode='a', encoding=None, delay=False) 

模式預設為append,delay為true時,檔案直到emit方法被執行才會開啟。預設情況下,日誌檔案可以無限增大。

三、NullHandler

空操作handler,logging模組自帶的三個handler之一。
沒有引數。

四、WatchedFileHandler

位於logging.handlers模組中。用於監視檔案的狀態,如果檔案被改變了,那麼就關閉當前流,重新開啟檔案,建立一個新的流。由於newsyslog或者logrotate的使用會導致檔案改變。這個handler是專門為/unix系統設計的,因為在windows系統下,正在被開啟的檔案是不會被改變的。
引數和FileHandler相同:

class logging.handlers.WatchedFileHandler(filename, mode='a', encoding=None, delay=False) 

五、RotatingFileHandler

位於logging.handlers支援迴圈日誌檔案。

class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0) 

引數maxBytes和backupCount允許日誌檔案在達到maxBytes時rollover.當檔案大小達到或者超過maxBytes時,就會新建立一個日誌檔案。上述的這兩個引數任一一個為0時,rollover都不會發生。也就是就檔案沒有maxBytes限制。backupcount是備份數目,也就是最多能有多少個備份。命名會在日誌的base_name後面加上.0-.n的字尾,如example.log.1,example.log.1,…,example.log.10。當前使用的日誌檔案為base_name.log。

六、TimedRotatingFileHandler

定時迴圈日誌handler,位於logging.handlers,支援定時生成新日誌檔案。

class logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False) 

引數when決定了時間間隔的型別,引數interval決定了多少的時間間隔。如when=‘D’,interval=2,就是指兩天的時間間隔,backupCount決定了能留幾個日誌檔案。超過數量就會丟棄掉老的日誌檔案。

when的引數決定了時間間隔的型別。兩者之間的關係如下:

 'S'         |  秒

 'M'         |  分

 'H'         |  時

 'D'         |  天

 'W0'-'W6'   |  週一至週日

 'midnight'  |  每天的凌晨 

utc參數列示UTC時間。

七、其他handler——SocketHandler、DatagramHandler、SysLogHandler、NtEventHandler、SMTPHandler、MemoryHandler、HTTPHandler

這些handler都不怎麼常用,所以具體介紹就請參考官方文件

下面使用簡單的例子來演示handler的使用:

例子一——不使用配置檔案的方式(StreamHandler):

import logging

# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    datefmt='%m-%d %H:%M',
                    filename='/temp/myapp.log',
                    filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
# 
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
#設定格式
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
#告訴handler使用這個格式
console.setFormatter(formatter)
# add the handler to the root logger
#為root logger新增handler
logging.getLogger('').addHandler(console)

# Now, we can log to the root logger, or any other logger. First the root...
#預設使用的是root logger
logging.info('Jackdaws love my big sphinx of quartz.')

# Now, define a couple of other loggers which might represent areas in your
# application:

logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')

logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.') 

輸出到控制檯的結果:

root        : INFO     Jackdaws love my big sphinx of quartz.
myapp.area1 : INFO     How quickly daft jumping zebras vex.
myapp.area2 : WARNING  Jail zesty vixen who grabbed pay from quack.
myapp.area2 : ERROR    The five boxing wizards jump quickly. 

例子二——使用配置檔案的方式(TimedRotatingFileHandler) :

log.conf 日誌配置檔案:

[loggers]
keys=root,test.subtest,test

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=INFO
handlers=consoleHandler,fileHandler

[logger_test]
level=INFO
handlers=consoleHandler,fileHandler
qualname=tornado
propagate=0

[logger_test.subtest]
level=INFO
handlers=consoleHandler,fileHandler
qualname=rocket.raccoon
propagate=0

[handler_consoleHandler] #輸出到控制檯的handler
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler] #輸出到日誌檔案的handler
class=logging.handlers.TimedRotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=('rocket_raccoon_log','midnight')

[formatter_simpleFormatter]
format=[%(asctime)s-%(name)s(%(levelname)s)%(filename)s:%(lineno)d]%(message)s
datefmt=

logging.config.fileConfig('conf/log.conf')
logger = getLogging() 

獲取logger方法:

def getLogging():
    return logging.getLogger("test.subtest") 

配置logger並且呼叫:

logging.config.fileConfig('conf/log.conf')
logger = getLogging()
logger.info("this is an example!") 

控制檯和日誌檔案中都會輸出:

[2016-07-01 09:22:06,470-test.subtest(INFO)main.py:55]this is an example! 

模組中的logging模組的handlers大致介紹就是這樣。

在配置檔案中為Logger配置多個handler

使用樣例

讀取配置檔案:

logging.config.fileConfig("log.conf")    # 採用配置檔案 

建立logger:

logger = logging.getLogger("simpleExample") 

log.conf檔案:

[loggers] #loggers列表
keys=root,main

[handlers] #handlers列表
keys=consoleHandler,fileHandler

[formatters] #formatters列表
keys=fmt

[logger_root] #root logger
level=DEBUG
handlers=consoleHandler,fileHandler #將root logger的日誌資訊輸出到檔案和控制檯

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

[handler_consoleHandler] #控制檯handler
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,) #引數是RotatingFileHandler的__init__()的引數

[formatter_fmt] #格式
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt= 

上述檔案中,用逗號將handler隔開就可以將日誌輸出到多個目的地:

handlers=consoleHandler,fileHandler #將root logger的日誌資訊輸出到檔案和控制檯 
=========================================================================================================

參考:

http://blog.csdn/yypsober/article/details/51775787

http://blog.csdn/yypsober/article/details/51782281

http://blog.csdn.net/yypsober/article/details/51800120

http://blog.csdn.net/yypsober/article/details/50832754

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29519108/viewspace-2137835/,如需轉載,請註明出處,否則將追究法律責任。

相關文章