1.1简介
日志记录是一个跟踪软件运行情况行之有效的方法。软件开发者通过添加日志来表明某些事件已经发生了。一个事件可由一个可描述性信息来进行描述,这些信息可以包含可变的数据(即数据在事件中每次出现值都有所不同)。事件也有一个重要性等级,这个等级是由开发人员进行认定的;这个重要性通常被称为等级或严重级别。
1.2何时使用日志
Logging模块为方便我们使用提供了一组便利的方法。它们是debug(),info(),warning(),error()和critical()。要决定何时使用logging日志,可以参考下面的表格,对于每组常见的任务,哪个工具是最适合它的。
你想要执行的任务 | 适合的工具 |
---|---|
为了查看是否正常使用了命令行脚本或程序,将输出显示到控制台上 | print() |
显示一个程序正常操作发生的事件(例如:用于状态监控或故障调查) | logging.info()(或者logging.debug()——输出非常详细的信息用于诊断程序) |
对运行时一些特定事件进行警告 | warnings.warn()——如果可以通过修改客户端代码来避免的错误;logging.warn()——如果不能通过修改客户端代码来避免的错误,但是该事件还是需要注意的,例如:磁盘空间不足 |
提示有关特定运行时事件的错误 | 抛出一个异常,raise Exception |
在不引发异常的情况下抑制错误 | logging.error(),logging.exception()或者logging.critical(),这些方法适用于特定的错误和应用程序域 |
这些logging的方法是根据它们用于跟踪事件的严重等级进行命名的。标准的等级和它们的适用性描述如下:
等级 | 何时使用 |
---|---|
DEBUG | 详细的信息,通常只有在诊断程序时使用 |
INFO | 确认程序按照预期一样在工作 |
WARNING | 表明发生了一些意外情况,或者在将来会发生一些问题(例如:磁盘满了)。程序还是如预期一样工作 |
ERROR | 由于一些严重的问题,软件某些功能不能正常执行 |
CRITICAL | 一个严重的错误导致程序它不能继续运行下去了 |
Logging模块默认的级别是WARNING,这就意味,只有WARNING和比它更高等级的方法才会被追踪,除非对logging模块进行配置。
被追踪的事件可以通过不同的方式进行处理。最简单的处理方式就是将追踪事件的信息打印到控制台。另一种通常的做法就是将它们写入到磁盘文件中。
1.3一个简单的例子
一个很简单的例子:
import logging
logging的默认等级为WARNING,只有等级高于WARNING的才会输出
logging.warning('This is a warning.') # 将打印到控制台
logging.info('This is a info.') # 不会有任何的输出
如果你输入了以上的脚本然后运行它,你会看到如下的输出:
WARNING:root:This is a warning.
之所以info的信息没有打印出来,是因为默认等级是WARNING。这打印出来的信息包含该信息所代表的等级,和对该事件信息的描述。当前可以暂时忽略root,这个会在进阶中进行解释。如果需要,可以非常灵活的格式化输出信息。这个会在后面讲到。
1.4将日志写入文件
将日志事件记录到文件中是一个很常见的情形,让我们接下来看看该如何实现。首先将以下的脚本放入到新打开的Python脚本中(原因后面说),不要在上面的会话中执行以下的代码,会没有效果的,代码如下:
import logging
LOGGING_FILE ='tutorial.log'
logging.basicConfig(filename=LOGGING_FILE, level=logging.DEBUG)
logging.debug('This message should go to the log file.')
logging.info('So should this.')
logging.warning('And this, too.')
运行脚本后,我们会发现,filename参数指定的位置有个tutorial.log生成了,上面的例子会在脚本同级目录生成tutorial.log文件。你可以看看文件中都有些什么,我的文件有以下信息:
DEBUG:root:This message should go to the log file.
INFO:root:So should this.
WARNING:root:And this, too.
上面的例子同样展示了如何设置默认的跟踪等级。在这个例子中,我把默认的跟踪等级设置为DEBUG,因为DEBUG等级最低,所以会将所有的跟踪事件都输出到文件中了。
值得注意的是,basicConfig()函数需要在任一logging函数(例如debug(),info())之前被调用。因为它是一个一次性的简单配置函数,只有在第一个调用时才会起作用:放到后面调用会没有任何作用。
如果你对上面的脚本反复运行几次,这些运行成功的信息会追加到tutorial.log文件后面。如果你想每次运行时刷新文件,不需要去记忆之前运行的信息,你可以通过指定filemode参数。将上面的代码进行修改:
logging.basicConfig(filename=LOGGING_FILE, filemode='w', level=logging.DEBUG)
输出的信息还是和之前一样,但是日志文件不再是追加,所以之前运行的信息丢失了。
1.5记录变量日志
想要记录变量的日志,我们在描述事件的信息中使用一个格式化的字符串进行占位,然后将变量作为参数传递给函数。例子如下:
import logging
logging.warning('%s before you %s', 'Look', 'leap!')
执行结果如下:
WARNING:root:Look before you leap!
正如你所看见的,将可变数据合并到事件描述信息中使用的就是旧的%-type格式字符串。这是为了向后兼容,logging包已经提前更新了格式化的选项例如str.format()和string.Template。详细说明可参见:Using particular formatting styles throughout your application
1.6更改显示信息的格式
想要改变输出信息的格式,你需要指定你想要使用的格式:
import logging
logging.basicConfig(format='%(levelname)s%(message)s', level=logging.DEBUG)
logging.debug('This message should go to the log file.')
logging.info('So should this.')
logging.warning('And this, too.')
显示如下:
DEBUG:This message should go to the log file.
INFO:So should this.
WARNING:And this, too.
可以看到之前出现的“root”现在消失了。对于可以出现格式字符串中的一整套内容,你可以参考这个文档LogRecord attributes。
如果你只是想简单的使用logging的格式化,或许你只需要三个元素:level(等级),message(跟踪的信息 )和asctime(事件发生的时间)。
1.7如何显示事件发生的时间
如果想要显示发生事件的时间,你需要在你的格式化字符串中使用“%(asctime)s”。
import logging
logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('is when this event was logged.')
控制台显示如下:
2018-08-07 08:31:30,205 is when this event was logged.
这默认时间的格式看起来像ISO8601或者RFC 3339。如果需要设置自己想要的日期格式,你需要向basicConfig添加一个日期格式化参数,例如:
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
logging.warning('is when this event was logged.')
运行脚本后显示如下:
2018-08-07 08:36:04 is when this event was logged.
日期格式参数(datefmt)所支持的参数格式与time.strftime()函数所支持的一致。
网友评论