Python logging库(python日志库)Logger(记录器、收集器、采集器)、Handler(处理器)、Formatter(格式化器)、Log Level(日志级别)

文章目录

  • Python Logging库详解
    • 简介
    • 日志记录的基本概念
      • 1. Logger(记录器):这是日志系统的入口点。每个记录器都有一个名称,并且记录器之间可以存在父子关系。
      • 2. Handler(处理器):记录器将日志消息发送到处理器,处理器决定如何处理这些消息。常见的处理器有`StreamHandler`、`FileHandler`等。
      • 3. Formatter(格式化器):格式化器定义了日志消息的最终输出格式。
      • 4. Log Level(日志级别):每条日志消息都有一个级别(比如DEBUG、INFO、WARNING、ERROR、CRITICAL),日志系统会根据级别决定是否记录某条消息。
    • 基本用法
      • 代码示例
      • 疑问:为什么代码中有两个 `setLevel(logging.DEBUG)`?
        • 记录器(Logger)
        • 处理器(Handler)
        • 为什么需要两个 `setLevel(logging.DEBUG)`
    • 日志级别
      • 1. DEBUG:详细的信息,通常只在诊断问题时使用。
      • 2. INFO:确认一切按预期工作的信息。
      • 3. WARNING:表示某些意外情况或问题,但不会阻止程序继续运行。
      • 4. ERROR:更严重的问题,表明程序不能执行某些功能。
      • 5. CRITICAL:严重的错误,表明程序可能无法继续运行。
    • 日志配置
      • 基本配置
        • 说明
        • 基本(`logging.basicConfig`,配置日志级别和格式化日期)
        • 简化1(只配置日志级别`level=`)
        • 简化2(什么都不配置,默认日志级别为warning)
      • 高级配置
    • 日志处理器
      • StreamHandler
      • FileHandler
      • 其他处理器
        • `RotatingFileHandler`:用于将日志消息输出到文件,并在文件达到一定大小时进行日志轮换。
        • `TimedRotatingFileHandler`:用于将日志消息输出到文件,并在特定时间间隔进行日志轮换。
        • `SocketHandler`:用于将日志消息发送到网络套接字。
        • `SMTPHandler`:用于通过电子邮件发送日志消息。
    • 日志格式化
      • 基本示例
      • 常用的日志格式化变量
        • 官方文档
        • 常用的日志格式化变量
          • `%(asctime)s`:日志事件发生的时间,格式是可配置的,默认格式为`'YYYY-MM-DD HH:MM:SS,sss'`。(`asc` 是 "ASCII" 的缩写。`asctime` 代表 "ASCII time",即使用ASCII字符表示的时间字符串)
          • `%(levelname)s`:日志级别名称(如`DEBUG`、`INFO`、`WARNING`、`ERROR`、`CRITICAL`)。
          • `%(name)s`:记录器的名称。
          • `%(message)s`:日志消息。
          • `%(filename)s`:调用日志记录函数的源文件的文件名。
          • `%(pathname)s`:调用日志记录函数的源文件的全路径名。
          • `%(module)s`:调用日志记录函数的模块名。
          • `%(funcName)s`:调用日志记录函数的函数名。
          • `%(lineno)d`:调用日志记录函数的语句所在的行号。
          • `%(created)f`:日志事件发生时的时间戳(自UNIX epoch开始的秒数)。
          • `%(msecs)d`:日志事件发生时的毫秒部分。
          • `%(relativeCreated)d`:日志事件发生时相对于Logger创建时间的毫秒数。
          • `%(thread)d`:线程ID。
          • `%(threadName)s`:线程名称。
          • `%(process)d`:进程ID。
          • `%(processName)s`:进程名称。
    • 日志捕捉
      • 基本示例
      • 日志捕捉函数的用法
        • 日志级别函数
          • 1. `logger.debug(msg, *args, **kwargs)`:记录一条DEBUG级别的日志消息。此级别的日志用于详细的信息,通常只在诊断问题时使用。
          • 2. `logger.info(msg, *args, **kwargs)`:记录一条INFO级别的日志消息。此级别的日志用于确认程序按预期工作的信息。
          • 3. `logger.warning(msg, *args, **kwargs)`:记录一条WARNING级别的日志消息。此级别的日志用于指示某些意外情况或问题,但程序仍可以继续运行。
          • 4. `logger.error(msg, *args, **kwargs)`:记录一条ERROR级别的日志消息。此级别的日志用于表示更严重的问题,表明程序不能执行某些功能。
          • 5. `logger.critical(msg, *args, **kwargs)`:记录一条CRITICAL级别的日志消息。此级别的日志用于表示严重的错误,表明程序可能无法继续运行。
        • 日志函数的参数
          • 1. `msg`:这是必需的参数,表示要记录的日志消息。可以是字符串,也可以是包含占位符的字符串,然后通过`*args`或`**kwargs`传入占位符对应的值。
          • 2. `*args`:用于为`msg`中的占位符提供参数。这些参数会以位置参数的形式传递,替换`msg`中的占位符。
          • 3. `**kwargs`:用于为日志消息提供额外的参数,通常用于设置一些可选参数,比如`exc_info`、`stack_info`、`extra`等。
            • 1). `exc_info`:用于记录异常信息。如果设置为`True`,日志消息会包含异常的堆栈信息。这在记录异常时非常有用。
            • 2). `stack_info`:如果设置为`True`,日志消息会包含调用日志函数时的堆栈信息。
            • 3). `extra`:一个字典,用于向日志消息添加额外的信息。这个字典中的键必须是格式化器中使用的占位符。
        • 示例
          • 代码
          • 各日志级别函数及其参数用法解释
            • 1. `logger.debug(msg, *args, **kwargs)`:记录DEBUG级别的日志消息。此级别的日志用于详细的信息,通常只在诊断问题时使用。
            • 2. `logger.info(msg, *args, **kwargs)`:记录INFO级别的日志消息。此级别的日志用于确认程序按预期工作的信息。
            • 3. `logger.warning(msg, *args, **kwargs)`:记录WARNING级别的日志消息。此级别的日志用于指示某些意外情况或问题,但程序仍可以继续运行。
            • 4. `logger.error(msg, *args, **kwargs)`:记录ERROR级别的日志消息。此级别的日志用于表示更严重的问题,表明程序不能执行某些功能。
            • 5. `logger.critical(msg, *args, **kwargs)`:记录CRITICAL级别的日志消息。此级别的日志用于表示严重的错误,表明程序可能无法继续运行。
      • 注意:日志打印中不建议使用`f-string`,建议使用`%惰性格式化`
    • 实际应用中的示例
      • 示例1. 在线电商平台复杂日志系统,包括不同级别和多个输出目标的处理器(Handlers)
        • 完整的日志配置代码示例
        • 解释1
        • 解释2
      • 示例2. 使用过滤器来区分日志内容(logging.Filter)
      • 示例3. 使用python字典配置多个记录器和处理器
    • 总结

