写点什么

python 小知识 - 日志处理 logging

作者:AIWeker
  • 2022 年 9 月 10 日
    福建
  • 本文字数:2174 字

    阅读完需:约 7 分钟

python小知识-日志处理logging

在项目开发中,日志信息是程序中必不可少的组成部分。每一种语言都有相应的日志模块,如 java 中 log4j,而 python 中是通过 logging 模块来提供日志功能。

1.日志要哪些本质功能?

在分享日志 logging 模块之前,先来思考下我们需要哪些的日志信息?或者日志信息给我们提供什么样的价值?


  • 基本功能 1.首先:日志应该包含程序运行的基本信息,比如运行时间,**运行的位置信息(哪个文件,哪行)**等,这些信息可以帮助我们观测程序的运行的基本情况,以便更好的分析你需要的输出的信息所代表的含义;

  • 基本功能 2.接着:日志最重要的功能是在程序功能中输出一些信息数据,以便更好的了解程序的运行情况。而我们需要输出的信息太多了,在不同的开发阶段需要的信息也不同,如一些流程必要的基本信息调试的过程信息错误信息告警信息;这么多信息要展示,日志信息会显得杂乱,不能突出重点,同时这些信息又都能在不同场景使用(通常我们在调试完程序后,调试一些信息可以删除,但是出现 bug 后,又有调试的时候,就会出现重复劳动的问题);所以日志模块需要提供日志筛选和过滤的功能,通常是对日志信息进行等级分类,并设置需要显示的最低等级。这样我们需要调试的时候就开启调试的日志,不需要的时候开启更高等级的日志信息,更加灵活

  • 基本功能 3.另外,日志应该支持输出到多种途径,比如直接终端显示,一般线上系统需要输出到日志文件,便于排查问题


以上就是日志必须要有的功能 3 个模块。

2.logging 基本使用

python 的 logging 模块也提供了上面说的 3 个基本模块,也是我们最经常使用的(别的花哨的功能可以查看 API 咯);


import logginglogging.basicConfig()print(__name__)logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)logger.debug("this is a debug")logger.info('this is a info')logger.warning('this is a warn')logger.critical('this is a critical')logger.error('this is a error')
# __main__# DEBUG:__main__:this is a debug# INFO:__main__:this is a info# WARNING:__main__:this is a warn# CRITICAL:__main__:this is a critical# ERROR:__main__:this is a error
复制代码


logging 中的日志等级可以分为 5 个,从低到高分别是:


  • DEBUG:调试

  • INFO: 基本信息

  • WARNING: 非错误,警告类信息

  • ERROR: 异常错误信息

  • CRITICAL:严重问题如硬件问题等,基本很少使用


默认的是 WARNING 等级,当在 WARNING 或 WARNING 之上等级的才记录日志信息。


上面我们了解了 logging 的基本的使用:


  • 导入 logging, 默认情况下回进行基本配置

  • 获取日志记录器 logger

  • 设置日志等级

  • 利用日志记录器 logger 进行日志输出

3.logging 进阶

logging 主要由四个模块组成:


  • 记录器 loggers: 记录日志主要信息,一般通过 logger.getLogger("name"), 可以设置名字来创建不同日志记录器,默认不设置为 root 记录器,记录器可以设置日志等级,对应日志基本功能 2

  • 句柄 handlers; 设置日志的输出的形式,正常是文件输出和屏幕流输出,对应日志基本功能 3

  • 过滤器 Filters:很少用,过滤日志信息

  • 格式化 Formatters:设置日志输出的格式(如时间,文件名等), 对应日志基本功能 1


下面给出完整的例子:


import loggingdef get_root_logger(logger_name='log', log_level=logging.INFO, log_file=None):    logger = logging.getLogger(logger_name)    logger.setLevel(level=log_level)    format_str = '%(asctime)s [ %(name)s ] %(filename)s - line:%(lineno)d %(levelname)s: %(message)s'    # if the logger has been initialized, just return it    if logger.hasHandlers():        return logger
if log_file is not None: file_handler = logging.FileHandler(log_file, 'w') file_handler.setFormatter(logging.Formatter(format_str)) file_handler.setLevel(log_level) logger.addHandler(file_handler) else: sh = logging.StreamHandler() sh.setFormatter(logging.Formatter(format_str)) sh.setLevel(log_level) logger.addHandler(sh)
return logger
logger = get_root_logger("mylog")logger.info('this is a info')logger.warning('this is a warn')logger.critical('this is a critical')logger.error('this is a error')
# 2022-09-10 22:47:08,611 [ mylog ] log.py - line:24 INFO: this is a info# 2022-09-10 22:47:08,611 [ mylog ] log.py - line:25 WARNING: this is a warn# 2022-09-10 22:47:08,611 [ mylog ] log.py - line:26 CRITICAL: this is a critical# 2022-09-10 22:47:08,614 [ mylog ] log.py - line:27 ERROR: this is a error
复制代码


从上面可以知道,handler 需要设置日志格式和日志等级。


基本格式:


  • asctime 时间

  • name 日志名称

  • filename 日志信息所在文件

  • lineno: 日志信息坐在文件行号

  • levelname:日志等级

  • message 日志内容

4.logging 注意事项

  • 单例模式 logging.getLogger 是单例模式,所以同一个名字的 logger 在不同的文件或者模块中使用都是调用的是同一个 logger。

  • 这个在多模块中使用通过一个 logger 特别实用。

  • 避免多个句柄输出相同的内容由于一个 logger 可以有多个句柄 handler,如果出现输出相同日志信息的情况,可以检查下是否多个句柄。注意 logging.basicConfig()默认会创建一个屏幕流句柄。





发布于: 刚刚阅读数: 4
用户头像

AIWeker

关注

公众号:人工智能微客(aiweker) 2019.11.21 加入

人工智能微客(aiweker)长期跟踪和分享人工智能前沿技术、应用、领域知识,不定期的发布相关产品和应用,欢迎关注和转发

评论

发布
暂无评论
python小知识-日志处理logging_Python_AIWeker_InfoQ写作社区