小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

python的logging模塊【zz】

 londonKu 2012-11-23

如果使用Python寫一個比較大型的程序,你一定會用上日志系統(tǒng)。特別是Python這樣的動態(tài)語言,很多錯誤都只能在運行的時候才能發(fā)現(xiàn),一個好的日志系統(tǒng)對于Python程序相當重要。最簡單的解決方案當然是直接使用print輸出運行信息。但是這樣太簡單了,沒有分級功能,如果在發(fā)布的時候想去掉調(diào)試用的運行信息還得找出所有的print語句進行修改。再者,print只能輸出到控制臺,想要輸出到文件或者通過電子郵件發(fā)送到其他地方,一個print語句就沒辦法解決了。

通過使用Python的日志系統(tǒng),就可以解決以上問題。
首先看一下這個示例:
import logging
LOG=logging.getLogger(’應(yīng)用程序名’)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
LOG.addHandler(console)
LOG.debug(’調(diào)試信息’)
LOG.info(’有用的信息’)
LOG.warning(’警告信息’)
LOG.error(’錯誤信息’)
LOG.critical(’嚴重錯誤信息’)
上面的代碼想控制臺輸出了五種錯誤信息。分為五個從低到高的級別,從DEBUG到CRITICAL。此外,我們還指定了程序輸出的級別,只有INFO級別以上的信息才會被輸出。
這就是日志系統(tǒng)最常用的使用方法。這段代碼中有兩個概念可以幫助我們更進一步使用Python的日志系統(tǒng):
1.        “Logger”。每個程序在輸出信息之前都要獲得一個Logger。Logger通常對應(yīng)了程序的模塊名,比如聊天工具的圖形界面模塊可以這樣獲得它的Logger:
LOG=logging.getLogger(”chat.gui”)
而核心模塊可以這樣:
LOG=logging.getLogger(”chat.kernel”)
我們接下來可以看到使用這種命名方法的用途。
2.        “Handler”。用于處理程序的輸出。Python的日志系統(tǒng)有多種Handler可以使用。有些Handler可以把信息輸出到控制臺,有些Logger可以把信息輸出到文件,還有些Handler可以把信息發(fā)送到網(wǎng)絡(luò)上。如果覺得不夠用,還可以編寫自己的Handler。
所有的Handler可以支持三個操作:
1.      設(shè)置輸出格式。比如設(shè)置輸出的信息中包含時間和級別信息:
LOG=logging.getLogger(”chat.gui”)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter(’%(asctime)s %(levelname)s %(message)s’)
console.setFormatter(formatter)
LOG.addHandler(console)
熟悉Python的朋友應(yīng)該會發(fā)現(xiàn),logging.Formatter的參數(shù)實際上只是Python常用的“%”字符串格式化。它使用“%(name)s”表示占位符。下面是一個完整的表格,展示了日志系統(tǒng)可以輸出的各種信息:

%(name)s

Logger的名字

%(levelno)s

數(shù)字形式的日志級別

%(levelname)s

文本形式的日志級別

%(pathname)s

調(diào)用日志輸出函數(shù)的模塊的完整路徑名,可能沒有

%(filename)s

調(diào)用日志輸出函數(shù)的模塊的文件名

%(module)s

調(diào)用日志輸出函數(shù)的模塊名

%(funcName)s

調(diào)用日志輸出函數(shù)的函數(shù)名

%(lineno)d

調(diào)用日志輸出函數(shù)的語句所在的代碼行

%(created)f

當前時間,用UNIX標準的表示時間的浮點數(shù)表示

%(relativeCreated)d

輸出日志信息時的,自Logger創(chuàng)建以來的毫秒數(shù)

%(asctime)s

字符串形式的當前時間。默認格式是“2003-07-08 16:49:45,896”。逗號后面的是毫秒

%(thread)d

線程ID??赡軟]有

%(threadName)s

線程名。可能沒有

%(process)d

進程ID。可能沒有