Python Logging库详解

在软件开发中,日志是一个不可或缺的部分。它不仅用于调试和错误排查,还可以用于监控应用程序的运行状态。Python提供了一个强大且灵活的日志库——logging,可以满足几乎所有日志记录需求。本文将详细介绍Python的logging库,包括其基本概念、配置方法、日志记录级别、处理器、格式化器,以及如何在实际应用中有效利用它。

简介

Python的logging库是标准库的一部分,旨在为应用程序提供灵活的日志记录功能。它可以轻松地记录不同级别的日志信息,并可以将日志信息输出到不同的目标,比如控制台、文件、远程服务器等。logging库非常适合在开发和生产环境中使用,因为它不仅可以帮助开发人员追踪和调试代码,还可以帮助系统管理员监控应用程序的运行状态。

日志记录的基本概念

在深入了解logging库的使用之前,需要了解几个基本概念:

1. Logger(记录器):这是日志系统的入口点。每个记录器都有一个名称,并且记录器之间可以存在父子关系。

2. Handler(处理器):记录器将日志消息发送到处理器,处理器决定如何处理这些消息。常见的处理器有StreamHandlerFileHandler等。

3. Formatter(格式化器):格式化器定义了日志消息的最终输出格式。

4. Log Level(日志级别):每条日志消息都有一个级别(比如DEBUG、INFO、WARNING、ERROR、CRITICAL),日志系统会根据级别决定是否记录某条消息。

基本用法

代码示例

在使用logging库时,首先需要创建一个记录器,然后可以通过这个记录器记录日志消息。下面是一个简单的示例:

import logging# 创建一个记录器
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)# 创建一个处理器
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)# 创建一个格式化器并将其添加到处理器中
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)# 将处理器添加到记录器中
logger.addHandler(ch)# 记录一些日志消息
logger.debug('这是一个调试消息')
logger.info('这是一个信息消息')
logger.warning('这是一个警告消息')
logger.error('这是一个错误消息')
logger.critical('这是一个致命错误消息')

在这里插入图片描述

在上述示例中,创建了一个名为my_logger的记录器,并将其日志级别设置为DEBUG。然后创建了一个StreamHandler,用于将日志消息输出到控制台。接着,创建了一个Formatter,定义了日志消息的格式。最后,将处理器和格式化器添加到记录器中,并记录了一些不同级别的日志消息。

