Python 教程:日志功能与处理逻辑

举报
TT-千叶 发表于 2022/12/28 11:27:11 2022/12/28
【摘要】 前言在应用程序执行过程中,我们希望通过规范格式输出程序执行的详细信息,这时我们需要用到日志功能。在 Python 语言中,有个內建模块 logging 能够很好的实现日志功能。整体来说,logging 配置可以分成 4 个部分: Loggers、Handlers、Filters 和 Formatters。接下来我们详细探讨其处理逻辑和配置方法。 1. 日志功能逻辑 LogRecord每个事...

前言

在应用程序执行过程中,我们希望通过规范格式输出程序执行的详细信息,这时我们需要用到日志功能。在 Python 语言中,有个內建模块 logging 能够很好的实现日志功能。整体来说,logging 配置可以分成 4 个部分: LoggersHandlersFiltersFormatters。接下来我们详细探讨其处理逻辑和配置方法。

1. 日志功能逻辑

LogRecord

每个事件生成日志条目称之为 LogRecord,在 LogRecord 中包含了日志级别日志元数据信息两个重要组成部分。在 Python 语言中日志级别可以分为 5 个等级:

  • DEBUG: Low level system information for debugging purposes.
  • INFO: General system information.
  • WARNING: Information describing a minor problem that has occurred.
  • ERROR: Information describing a major problem that has occurred.
  • CRITICAL: Information describing a critical problem that has occurred. 当 LogRecord 传入 Logger 中处理时,会比较 LogRecord 和 Logger 中的日志级别。若日志级别相等或者高于 Logger 的日志级别,该条 LogRecord 才会被 Logger 处理。

Formatter

Formatter 主要用于渲染日志的输出格式,在 Python 中给定了内置的格式变量,我们可以自定义日志信息的输出格式。

格式变量列举:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息

Filter

Filter 用来为日志信息的处理提供额外的过滤选项。在默认情况下,从 Logger 获取到的每一条 LogRecord 都会交给 Handler 处理。但是,当我们有一些额外的处理逻辑,比方说我希望将 LogRecord 的日志级别变更,或者我希望后续仅处理 ERROR 类型的记录,那么就可以使用 Filter 来过滤。

Handler

Handler 是日志处理的核心,描述了程序日志的后续执行方式。一般而言,我们希望日志能够输出到 Console 显示,或者写成文件本地持久化存储,都要靠 Handler 来实现。为此,Python 中主要提供了 FileHandlerStreamHandler 两种 Handler 来分别执行文件存储和控制台打印两种日志处理方式。

2. 函数式配置日志

函数式配置日志输出是最简单的方式,我们可以将日志打印到文件中。但是,这种方式有个缺陷,即无法将日志打印到 Console。 特点:配置简单,但无法同时输出控制台和文件

import logging
logging.basicConfig(
    level=logging.DEBUG, # 设定打印日志的级别
    # 日志消息格式,level=日志级别 format=日志格式 asctime=对应下面的datefmt filename=日志文件路径
    format="%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s",
    datefmt="%Y-%d-%d %H:%M:%S",
    filename="1.log",
    # a=追加 w=覆盖
    filemode="a"
)
logging.debug("debug")
logging.info("info")

3. 对象式配置日志

对象式配置日志能够较强的进行定制化配置,包括日志的输出格式、控制台输出、输出本地文件持久化存储。因此,在实际使用时一般都采用对象式配置日志的方式来处理。 特点:定制化强,配置较为复杂

配置流程

  1. 创建并获取 logger 对象;
  2. 创建 FileHandler 对象;
  3. 创建 StreamHandler 对象;
  4. 创建 Formatter 对象;
  5. 给 Handler 对象绑定 Formatter;
  6. 给 logger 对象绑定 Handler

import logging
logger = logging.RootLogger("DEBUG") # 如果要自定义level,则可使用RootLogger,或者logger.setLevel()
# logger = logging.getLogger() # 使用getLogger默认level为WARNING
fh = logging.FileHandler('test.log', encoding='utf-8')  # 创建FileHandler对象
sh = logging.StreamHandler()  # 创建StreamHandler对象

fmt = logging.Formatter("%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s")
fh.setFormatter(fmt)  # 给Handler对象绑定Formatter
sh.setFormatter(fmt)  # 给Handler对象绑定Formatter

logger.addHandler(fh)  # 给logger对象绑定Handler
logger.addHandler(sh) # 给logger对象绑定Handler

logger.info('info')
logger.debug('debug')
logger.error("error")

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。