%(message)s

用戶輸出的消息

2.      設(shè)置輸出級別
在上面我們已經(jīng)演示了如何設(shè)置輸出級別了。除了Python內(nèi)置的五種級別,我們還可以自定義輸出級別。
TODO 子定義輸出級別
3.      設(shè)置過濾器
細心的朋友一定會發(fā)現(xiàn)前文調(diào)用logging.getLogger()時參數(shù)的格式類似于“A.B.C”。采取這樣的格式其實就是為了可以配置過濾器??匆幌逻@段代碼:
LOG=logging.getLogger(”chat.gui.statistic”)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter(’%(asctime)s %(levelname)s %(message)s’)
console.setFormatter(formatter)
filter=logging.Filter(”chat.gui”)
console.addFilter(filter)
LOG.addHandler(console)
和前面不同的是我們在Handler上添加了一個過濾器?,F(xiàn)在我們輸出日志信息的時候就會經(jīng)過過濾器的處理。名為“A.B”的過濾器只讓名字帶有“A.B”前綴的Logger輸出信息??梢蕴砑佣鄠€過濾器,只要有一個過濾器拒絕,日志信息就不會被輸出。另外,在Logger中也可以添加過濾器。
每個Logger可以附加多個Handler。接下來我們就來介紹一些常用的Handler:
1)        logging.StreamHandler
使用這個Handler可以向類似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息。它的構(gòu)造函數(shù)是:
StreamHandler([strm])
其中strm參數(shù)是一個文件對象。默認是sys.stderr
2)    2.logging.FileHandler
和StreamHandler類似,用于向一個文件輸出日志信息。不過FileHandler會幫你打開這個文件。它的構(gòu)造函數(shù)是:
FileHandler(filename[,mode])
filename是文件名,必須指定一個文件名。
mode是文件的打開方式。參見Python內(nèi)置函數(shù)open()的用法。默認是’a’,即添加到文件末尾。
3)    3.logging.handlers.RotatingFileHandler
這個Handler類似于上面的FileHandler,但是它可以管理文件大小。當文件達到一定大小之后,它會自動將當前日志文件改名,然后創(chuàng)建一個新的同名日志文件繼續(xù)輸出。比如日志文件是chat.log。當chat.log達到指定的大小之后,RotatingFileHandler自動把文件改名為chat.log.1。不過,如果chat.log.1已經(jīng)存在,會先把chat.log.1重命名為chat.log.2。。。最后重新創(chuàng)建chat.log,繼續(xù)輸出日志信息。它的構(gòu)造函數(shù)是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode兩個參數(shù)和FileHandler一樣。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes為0,意味著日志文件可以無限大,這時上面描述的重命名過程就不會發(fā)生。
backupCount用于指定保留的備份文件的個數(shù)。比如,如果指定為2,當上面描述的重命名過程發(fā)生時,原有的chat.log.2并不會被更名,而是被刪除。
4)    4.logging.handlers.TimedRotatingFileHandler
這個Handler和RotatingFileHandler類似,不過,它沒有通過判斷文件大小來決定何時重新創(chuàng)建日志文件,而是間隔一定時間就自動創(chuàng)建新的日志文件。重命名的過程與RotatingFileHandler類似,不過新的文件不是附加數(shù)字,而是當前時間。它的構(gòu)造函數(shù)是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename參數(shù)和backupCount參數(shù)和RotatingFileHandler具有相同的意義。
interval是時間間隔。
when參數(shù)是一個字符串。表示時間間隔的單位,不區(qū)分大小寫。它有以下取值:
S 秒
M 分
H 小時
D 天
W 每星期(interval==0時代表星期一)
midnight 每天凌晨
5)    5.logging.handlers.SocketHandler
6)    […]

6:00 PM | Read comments (1) | Permalink | python

python 日志打印[zz]

python 日志打印