疑问:为什么代码中有两个 setLevel(logging.DEBUG)

在 Python 的 logging 模块中,有两个 setLevel(logging.DEBUG) 是因为日志记录的级别设置涉及到两个不同的层次:记录器(Logger)和处理器(Handler)。让我们详细讨论一下它们各自的作用和意义。

记录器(Logger)

记录器是日志记录的核心,它决定了哪些日志消息会被处理和记录。记录器有一个级别,只有级别高于或等于这个级别的日志消息才会被处理。通过 logger.setLevel(logging.DEBUG),你设置了记录器的最低级别为 DEBUG,这意味着 DEBUG 及其以上级别的消息(DEBUG, INFO, WARNING, ERROR, CRITICAL)都会被处理。

处理器(Handler)

处理器是将日志消息发送到合适的输出位置的组件,例如控制台、文件、网络等。每个处理器也有自己的级别设置,只有级别高于或等于处理器级别的日志消息才会被发送到处理器的输出位置。通过 ch.setLevel(logging.DEBUG),你设置了处理器的最低级别为 DEBUG,这意味着 DEBUG 及其以上级别的消息都会被这个处理器处理并输出。

为什么需要两个 setLevel(logging.DEBUG)
  1. 记录器级别设置:这是为了控制日志消息的初始过滤。只有级别符合条件的消息才会被进一步处理。这一层的设置确保了不必要的日志消息不会浪费资源。

  2. 处理器级别设置:这是为了控制具体的输出行为。即使一条日志消息通过了记录器的级别过滤,如果它的级别低于处理器的级别,它也不会被输出到该处理器。这一层的设置确保了不同的处理器可以有不同的日志输出级别。例如,你可能希望某些重要消息被写入文件,而所有消息都打印到控制台。

日志级别

logging库定义了五个标准的日志级别,每个级别都有对应的数值:

1. DEBUG:详细的信息,通常只在诊断问题时使用。

2. INFO:确认一切按预期工作的信息。

3. WARNING:表示某些意外情况或问题,但不会阻止程序继续运行。

4. ERROR:更严重的问题,表明程序不能执行某些功能。

5. CRITICAL:严重的错误,表明程序可能无法继续运行。

使用这些级别可以控制日志的记录和显示。比如,可以设置记录器只记录WARNING及以上级别的日志,而忽略DEBUG和INFO级别的日志。

日志配置

基本配置

说明

logging.basicConfig() 实际上并没有显式地配置特定的处理器(Handler)。这个 basicConfig 方法在没有提供其他参数的情况下,会默认配置一个 StreamHandler,它将日志输出到标准输出(通常是控制台)。这个默认的设置等同于创建了一个很基本的控制台日志处理器。

这里的 StreamHandler 是最简单的日志处理器之一,用于将日志消息发送到控制台。它会接收所有等于或高于它配置级别的日志消息(代码中为 DEBUG 级别),并将其输出到 sys.stdout,即 Python 程序的标准输出。

基本(logging.basicConfig,配置日志级别和格式化日期)

logging库提供了一个简单的配置函数logging.basicConfig,可以用来快速配置日志系统。下面是一个基本配置的示例:

import logginglogging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')logging.debug('这是一个调试消息')
logging.info('这是一个信息消息')
logging.warning('这是一个警告消息')
logging.error('这是一个错误消息')
logging.critical('这是一个致命错误消息')

在这里插入图片描述

在上述示例中,使用basicConfig函数设置了日志级别和日志格式。所有日志消息将输出到控制台,并且使用指定的格式。

