欢迎访问我的网站,希望内容对您有用,感兴趣的可以加入免费知识星球。

Python实用模块(十四)logging

实用模块 迷途小书童 4年前 (2019-12-04) 5992次浏览 0个评论

软硬件环境

  • ubuntu 19.04 64bit
  • anaconda3 with python 3.7.3
  • logging 0.5.1.2

简介

软件运行时难免出现问题,日志是追踪问题的一种方式。不管是在软件的开发阶段、调试阶段或者上线后,日志都非常重要。当程序crash掉而你没有保存日志,那将是灾难性的,损失将非常巨大,而且几乎没有可能找到问题的所在。

print语句可以用来输出调试信息,但是它不是一个好的选择。在简单的脚本中它可能管用,但是随着项目的变大、变复杂,print不会被采用。

python中有一个内置模块logging,它可以将程序运行的信息写入到文件或者其它输出流(如标准输出stdout)当中。

logging消息的级别

按照消息的严重程度,可分为

  • Debug : 详细的信息,调试阶段常用
  • Info : 程序正常运行的一些信息
  • Warning : 警告信息,代码可以继续运行,但是结果可能不是你想要的
  • Error : 程序已经出现错误
  • Critical : 非常严重的错误,程序可能无法继续运行

logging中,各级别又对应了一个整数,如下表

级别 整数
NOSET 0
DEBUG 10
INFO 20
WARNING 30
ERROR 40
CRITICAL 50

代码实践


# 导入模块
import logging

# 创建并配置logger,保存到文件
logging.basicConfig(filename="log.txt", 
                    format='%(asctime)s %(message)s', 
                    filemode='w') 

# 创建一个对象,参数传入__name__,在模块中就是模块的名称
logger=logging.getLogger(__name__) 

# 设置消息的日志层级,在这里,所以高于DEBUG层级的消息都会被写入文件
logger.setLevel(logging.DEBUG) 

# 测试
logger.debug("This is debug message.") 
logger.info("This is info message.") 
logger.warning("This is warning message.")
logger.error("This is error message.") 
logger.critical("This is critical message.")

程序执行后,log.txt文件内容为

2019-08-20 17:34:54,362 This is debug message.
2019-08-20 17:34:54,362 This is info message.
2019-08-20 17:34:54,362 This is warning message.
2019-08-20 17:34:54,362 This is error message.
2019-08-20 17:34:54,362 This is critical message.

Logger对象和Handler对象都可以设置级别,而默认Logger对象级别为30 ,也即WARNING,默认Handler对象级别为0,也即NOTSETlogging模块这样设计是为了更好的灵活性,比如有时候我们既想在控制台中输出DEBUG级别的日志,又想在文件中输出WARNING级别的日志。可以只设置一个最低级别的Logger对象,两个不同级别的Handler对象,示例代码如下

import logging
import logging.handlers

logger = logging.getLogger("__name__")

# 标准输出
handler1 = logging.StreamHandler()

# 输出到文件
handler2 = logging.FileHandler(filename="test.txt")

logger.setLevel(logging.DEBUG)
handler1.setLevel(logging.WARNING)
handler2.setLevel(logging.DEBUG)

formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)

logger.addHandler(handler1)
logger.addHandler(handler2)

logger.debug('This is debug message.')
logger.info('This is info message.')
logger.warning('This is warning message.')
logger.error('This is error message.')
logger.critical('This is critical message.')

如果将日志保存在一个文件中,那么时间一长,或者日志一多,单个日志文件就会很大,既不利于备份,也不利于查看。我们会想到能不能按照时间或者大小对日志文件进行划分呢?答案肯定是可以的。logging.handlers文件中提供了TimedRotatingFileHandlerRotatingFileHandler类分别可以实现按时间和大小划分。

在上面的代码块中修改handler2

# 每隔500字节保存成一个日志文件,备份文件为3个
handler2 = logging.handlers.RotatingFileHandler("test.txt", mode="w", maxBytes=500, backupCount=3)

# 每隔1个小时,保存一个日志文件,备份文件为3个
handler2 = logging.handlers.TimedRotatingFileHandler("test.txt", when="H", interval=1, backupCount=3)

参考资料

喜欢 (0)

您必须 登录 才能发表评论!

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

请关闭 Adblock 等类似浏览器插件,然后刷新页面访问,感谢您的支持!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.