您的位置:首页 > 游戏 > 游戏 > Python日志模块详解

Python日志模块详解

2024/10/5 17:25:21 来源:https://blog.csdn.net/szy13323042191/article/details/141956242  浏览:    关键词:Python日志模块详解

Python日志模块详解

Python的日志模块(logging)是一个非常强大、灵活的日志记录框架,适用于各种规模的应用程序。它允许开发者将程序执行中的信息输出到多个地方,如控制台、文件、网络等。接下来我们来详细介绍它的功能和使用方法。

1. 基本概念

1.1 日志级别

logging模块提供了几种内置的日志级别,用于标识日志的严重程度。默认情况下,日志级别从低到高依次为:

  • DEBUG:调试信息,最详细的日志信息,用于诊断问题。
  • INFO:普通运行信息,确认程序按预期工作。
  • WARNING:表示潜在问题或提示,比如磁盘空间不足。
  • ERROR:更严重的问题,程序的某些功能无法正常执行。
  • CRITICAL:最严重的级别,程序可能无法继续运行。

1.2 日志组件

logging模块有四个核心组件,每个组件有不同的用途:

  1. Logger:日志记录器,是日志系统的入口,用来生成日志记录。
  2. Handler:处理器,用来将日志记录发送到合适的地方(如文件、控制台)。
  3. Filter:过滤器,用来过滤日志记录,决定哪些日志记录应当被输出。
  4. Formatter:格式器,用来定义日志记录的最终输出格式。

2. 基本用法

可以通过logging.basicConfig()配置日志输出。

import logging# 配置日志模块
logging.basicConfig(level=logging.INFO)# 日志输出
logging.debug('这是调试信息')
logging.info('这是普通信息')
logging.warning('这是警告信息')
logging.error('这是错误信息')
logging.critical('这是严重错误信息')

在这个例子中,logging.basicConfig()用于一次性配置日志输出,level参数设置最低日志级别。只有级别高于level的日志才会被输出。

3. 配置日志格式

你可以通过Formatter来指定日志的输出格式,包括时间、日志级别、模块名称等信息。

import logging# 设置格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')# 创建一个日志记录器
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)# 创建控制台处理器并设置其格式
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)# 将处理器添加到记录器
logger.addHandler(console_handler)# 日志记录
logger.debug('这是调试信息')
logger.info('这是普通信息')
logger.warning('这是警告信息')

在这个例子中,我们创建了一个名为my_logger的记录器,设置了控制台处理器,并指定了日志的输出格式。

常用的格式化占位符

  • %(name)s:记录器的名称(即通过 logging.getLogger() 创建的 logger 名称)。
  • %(levelname)s:日志级别名称(如 DEBUG, INFO, WARNING, ERROR, CRITICAL)。
  • %(levelno)s:日志级别的数值(如 DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50)。
  • %(asctime)s:日志事件发生的时间,默认为 ISO8601 格式(你也可以通过 datefmt 参数自定义)。
  • %(msecs)d:日志事件时间的毫秒部分。
  • %(message)s:实际的日志消息内容(用户传递的消息)。
  • %(pathname)s:调用日志输出函数的完整文件路径。
  • %(filename)s:调用日志输出函数的文件名,不带路径。
  • %(module)s:调用日志输出函数所在的模块名(即文件名,不带 .py 后缀)。
  • %(funcName)s:调用日志输出函数的函数名。
  • %(lineno)d:调用日志输出函数的行号。
  • %(thread)d:线程 ID。
  • %(threadName)s:线程名称。
  • %(process)d:进程 ID。
  • %(processName)s:进程名称。
  • %(created)f:日志事件发生的时间戳(UNIX 时间)。
  • %(relativeCreated)d:日志事件发生相对于 logging 模块加载时间的毫秒数。
  • %(exc_info)s:异常相关信息,如果使用 logger.exception() 记录异常,它会输出堆栈跟踪信息。

4. 输出到文件

除了输出到控制台,你还可以将日志输出到文件:

import logging# 创建文件处理器
file_handler = logging.FileHandler('app.log')# 创建格式器并设置
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)# 获取日志记录器并设置日志级别
logger = logging.getLogger('file_logger')
logger.setLevel(logging.INFO)# 添加处理器到记录器
logger.addHandler(file_handler)# 记录日志
logger.info('日志记录到文件中')

这样,日志会被输出到app.log文件中。

5. 多个处理器