简化1(只配置日志级别level=
import logginglogging.basicConfig(level=logging.DEBUG)logging.debug('这是一个调试消息')
logging.info('这是一个信息消息')
logging.warning('这是一个警告消息')
logging.error('这是一个错误消息')
logging.critical('这是一个致命错误消息')

在这里插入图片描述

简化2(什么都不配置,默认日志级别为warning)
import logginglogging.basicConfig()logging.debug('这是一个调试消息')
logging.info('这是一个信息消息')
logging.warning('这是一个警告消息')
logging.error('这是一个错误消息')
logging.critical('这是一个致命错误消息')

在这里插入图片描述

高级配置

对于更复杂的日志需求,可以使用字典配置或配置文件来配置日志系统。以下是使用字典配置的示例:

import logging
import logging.configlog_config = {'version': 1,'disable_existing_loggers': False,'formatters': {'standard': {'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',},},'handlers': {'console': {'class': 'logging.StreamHandler','formatter': 'standard','level': logging.DEBUG,},'file': {'class': 'logging.FileHandler','filename': 'app.log','formatter': 'standard','level': logging.DEBUG,},},'loggers': {'': {'handlers': ['console', 'file'],'level': logging.DEBUG,'propagate': True,},}
}logging.config.dictConfig(log_config)logger = logging.getLogger(__name__)logger.debug('这是一个调试消息')
logger.info('这是一个信息消息')
logger.warning('这是一个警告消息')
logger.error('这是一个错误消息')
logger.critical('这是一个致命错误消息')

在这里插入图片描述
在这里插入图片描述

在上述示例中,使用字典配置了日志系统,包括格式化器、处理器和记录器。日志消息将同时输出到控制台和文件app.log

日志处理器

日志处理器是日志系统中负责将日志消息发送到不同目标的组件。logging库提供了多种处理器,包括StreamHandlerFileHandler等。

StreamHandler

StreamHandler用于将日志消息输出到流(如控制台、文件等)。下面是一个使用StreamHandler的示例:

import logginglogger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)logger.addHandler(ch)logger.debug('这是一个调试消息')

在这里插入图片描述

FileHandler

FileHandler用于将日志消息输出到文件。下面是一个使用FileHandler的示例:

import logginglogger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)fh = logging.FileHandler('my_log.log')
fh.setLevel(logging.DEBUG)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)logger.addHandler(fh)logger.debug('这是一个调试消息')

在这里插入图片描述

其他处理器

除了StreamHandlerFileHandlerlogging库还提供了其他多种处理器,比如:

RotatingFileHandler:用于将日志消息输出到文件,并在文件达到一定大小时进行日志轮换。
TimedRotatingFileHandler:用于将日志消息输出到文件,并在特定时间间隔进行日志轮换。
SocketHandler:用于将日志消息发送到网络套接字。
SMTPHandler:用于通过电子邮件发送日志消息。

日志格式化

基本示例

日志格式化器用于定义日志消息的输出格式。logging库的Formatter类允许使用格式字符串自定义日志消息的格式。下面是一个示例:

import logginglogger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)logger.addHandler(ch)logger.debug('这是一个调试消息')

在这里插入图片描述

在上述示例中,使用格式字符串'%(asctime)s - %(name)s - %(levelname)s - %(message)s'定义了日志消息的格式,包括时间戳、记录器名称、日志级别和消息内容。

常用的日志格式化变量

在Python的logging模块中,日志格式化字符串可以包含多个特定的变量,这些变量会在日志记录时被自动替换。除了你提到的%(asctime)s%(name)s%(levelname)s%(message)s,还有许多其他的变量可以使用。

官方文档

可以在官方文档中找到所有可用的格式化变量:

  • Logging Module Documentation
常用的日志格式化变量
%(asctime)s:日志事件发生的时间,格式是可配置的,默认格式为'YYYY-MM-DD HH:MM:SS,sss'。(asc 是 “ASCII” 的缩写。asctime 代表 “ASCII time”,即使用ASCII字符表示的时间字符串)
%(levelname)s:日志级别名称(如DEBUGINFOWARNINGERRORCRITICAL)。
%(name)s:记录器的名称。
%(message)s:日志消息。
%(filename)s:调用日志记录函数的源文件的文件名。
%(pathname)s:调用日志记录函数的源文件的全路径名。
%(module)s:调用日志记录函数的模块名。
%(funcName)s:调用日志记录函数的函数名。
%(lineno)d:调用日志记录函数的语句所在的行号。
%(created)f:日志事件发生时的时间戳(自UNIX epoch开始的秒数)。
%(msecs)d:日志事件发生时的毫秒部分。
%(relativeCreated)d:日志事件发生时相对于Logger创建时间的毫秒数。
%(thread)d:线程ID。
%(threadName)s:线程名称。
%(process)d:进程ID。
%(processName)s:进程名称。

日志捕捉

基本示例

在开发过程中,有时需要捕捉代码中的异常并记录日志。logging库提供了便捷的方式来实现这一功能。下面是一个示例:

import logginglogger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)logger.addHandler(ch)try:1 / 0
except ZeroDivisionError as e:logger.error('捕捉到异常', exc_info=True)

在这里插入图片描述

在上述示例中,捕捉到ZeroDivisionError异常,并使用logger.error记录了异常信息。exc_info=True参数确保异常的堆栈信息也被记录下来。

日志捕捉函数的用法

logging库中,每个日志级别都有一个对应的函数,用于记录该级别的日志消息。这些函数包括debuginfowarningerrorcritical。每个函数的用法基本相同,但它们的日志级别不同,使用时需要根据具体的日志需求选择合适的函数。