發(fā)現(xiàn)python里面擴展了日志打印功能。感覺比java自帶的還好,和log4j很類似。
下面總結(jié)下其用法。先說一種不用配置文件的:
<log.py>

1# -*- coding: gb2312 -*-
2import logging
3
4logging.basicConfig(level=logging.INFO,
5                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
6                    datefmt='%m-%d %H:%M',
7                    filename='./AutoUpdate.log',
8                    filemode='w')
9
10console = logging.StreamHandler()
11console.setLevel(logging.INFO)
12formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
13console.setFormatter(formatter)
14logging.getLogger('').addHandler(console)
15
16
17## 
18# console = logging.StreamHandler()
19# console = setLevel(logging.DEBUG)
20# formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
21# console.setFormatter(formatter)
22# logging.getLogger('').addHandler(console)
23
24
25def getLogging(name):
26 return logging.getLogger(name)

<test.py>

import log

testlog = log.getLogging('test')
testlog.error( "~~~~~~~~~~~~~~test1.")
testlog.info( "~~~~~~~~~~~~~~test2." )
testlog.exception( "~~~~~~~~~~~~~~~~~~~~~~~~~test3.")

用過log4j的人不會陌生這種用法。如果你對log4j有疑惑,或者想了解請在本人blog內(nèi)查找關(guān)于log4j的文章。有詳細介紹。這里不再贅述。
第二種使用配置文件的:

# logging.conf

[loggers]
keys=root,example

[handlers]
keys=consoleHandler,rotateFileHandler

[formatters]
keys=simpleFormatter

[formatter_simpleFormatter]
format=[%(asctime)s](%(levelname)s)%(name)s : %(message)s

[logger_root]
level=DEBUG
handlers=consoleHandler,rotateFileHandler

[logger_example]
level=DEBUG
handlers=consoleHandler,rotateFileHandler
qualname=example
propagate=0

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

[handler_rotateFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=('test.log', 'a', 10000, 9)

<test2.py>

import logging
import logging.config

logging.config.fileConfig("logger.conf")

#create logger
logger = logging.getLogger("example")

#"application" code
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")

logHello = logging.getLogger("hello")
logHello.info("Hello world!")

其中值得注意的是args的含義。

5:59 PM | Read comments (3) | Permalink | python

使用Python的logging.config[zz]

使用Python的logging.config
Python的logging模塊接口仿log4j,概念上一致,使用上相當方便。
利用logging.config.fileConfig(),可以將日志的配置用文件來描述,簡化了日志的初始化。
例程:

# test.py
import logging
import logging.config
logging.config.fileConfig("logging.conf")
#create logger
logger = logging.getLogger("example")
#"application" code
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
logHello = logging.getLogger("hello")
logHello.info("Hello world!")

配置文件示例如下:

# logging.conf
[loggers]
keys=root,example
[handlers]
keys=consoleHandler,rotateFileHandler
[formatters]
keys=simpleFormatter
[formatter_simpleFormatter]
format=[%(asctime)s](%(levelname)s)%(name)s : %(message)s
[logger_root]
level=DEBUG
handlers=consoleHandler,rotateFileHandler
[logger_example]
level=DEBUG
handlers=consoleHandler,rotateFileHandler
qualname=example
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_rotateFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=('test.log', 'a', 200000, 9)

注意,RotatingFileHandler中doRollover()會因為rename()出錯而中途退出,造成日志文件沒有打開,并且后繼的日志消息都因為日志文件沒有打開而失敗??梢宰约涸趓ename()處加上try,或者不用RotatingFileHandler。估計隔一段時間就fileConfig()一次也是可以恢復正常。
詳見:Python logging RotatingFileHandler bug
該錯誤僅當日志文件滿時切換文件時才可能發(fā)生,當文件被鎖定時才會出錯。正常使用不會有問題,并且日志出錯不會影響主程序的運行。所以可以放心使用,想再可靠點就直接在源碼中加個try.
(轉(zhuǎn)載請注明來源于金慶的專欄)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多