晚上比較懶,直接搬磚了。
1.簡單的將日志打印到屏幕
|
默認情況下,logging將日志打印到屏幕,日志級別為WARNING;
日志級別大小關系為:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,當然也可以自己定義日志級別。
2.通過logging.basicConfig函數對日志的輸出格式及方式做相關配置
|
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.將日志同時輸出到文件和屏幕
|
4.logging之日志回滾
|
從上例和本例可以看出,logging有一個日志處理的主對象,其它處理方式都是通過addHandler添加進去的。
logging的幾種handle方式如下:
logging.StreamHandler: 日志輸出到流,可以是sys.stderr、sys.stdout或者文件 日志回滾方式,實際使用時用RotatingFileHandler和TimedRotatingFileHandler logging.handlers.SocketHandler: 遠程輸出日志到TCP/IP sockets |
由于StreamHandler和FileHandler是常用的日志處理方式,所以直接包含在logging模塊中,而其他方式則包含在logging.handlers模塊中,
上述其它處理方式的使用請參見python2.5手冊!
5.通過logging.config模塊配置日志
|
上例3:
|
上例4:
|
6.logging是線程安全的
from:http://blog.csdn.NET/yatere/article/details/6655445
原文地址:Python 模塊 Logging HOWTO 官方文檔
一、Logging簡介
Logging是一種當軟件運行時對事件的追蹤記錄方式,軟件開發者通過在代碼中調用Logging的相關方法來提示某些事件的發生。事件可以通過描述信息描述,當然描述信息中也可以包含變量,因為對于事件的每次觸發,描述信息可能不同。
二、簡單的例子
一個簡單的例子:
import logging
logging.warning('Watch out!') # 信息會打印到控制臺
logging.info('I told you so') # 不會打印任何信息,因為默認級別高于info
如果你將上述代碼存入Python文件,然后運行:
WARNING:root:Watch out!
INFO的信息沒有出現在控制臺,因為默認的級別為WARNING高于INFO。日志信息包含日志級別和事件描述信息,暫且別太在意輸出中的root,稍后會有介紹。實際的輸出可以讓你任意的定制,格式設置會在稍后介紹。
三、將日志信息存入文件
在應用中我們常常需要將日志信息存入文件。請重新創建一個新文件,不要接在上面的Python文件中。
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進階
五、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參數的格式和time.strftime()是相似的。
以上是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是專門為Linux/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都不怎么常用,所以具體介紹就請參考官方文檔 其他handlers
下面使用簡單的例子來演示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!
Python 模塊中的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.NET/yypsober/article/details/51775787
http://blog.csdn.net/yypsober/article/details/51782281
http://blog.csdn.Net/yypsober/article/details/51800120
http://blog.csdn.net/yypsober/article/details/50832754
文章列表