日志级别函数
1. logger.debug(msg, *args, **kwargs):记录一条DEBUG级别的日志消息。此级别的日志用于详细的信息,通常只在诊断问题时使用。
2. logger.info(msg, *args, **kwargs):记录一条INFO级别的日志消息。此级别的日志用于确认程序按预期工作的信息。
3. logger.warning(msg, *args, **kwargs):记录一条WARNING级别的日志消息。此级别的日志用于指示某些意外情况或问题,但程序仍可以继续运行。
4. logger.error(msg, *args, **kwargs):记录一条ERROR级别的日志消息。此级别的日志用于表示更严重的问题,表明程序不能执行某些功能。
5. logger.critical(msg, *args, **kwargs):记录一条CRITICAL级别的日志消息。此级别的日志用于表示严重的错误,表明程序可能无法继续运行。
日志函数的参数

每个日志级别函数都可以接受以下参数:

1. msg:这是必需的参数,表示要记录的日志消息。可以是字符串,也可以是包含占位符的字符串,然后通过*args**kwargs传入占位符对应的值。
2. *args:用于为msg中的占位符提供参数。这些参数会以位置参数的形式传递,替换msg中的占位符。
3. **kwargs:用于为日志消息提供额外的参数,通常用于设置一些可选参数,比如exc_infostack_infoextra等。
1). exc_info:用于记录异常信息。如果设置为True,日志消息会包含异常的堆栈信息。这在记录异常时非常有用。
2). stack_info:如果设置为True,日志消息会包含调用日志函数时的堆栈信息。
3). extra:一个字典,用于向日志消息添加额外的信息。这个字典中的键必须是格式化器中使用的占位符。

就是说格式化器中出现的字段,日志捕获函数参数中必须提供,如:

# 创建格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(user_defined_info)s')
# 定义额外的参数
extra_info = {'user_defined_info': 'xxxxxxx'}
# 记录CRITICAL级别的日志,并使用堆栈信息
logger.critical('这是一个致命错误消息', stack_info=True, extra=extra_info)

如果执行logger.critical函数extra参数中的字典没有提供相应字段的信息,就会报错。

示例代码:

import logging# 创建记录器
logger = logging.getLogger('example_logger')
logger.setLevel(logging.DEBUG)# 创建处理器并设置级别
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)# 创建格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(user_defined_info)s')
ch.setFormatter(formatter)# 将处理器添加到记录器
logger.addHandler(ch)# 定义额外的参数
extra_info = {'user_defined_info': 'xxxxxxxxx'}# 记录DEBUG级别的日志
logger.debug('这是一个调试消息', extra=extra_info)

在这里插入图片描述

示例
代码
import logging# 创建记录器
logger = logging.getLogger('example_logger')
logger.setLevel(logging.DEBUG)# 创建处理器并设置级别
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)# 创建格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(user)s')
ch.setFormatter(formatter)# 将处理器添加到记录器
logger.addHandler(ch)# 定义额外的参数
extra_info = {'user': 'admin'}# 记录DEBUG级别的日志
logger.debug('这是一个调试消息', extra=extra_info)# 记录INFO级别的日志
logger.info('这是一个信息消息', extra=extra_info)# 记录WARNING级别的日志,并使用位置参数
logger.warning('这是一个警告消息,参数1: %s, 参数2: %d', 'param1', 2, extra=extra_info)# 记录ERROR级别的日志,并包含异常信息
try:1 / 0
except ZeroDivisionError as e:logger.error('捕捉到异常', exc_info=True, extra=extra_info)# 记录CRITICAL级别的日志,并使用堆栈信息
logger.critical('这是一个致命错误消息', stack_info=True, extra=extra_info)

在这里插入图片描述

各日志级别函数及其参数用法解释
1. logger.debug(msg, *args, **kwargs):记录DEBUG级别的日志消息。此级别的日志用于详细的信息,通常只在诊断问题时使用。

示例:

logger.debug('这是一个调试消息', extra=extra_info)
2. logger.info(msg, *args, **kwargs):记录INFO级别的日志消息。此级别的日志用于确认程序按预期工作的信息。

示例:

logger.info('这是一个信息消息', extra=extra_info)
3. logger.warning(msg, *args, **kwargs):记录WARNING级别的日志消息。此级别的日志用于指示某些意外情况或问题,但程序仍可以继续运行。

示例:

logger.warning('这是一个警告消息,参数1: %s, 参数2: %d', 'param1', 2, extra=extra_info)
4. logger.error(msg, *args, **kwargs):记录ERROR级别的日志消息。此级别的日志用于表示更严重的问题,表明程序不能执行某些功能。

示例:

