内容简介:在看点这里
在《 后端问题如何快速定位? 》中老张强调了日志的重要性,也提到了使用日志需要的注意的一些问题。但是并没有提到实践方式,其实掌握一个 工具 最快的方法就是阅读官方文档,老张试着翻译了 Python 3.8官方Logging文档,由于官方文档实在是长,所以会分成两到三篇文章。官方文档给出了非常详细的设计思想、实践方式,相信你读完肯定会非常受用。
日志是用来的记录程序运行事件的工具。当 程序员 可以通过添加日志打印的代码来记录程序运行过程中发生的某些事件时。这些事件包含了诸如变量数据在内的描述信息,当然也包括开发人员认为重要的诸如日志级别等信息。
什么时候使用Loggin包
针对简单的场景,Loggin包提供了一系列方便的函数。其中包括debug()、info()、warning()、error()以及 critical()。下面的表格列举了什么函数适用于什么场景。
需求场景 |
适用工具 |
---|---|
在命令行场景下,需要在控制台打印输出信息 |
print() |
需要记录一些程序正常运行的事件信息(例如运行状态或者调试信息) |
logging.info() (为了记录非常详细的调试信息也可以使用 logging.debug() ) |
担心程序运行时可能发生的某些告警 |
|
记录特定的错误信息 |
抛异常 |
记录那些不需要抛异常的错误信息(例如捕捉服务进程长时间运行期间的错误信息) |
logging.error(), logging.exception() 或者 logging.critical() 都可以适用 |
日志函数的命名依据于约定俗成的事件级别。不同事件级别的适用范围可以参考下面的这个表格(按照级别的严重程度升序排列):
事件级别 |
适用范围 |
---|---|
|
通常用在调试程序时输出详细信息 |
|
确认程序在正常运行 |
|
在程序依旧能够正常运行的情况下:记录某个期望外的运行事件;记录一些达到临界值的运行信息(例如磁盘空间不足) |
|
因为某些严重的运行错误,影响程序的某些功能使用 |
|
运行错误存在导致程序不能继续运行的场景 |
缺省的事件级别为 WARNING ,也就是说只有 WAR NIN G 级别已经高于 WAR NIN G 级别的事件可以被捕捉到。如果需要其他级别的信息,可以显式的设置日志级别。
针对捕捉到的运行事件有多种的处理措施,最简单的措施就是在控制台打印出来,当然也可以把这些事件信息记录到磁盘。
简单演示
下面是一个非常简单的用例:
import logging
logging.warning('Watch out!') # 信息会被输出到控制台
logging.info('I told you so') # 这时不会打印任何信息
运行上述代码,执行结果如下:
WARNING:root:Watch out!
INFO
级别的消息没有输出是因为缺省的日志级别是 WARNING
级别。观察输出信息,其中包含了日志级别以及调用日志函数时的入参信息(示例中为 ‘Watch out!’
)。你可能会对中间的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')
执行完这段代码之后,打开日志文件就会发现多了这些日志内容:
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too
上面的实例也展示了可以在一开始通过配置改变日志级别。因为一开始就把日志级别设置为了 DEBUG
,所以对应的日志也被记录了下来。
如果你你希望通过以下方式在命令行配置日志级别:
--log=INFO
如果向--log传递了符合规范的变量值,可以使用:
getattr(logging, loglevel.upper())
来获取入参,进而传递给basicConfig()函数。或许你也想到了需要对入参进行校验,下面提供了一个校验入参的示例:
# 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()以及其他日志输出函数之前。必须指出的是,baiscConfig()函数仅在第一次调用的时候生效,再次调用将不会产生任何作用。
如果你多次运行了上面的代码,你会发现日志文件里保存了多次运行的日志信息。可能你不需要把每次运行的日志信息都记录下来,而是仅保留最新的一次,那么你可以通过改变 filemode 入参来实现,下面是一个示例:
logging.basicConfig(filename='example.log', filemode='w', level=logging.DEBUG)
这样话,虽然多次运行都是一样的日志,但是只有最新一次的运行日志被保留下来,之前的都会被刷掉。
在多个模块中使用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 后,你会发现 myapp.log 记录的日志信息如下:
INFO:root:Started
INFO:root:Doing something
INFO:root:Finished
实际结果和你期望的一样。 mylib.py 的示例你可以灵活运用在你自己的多模块程序中。不过,需要注意的是,在这个简单的示例中,不同py文件的日志被穿插保存。《高级部分》(老张后面的推送会更新)部分会提供给你进一步的区分不同py文件日志信息的方法。
记录变量信息
通过格式化字符串的方式可以将想要保存的描述信息以及变量方便的保存下来。举个例子:
import logging
logging.warning('%s before you %s', 'Look', 'leap!')
运行结果如下:
WARNING:root:Look before you leap!
和你看到的一样,将变量格式化到描述信息的方式是使用的%这种旧的形式。这是为了向后兼容:logging包比新的格式化方式(比如str.format()、string.Template)诞生的要早。虽然logging也支持新的格式化方式,但是这里不做介绍。
自定义日志信息的格式
如果有需要,你可以自定义日志消息的格式:
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”消失了。还有其他好多配置项,但是在简单场景下,你需要也许仅是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 或者RFC 3339标准。如果你需要自定义时间格式,可以在调用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()一样。
总结
通过对《基础部分》的学习,你应该掌握了如何在程序里添加日志代码。logging还提供了高阶用法,为了能够掌握高阶用法,你应该继续阅读《高级部分》(老张这里顺道挖个坑)。
但是如果你仅仅是想跟上面介绍一样,简单的在程序里面使用日志,并且你有什么不明白的地方,可以把问题发在:
https://groups.google.com/forum/#!forum/comp.lang.python
你会很快收到回复的。
在看点这里
以上所述就是小编给大家介绍的《[译] Python 3.8 官方 Logging 文档:基础部分》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- [译] Python 3.8 官方 Logging 文档:基础部分
- [译] Python 3.8 官方 Logging 文档:高级部分
- twitter-bootstrap – Bootstrap 3.0:响应列重置文档部分
- Java XML和JSON:Java SE的文档处理 第2部分
- QueryPHP V1-beta.1 部分文档代码解耦,版本 PHP 7.3.2
- 你负责人工智能哪部分?人工那部分;知识图谱的构建主要靠人工还是机器?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ajax修炼之道
(美)哥特兰、高伯瑞斯、艾米亚 / 徐锋,胡冰 / 电子工业出版社 / 2006-4 / 29.8
Ajax将静态Web页面转变为充满交互的应用。现在您不需要牺牲Web应用程序部署的简单性,就可以将“胖”客户端应用程序部署到客户端。不过对于很多人业说,Ajax看起来很难。这就是我们撰写本书的原因。作为实践的指导,本书揭开了Ajax神秘的面纱,教您如何以简单的方式使用Ajax。本书内容覆盖了DHTML、Javascript和闻名已久的XmlHttp Request回调技术的基础知识。您将了解如何将......一起来看看 《Ajax修炼之道》 这本书的介绍吧!