Py学习  »  翻译

[翻译]Python Logging HOWTO

Py站长 • 10 年前 • 6549 次点击  

翻译原文:http://docs.python.org/2/howto/logging.html 略有删减。

基本的Logging教程

程序日志logging是对程序运行时的一些事件进行记录的一种方法。程序员通常调用 logging calls 来标明事件的发生。事件消息包含了程序运行当时的一些变量数据,并且,他还包含了事件本身的重要程度信息,这个重要程度,我们称之为 Level。

一个简单的例子

例子如下:

import logging
logging.warning('Watch out!')#打印一条消息到控制台
logging.info('I told you so')#什么都不会打印

将上述代码写到脚本中并运行,可以看到

WARNING:root:Watch out!

打印到控制台中。由于默认的级别是WARNING,所以INFO消息并没有出现。打印出的消息包括,级别、logging调用中事件的描述,即’Watch out!’。目前暂不关心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')

现在打开文件,就可以看到如下日志记录:

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

上面的代码还给出了如何设置作跟踪阈值用的日志级别。这里由于阈值是DEBUG,所以所有的消息都打印出来了。

如果你想通过类似下面的命令行选项来设置日志级别:

--log=INFO

并且,传递给--log的参数存储在变量loglevel中,可以使用:

getattr(logging, loglevel.upper())

来获取传给函数basicConfig()的参数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()等的调用。由于这种简单配置是一次性的,所以只有第一次调用是有效的,之后的调用则是无效的。

将上面的脚本运行多次后,产生的日志记录都会附加到文件example.log中。如果每次运行都重新开始记录,而不记录之前运行的日志,可以设置filemode参数。修改后如下:

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

这里产生的日志跟之前是一样的,但是日志记录不再是附加到文件中,所以之前的记录都丢失了。

日志来自多个模块

如果程序由多个模块构成,下面的例子给出了如何组织日志:

myapp.py 文件:

# 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文件:

# mylib.py
import logging

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

运行myapp.py,将会在文件myapp.log中看到:

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

而这正是望看到的。mylib.py中使用的方法可以扩展到多个模块的情形。注意,使用这种方法,并不能获知消息来自源码的哪里,除了对事件描述进行对比。如果想跟踪消息的来源,请参见 Advanced Logging Tutorial.

记录数据变量

为了记录数据变量,可以对事件描述信息进行格式化,并将变量作为格式化参数。例如:

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

将会输出:

WARNING:root:Look before you leap!

这里使用了%字符串格式化风格将数据变量合并到了事件描述信息中。这种做法是出于向后兼容考虑:日志包提供了更新的格式化选项str.format()和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 attributes,但是在简单应用中,通产只需要levelname,message(事件描述,包括数据变量),以及事件发生的时间。

显示消息的时间/日期

在格式化字符串中添加%(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。如果需要对日期/时间格式作更多的控制,可以对函数basicConfig的参数datefmt赋值,如下:

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()支持的格式一致。

下一步

前面给出了一些基本的操作。如果日志需求比较简单,完全可以结合上面给出的例子在自己的脚本使用。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/95
 
6549 次点击  
文章 [ 3 ]  |  最新文章 9 年前
Py站长
Reply   •   1 楼
Py站长    9 年前

@LYcSon 好滴,:)

LYcSon
Reply   •   2 楼
LYcSon    9 年前

呃,恐怕不是“略”有删减。

最重要的后面的高级教程部分,可能大家更需要呢。:-)

djangolover
Reply   •   3 楼
djangolover    10 年前

在我的小项目中试试看~