try:1 / 0
except ZeroDivisionError as e:logger.error('捕捉到异常', exc_info=True, extra=extra_info)
5. logger.critical(msg, *args, **kwargs):记录CRITICAL级别的日志消息。此级别的日志用于表示严重的错误,表明程序可能无法继续运行。

示例:

logger.critical('这是一个致命错误消息', stack_info=True, extra=extra_info)

注意:日志打印中不建议使用f-string,建议使用%惰性格式化

参考文章:python fstring教程(f-string教程)(python3.6+格式化字符串方法)(%惰性格式化%)

实际应用中的示例

示例1. 在线电商平台复杂日志系统,包括不同级别和多个输出目标的处理器(Handlers)

根据你提供的需求和配置,我将给出一个示例代码,展示如何为一个大型的在线电商平台配置一个复杂的日志系统,包括不同级别和多个输出目标的处理器(Handlers)。

完整的日志配置代码示例
import logging
import sysdef setup_logging():# 创建一个名为 'ecommerce' 的全局 Loggerlogger_ = logging.getLogger('ecommerce')logger_.setLevel(logging.DEBUG)  # 设置 Logger 的级别为 DEBUG# 创建文件 Handler 1:用于操作日志,记录级别为 INFOfile_handler_info = logging.FileHandler('operations.log')file_handler_info.setLevel(logging.INFO)file_handler_info.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))# 创建文件 Handler 2:用于错误报告,记录级别为 ERRORfile_handler_error = logging.FileHandler('errors.log')file_handler_error.setLevel(logging.ERROR)file_handler_error.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))# 创建控制台 Handler:用于调试信息,记录级别为 DEBUGconsole_handler = logging.StreamHandler(sys.stdout)console_handler.setLevel(logging.DEBUG)console_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))# 创建性能监控 Handler:用于性能监控日志,记录级别为 INFOperformance_handler = logging.FileHandler('performance.log')performance_handler.setLevel(logging.INFO)performance_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))# 将所有 Handler 添加到 Loggerlogger_.addHandler(file_handler_info)logger_.addHandler(file_handler_error)logger_.addHandler(console_handler)logger_.addHandler(performance_handler)return logger_# 配置并获取 Logger
logger = setup_logging()# 使用 Logger 记录一些示例消息
logger.debug('Debug message: User session started')
logger.info('Info message: User logged in')
logger.warning('Warning message: User session timeout is approaching')
logger.error('Error message: Failed to process transaction')
logger.critical('Critical message: System is down')

在这里插入图片描述
在这里插入图片描述

解释1
  • 这个配置设置了一个全局的 Logger ecommerce,它有四个不同的 Handler,每个 Handler 都设置了不同的日志级别和输出目标。
  • file_handler_infofile_handler_error 分别用于操作日志和错误报告,记录不同级别的日志到不同的文件中。
  • console_handler 用于在开发过程中在控制台输出调试信息。
  • performance_handler 用于记录与性能相关的关键信息。

这样的配置确保日志信息根据其重要性和用途被适当地分流和存储,从而提高了系统的可维护性和监控能力。

解释2

代码中名为 ecommerce的全局 Logger(记录器),设置级别为 DEBUG,这意味着DEBUG级别及以上的日志消息会被记录;

file_handler_info处理器设置级别为INFO,意味着会处理INFO级别及以上的日志消息;
同理,其他处理器也会处理其设置的级别及以上的日志消息;

示例2. 使用过滤器来区分日志内容(logging.Filter)

下面是一个使用过滤器来区分日志内容的示例:

import logging
import sysclass PerformanceFilter(logging.Filter):def filter(self, record):# 打印调试信息以确认过滤器是否被触发contains_performance = 'Performance' in record.getMessage()print(f"Filtering: {record.getMessage()}, Result: {contains_performance}")return contains_performancedef setup_logging():logger = logging.getLogger('ecommerce')logger.setLevel(logging.DEBUG)file_handler_info = logging.FileHandler('operations.log')file_handler_info.setLevel(logging.DEBUG)file_handler_info.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))console_handler = logging.StreamHandler(sys.stdout)console_handler.setLevel(logging.DEBUG)console_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))performance_handler = logging.FileHandler('performance.log')performance_handler.setLevel(logging.DEBUG)performance_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))performance_handler.addFilter(PerformanceFilter())  # 只记录包含'performance'的日志消息logger.addHandler(file_handler_info)logger.addHandler(console_handler)logger.addHandler(performance_handler)return loggerlogger = setup_logging()
logger.debug('User logged in')  # 不会记录到 performance.log
logger.debug('Performance metrics: CPU usage at 70%')  # 会记录到 performance.log