logging允许为一个Logger添加多个Handler,可以同时输出到多个目的地。

import logging# 创建日志记录器
logger = logging.getLogger('multi_handler_logger')# 创建文件处理器
file_handler = logging.FileHandler('app.log')
console_handler = logging.StreamHandler()# 设置日志格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)# 添加处理器到记录器
logger.addHandler(file_handler)
logger.addHandler(console_handler)logger.setLevel(logging.INFO)# 记录日志
logger.info('这条日志同时输出到控制台和文件')

在这个例子中,日志会同时输出到控制台和文件。

6. 使用配置文件

你可以通过配置文件配置日志系统,logging模块支持JSONYAMLINI格式。

INI文件

示例配置文件(INI格式):

[loggers]
keys=root[handlers]
keys=consoleHandler,fileHandler[formatters]
keys=defaultFormatter[logger_root]
level=INFO
handlers=consoleHandler,fileHandler[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=defaultFormatter
args=(sys.stdout,)[handler_fileHandler]
class=logging.handlers.RotatingFileHandler
level=INFO
formatter=defaultFormatter
args=('./log/app.log', 'a', 10485760, 5, 'utf-8')  # 文件路径, 打开模式, 最大文件大小, 备份文件数, 编码[formatter_defaultFormatter]
format=%(asctime)s %(levelname)s - %(pathname)s:%(funcName)s(),%(lineno)d - %(message)s
datefmt=%Y-%m-%d %H:%M:%S

在代码中加载这个配置:

import logging
import logging.configlogging.config.fileConfig('logging.conf')logger = logging.getLogger()
logger.info('这是调试信息')

JSON文件

示例配置文件(JSON格式):

{"version": 1,"disable_existing_loggers": false,"formatters": {"default": {"format": "%(asctime)s %(levelname)s - %(pathname)s:%(funcName)s(),%(lineno)d - %(message)s","datefmt": "%Y-%m-%d %H:%M:%S"}},"handlers": {"fileHandler": {"class": "logging.FileHandler","level": "INFO","formatter": "default","filename": "./log/timed_log.log","maxBytes": 10485760,"backupCount": 7,"encoding": "utf-8"},"consoleHandler": {"class": "logging.StreamHandler","level": "INFO","formatter": "default","stream": "ext://sys.stdout"}},"loggers": {"": {"level": "INFO","handlers": ["fileHandler", "consoleHandler"]},"django": {"level": "INFO","handlers": ["fileHandler", "consoleHandler"]}}
}

在代码中加载这个配置:

import logging
import logging.config# 读取 JSON 配置文件
with open('./conf/log_conf.json', 'r') as f:config = json.load(f)  # 读取并解析 JSON 配置文件为字典# 使用 dictConfig 加载 JSON 配置
logging.config.dictConfig(config)
logger = logging.getLogger()
logger.info('这是调试信息')

YAML文件

示例配置文件(YAML格式):

version: 1
disable_existing_loggers: falseformatters:default:format: '%(asctime)s %(levelname)s - %(pathname)s:%(funcName)s(),%(lineno)d - %(message)s'datefmt: '%Y-%m-%d %H:%M:%S'handlers:fileHandler:class: logging.handlers.RotatingFileHandlerlevel: INFOformatter: defaultfilename: './log/app.log'  # 基础文件名maxBytes: 10485760  # 最大文件大小为10MBbackupCount: 5  # 最多保留5个日志文件encoding: utf-8consoleHandler:class: logging.StreamHandlerlevel: INFOformatter: defaultstream: ext://sys.stdoutloggers:'':level: INFOhandlers: [fileHandler, consoleHandler]

在代码中加载这个配置:

import logging
import logging.config
import yaml# 读取 YAML 配置文件
with open('./conf/log_conf.yaml', 'r') as f:config = yaml.safe_load(f)  # 解析 YAML 配置文件为字典# 使用 dictConfig 加载 JSON 配置
logging.config.dictConfig(config)
logger = logging.getLogger()
logger.info('这是调试信息')

7. 过滤器

你可以使用过滤器来过滤特定的日志消息:

import loggingclass CustomFilter(logging.Filter):def filter(self, record):return 'special' in record.getMessage()logger = logging.getLogger()
logger.addFilter(CustomFilter())logger.warning('这条消息会被过滤')
logger.warning('这是 special 消息')

在这个例子中,只有包含special关键字的消息会被输出。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com