在这里插入图片描述

在这个例子中,PerformanceFilter 过滤器将检查日志消息是否包含 ‘Performance’ 这个关键字,如果包含,则这些日志消息会被记录到 performance.log 文件中,而不是 operations.log。这样可以有效地将日志内容区分开来,确保每个文件只包含相关的信息。

注意:python in语法判断字符串中是否包含字串是匹配大小写的。

示例3. 使用python字典配置多个记录器和处理器

在实际应用中,日志系统通常会根据应用的需求进行配置和使用。下面是一个更复杂的示例,展示了如何在实际应用中配置和使用logging库:

import logging
import logging.configlog_config = {'version': 1,'disable_existing_loggers': False,'formatters': {'detailed': {'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s:%(lineno)d',},'simple': {'format': '%(asctime)s - %(levelname)s - %(message)s',},},'handlers': {'console': {'class': 'logging.StreamHandler','formatter': 'simple','level': logging.DEBUG,},'file': {'class': 'logging.FileHandler','filename': 'app.log','formatter': 'detailed','level': logging.DEBUG,},'error_file': {'class': 'logging.FileHandler','filename': 'errors.log','formatter': 'detailed','level': logging.ERROR,},},'loggers': {'': {'handlers': ['console', 'file'],'level': logging.DEBUG,'propagate': True,},'error_logger': {'handlers': ['error_file'],'level': logging.ERROR,'propagate': False,},}
}logging.config.dictConfig(log_config)logger = logging.getLogger('app_logger')
error_logger = logging.getLogger('error_logger')logger.debug('这是一个调试消息')
logger.info('这是一个信息消息')
logger.warning('这是一个警告消息')
logger.error('这是一个错误消息')
logger.critical('这是一个致命错误消息')try:1 / 0
except ZeroDivisionError as e:error_logger.error('捕捉到异常', exc_info=True)

在这个示例中,配置了多个格式化器、处理器和记录器。普通日志消息输出到控制台和app.log文件,而错误日志消息还会额外输出到errors.log文件。这样,可以在实际应用中根据不同的需求记录和管理日志。

总结

本文详细介绍了Python的logging库,从基本概念、基本用法到高级配置和实际应用。通过logging库,开发者可以灵活地记录和管理日志,帮助调试和监控应用程序。掌握logging库的使用方法,是每个Python开发者必备的技能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/53016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全-intigriti-0422-XSS-Challenge Write-up

目录 一、环境 二、解题 2.1看源码 一、环境 Intigriti April Challenge 二、解题 要求:弹出域名就算成功 2.1看源码 我们看到marge方法,肯定是原型链污染题目 接的是传参,我们可控的点在于qs.config和qs.settings,这两个可…

Java设计模式—面向对象设计原则(四) ----->接口隔离原则(ISP) (完整详解,附有代码+案例)

文章目录 3.4 接口隔离原则(ISP)3.4.1 概述3.4.2 案列 3.4 接口隔离原则(ISP) 接口隔离原则:Interface Segregation Principle,简称ISP 3.4.1 概述 客户端测试类不应该被迫依赖于它不使用的方法;一个类对另一个类的依赖应该建立在最小的接…

Invoke-Maldaptive:一款针对LDAP SearchFilter的安全分析工具

关于Invoke-Maldaptive MaLDAPtive 是一款针对LDAP SearchFilter的安全分析工具,旨在用于对LDAP SearchFilter 执行安全解析、混淆、反混淆和安全检测。 其基础是 100% 定制的 C# LDAP 解析器,该解析器处理标记化和语法树解析以及众多自定义属性&#x…

Excel图片批量插入单元格排版处理插件【图片大师】

为了方便大家在图片的插入排版的重复工作中解放出来,最近发布了一款批量插入图片的插件,欢迎大家下载,免费试用。 这是图片的文件夹: 主要功能如下: 1,匹配单元格名称的多张图批量插入到一个单元格 该功能支持设置图…

腾讯百度阿里华为常见算法面试题TOP100(4):双指针、哈希、滑动窗口

之前总结过字节跳动TOP50算法面试题: 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 目录 双指针 42.接雨水 283.移动零 11.盛最多水的容器 15.三数之和 哈希 1. 两数之和 49.字母异位词分组 128.最长连续序列 滑动窗…

网络协议全景:Linux环境下的TCP/IP、UDP

目录 1.UDP协议解析1.1.定义1.2.UDP报头1.3.特点1.4.缓冲区 2.TCP协议解析2.1.定义2.2.报头解析2.2.1.首部长度(4位)2.2.2.窗口大小2.2.3.确认应答机制2.2.4.6个标志位 2.3.超时重传机制2.4.三次握手四次挥手2.4.1.全/半连接队列2.4.2.listen2.4.3.TIME_…

SQL进阶的技巧:如何实现某列的累计乘积?

目录 0 场景描述 1 数据准备 2 问题分析 3 完全情况查询 4 小结 0 场景描述 在做数据处理的时候,尤其是复利累积的时候,有时候会有这样一场景,通过某种条件找到一列数据[X1,X2,X3...Xn],然后想要求y=X1X2X3...Xn。下面给出一个具体案例来详细解释这一问题,如下图所示…

学成在线练习(HTML+CSS)

准备工作 项目目录 内部包含当前网站的所有素材,包含 HTML、CSS、图片、JavaScript等等 1.由于元素具有一些默认样式,可能是我们写网页过程中根本不需要的,所有我们可以在写代码之前就将其清除 base.css /* 基础公共样式:清除…

大模型入门3:理解LLAMA

LLama在transformers库中的代码,以及各部分原理Llama3.1技术报告LLama 33b 微调尝试 Model a stack of DecoderBlocks(SelfAttention, FeedForward, and RMSNorm) decoder block 整体结构:最大的区别在pre-norm x -> norm(x) -> attention() -…

什么是上拉,下拉?

上拉就是将引脚通过一个电阻连接到电源,作用:1.使IO口的不确定电平稳定在高点平,2、为了增加IO口拉电流的能力。 下拉就是将引脚通过一个电阻与GND相连,作用:1.从器件输出电流 2.当IO口为输入状态时,引脚的…

【爱给网-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

Flet全平台开发:软件开发界勇士为Python语言补短板的一次极具挑战性的尝试、冲刺和华丽亮相

一、Flet创始人和开发者介绍、开发Flet的背景介绍 Flet 的创始人和开发者 Feodor Fitsner 是俄罗斯人,就职于微软。 Flet 的第一个版本于 2022 年 6 月发布。这是一个相对较新的库,它基于 Flutter 框架,首先支持的是用 Python 语言开发软件…

速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令,DS寄存器

一,地址的概念 通常所说的地址指的是某内存单元在整个机器内存中的物理地址,把整个机器内存比作一个酒店,内存单元就是这个酒店的各个房间,给这些房间编的门牌号,类比回来就是内存单元的物理地址 在第一篇介绍debug的…

文心智能体应用:美国旅游助手的诞生

创造灵感 在如今的数字化时代,旅行体验越来越依赖于智能技术的辅助。从机票预订到行程安排,再到当地美食推荐,智能助手在旅行中的作用愈发重要。尤其在美国这样一个广袤且多样化的国家,拥有一个智能旅行助手能够极大地提升游客的…

C++3D迷宫

目录 开头程序程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 #include <iostream> using namespace std; void printmaze(char strmaze[5][5][5]) {cout << "-----" << endl;int i 0;int ia 0…

react18基础教程系列--安装环境及packagejson文件分析

一个React项目中&#xff0c;默认会安装: react:React框架的核心react-dom:React 视图渲染的核心「基于React构建WebApp(HTML页面)J—>react-native:构建和渲染App的react-scripts: 脚手架为了让项目目录看起来干净一些&#xff0c;把webpack打包的规则及相关的插件/LOADER…

《OpenCV计算机视觉》—— 图像金字塔

文章目录 什么是图像金字塔&#xff1f;一、定义与基本原理二、主要类型三、构建过程四、应用领域 图像金字塔中的下采样和上采样一、下采样&#xff08;Downsampling&#xff09;二、上采样&#xff08;Upsampling&#xff09;三、总结 代码实现 什么是图像金字塔&#xff1f;…

YOLOv8目标检测模型——遥感小目标检测经验分享

小目标检测——YOLOV8 一、引言 背景介绍 &#xff08;1&#xff09;目标检测的重要性 目标检测在许多领域都具有极其重要的作用。在自动驾驶中&#xff0c;目标检测能够识别道路上的障碍物和行人&#xff0c;确保行车安全。在视频监控中&#xff0c;目标检测能够实时发现异…

从登录到免登录:JSP与Servlet结合Cookie的基本实现

前言 JSP中应用Cookie解析&#xff1a; 用户登录成功后&#xff0c;将用户信息保存到Cookie中&#xff0c;在页面读取Cookie并显示&#xff0c;不需要再次登录可以直接进入页面 第一步&#xff1a;创建JavaWeb项目&#xff0c;配置pom.xml文件 创建maven项目&#xff0c;项目名…

DB-GPT部署和试用

前言 DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。 目的是构建大模型领域的基础设施&#xff0c;通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Mu…