Python模块之logging模块
1.如何更好的学习Python2.Python准备之Python环境安装和Pycharm使用3.Python准备之笔记-MarkDown格式及云端笔记4.Python准备之软件开发规范5.Python基础之计算机基础6.Python基础之编程语言7.Python基础之Python基本构成8.Python基础之流程控制9.Python特殊机制之垃圾回收机制10.Python中级之数据类型的内置方法11.Python中级之可变数据类型和不可变数据类型12.Python中级之文件操作13.Python中级之列表字典推导式和三元运算符14.Python中级之深浅拷贝15.Python中级之字符编码16.Python中级之异常处理17.Python中级之解压赋值18.Python高级之闭包函数19.Python高级之函数介绍20.Python高级之名称空间与作用域21.Python高级之装饰器22.Python高级之模块与包23.Python高级之迭代器与生成器24.Python模块之re模块25.Python模块之os模块26.Python模块之random模块27.Python模块之序列化模块(json模块与pickle模块)28.Python模块之time模块和datetme模块29.Python高级之递归函数30.Python高级之常见的内置函数31.Python模块之sys模块32.Python模块之hashlib模块
33.Python模块之logging模块
34.Python面向对象之面向对象编程35.Python面向对象之三大特征-封装36.Python面向对象之绑定方法和非绑定方法37.Python面向对象之三大特征-继承38.Python面向对象之三大特征-多态39.Python面向对象之派生40.Python面向对象之组合41.Python面向对象之反射logging模块
【一】概要
logging
模块是 Python 中用于记录日志的标准模块。它提供了一种灵活的方式来配置不同级别的日志消息,可以将日志消息输出到不同的地方,如控制台、文件、网络等。使用logging
模块可以帮助开发者更好地理解程序的运行状态、诊断问题以及记录关键信息。
【二】常见用法
- logging日志模块,只需要配置好以后复制粘贴就可以了
import logging '''常见的日志logging模板''' # 创建日志记录器 logger = logging.getLogger(name='my_logger') # 记录日志的最低等级为debug,意为将所有信息全部记录 logger.setLevel(logging.DEBUG) # 创建处理器并设置级别 '''标准输出处配置''' console_handler = logging.StreamHandler() # 标准输出处 的等级为INFO,意为记录等级必须大于等于info,也就是debug不记录 console_handler.setLevel(logging.INFO) '''文件配置''' file_handler = logging.FileHandler(filename='1.log', mode='a', encoding='utf8') # 创建格式化器并将其添加到处理器 logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(module)s : %(message)s', datefmt='%Y-%m-%d %H:%M:%S', handlers=[file_handler, console_handler], level=logging.ERROR ) # 记录日志消息 logger.debug('This is a debug message.') logger.info('This is an info message.') logger.warning('This is a warning message.') logger.error('This is an error message.') logger.critical('This is a critical message.') # 2024-01-08 21:02:07 - my_logger - INFO - logging模块 : This is an info message. # 2024-01-08 21:02:07 - my_logger - WARNING - logging模块 : This is a warning message. # 2024-01-08 21:02:07 - my_logger - ERROR - logging模块 : This is an error message. # 2024-01-08 21:02:07 - my_logger - CRITICAL - logging模块 : This is a critical message.
将logging配置成字典,重复使用
import logging import logging.config standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' # 其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' test_format = '%(asctime)s] %(message)s' other_format = '[%(levelname)s][%(asctime)s]] %(message)s' import os base_dir = os.path.dirname(os.path.abspath(__file__)) log_path = os.path.join(base_dir, 'log') if not os.path.exists(log_path): os.mkdir(log_path) logfile_path = os.path.join(log_path, 'a3.log') # log配置字典 LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, 'other': { 'format': other_format }, }, 'filters': {}, # 过滤日志 'handlers': { # 打印到终端的日志 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'simple' }, # 打印到文件的日志,收集info及以上的日志 'default': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', 'filename': logfile_path, # 日志文件 'maxBytes': 1024 * 1024 * 100, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, 'other': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'other' }, }, 'loggers': { # logging.getLogger(__name__)拿到的logger配置 空字符串作为键 能够兼容所有的日志 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置 'default': { 'handlers': ['default', ], 'level': 'DEBUG', 'propagate': False, }, 'console': { 'handlers': ['console', 'default'], 'level': 'DEBUG', 'propagate': False, }, 'other': { 'handlers': ['other'], 'level': 'DEBUG', 'propagate': False, }, }, } # 使用配置字典 def common(xxx): logging.config.dictConfig(LOGGING_DIC) # 自动加载字典中的配置 logger1 = logging.getLogger(xxx) return logger1 logger=common('default') logger.debug('xxx') logger.info('xxx') logger.warning('xxx')
【三】详解
'''python的默认标准输出(控制台)等级为warning''' import logging logging.debug("debug message") logging.info("debug message") logging.warning("debug message") logging.error("debug message") logging.critical("debug message") # WARNING:root:debug message # ERROR:root:debug message # CRITICAL:root:debug message
formatter参数详细
'''formatter参数详细''' # 官方源码 ''' %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted ''' ''' %(name)s: 记录器的名称(日志通道)。 %(levelno)s: 日志消息的数值级别(DEBUG、INFO、WARNING、ERROR、CRITICAL)。 %(levelname)s: 日志消息的文本级别("DEBUG"、"INFO"、"WARNING"、"ERROR"、"CRITICAL")。 %(pathname)s: 发出日志调用的源文件的完整路径名(如果可用)。 %(filename)s: 源文件路径名的文件名部分。 %(module)s: 模块名(文件名的名称部分)。 %(lineno)d: 发出日志调用的源代码行号(如果可用)。 %(funcName)s: 函数名。 %(created)f: LogRecord 创建的时间(time.time() 返回值)。 %(asctime)s: LogRecord 创建的文本时间。 %(msecs)d: 创建时间的毫秒部分。 %(relativeCreated)d: 相对于加载日志模块时(通常在应用程序启动时)创建 LogRecord 的时间,以毫秒为单位。 %(thread)d: 线程 ID(如果可用)。 %(threadName)s: 线程名(如果可用)。 %(process)d: 进程 ID(如果可用)。 %(message)s: record.getMessage() 的结果,记录被发出时计算的消息。 '''
日志配置参数详解
# 日志配置详解 # 自定义日志级别 CONSOLE_LOG_LEVEL = "INFO" FILE_LOG_LEVEL = "DEBUG" # 自定义日志格式 # 打印在文件里的格式:时间戳 + 线程名 + 线程ID + 任务ID + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志级别 + 日志消息正文 STANDARD_FORMAT = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d][%(levelname)s][%(message)s]' # 打印在控制台的格式:日志级别 + 时间戳 + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志消息正文 SIMPLE_FORMAT = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' ''' 参数详解: -1.%(asctime)s: 时间戳,表示记录时间 -2.%(threadName)s: 线程名称 -3.%(thread)d: 线程ID -4.task_id:%(name)s: 任务ID,即日志记录器的名称 -5.%(filename)s: 发出日志调用的源文件名 -6.%(lineno)d: 发出日志调用的源代码行号 -7.%(levelname)s: 日志级别,如DEBUG、INFO、WARNING、ERROR、CRITICAL等 -8.%(message)s: 日志消息正文 ''' def create_log_config_dict(tag_path=None, username=None): # 日志文件路径 # os.getcwd() : 获取当前工作目录,即当前python脚本工作的目录路径 # 拼接日志文件路径 : 当前工作路径 + “logs”(日志文件路径) LOG_PATH = os.path.join(BASE_DIR, "log", tag_path) # OS模块 : 创建多层文件夹 # exist_ok=True 的意思是如果该目录已经存在,则不会抛出异常。 os.makedirs(LOG_PATH, exist_ok=True) # log日志文件路径 : 路径文件夹路径 + 日志文件 LOG_FILE_PATH = os.path.join(LOG_PATH, f'{username}.log') # 日志配置字典 LOGGING_DIC = { # 日志版本 'version': 1, # 表示是否要禁用已经存在的日志记录器(loggers)。 # 如果设为 False,则已经存在的日志记录器将不会被禁用,而是可以继续使用。 # 如果设为 True,则已经存在的日志记录器将会被禁用,不能再被使用。 'disable_existing_loggers': False, # 格式化程序:用于将日志记录转换为字符串以便于处理和存储。 # 格式化程序定义了每个日志记录的输出格式,并可以包括日期、时间、日志级别和其他自定义信息。 'formatters': { # 自定义格式一:年-月-日 时:分:秒 'standard': { # 自定义日志格式 :时间戳 + 线程名 + 线程ID + 任务ID + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志级别 + 日志消息正文 # 这里要对应全局的 STANDARD_FORMAT 配置 'format': STANDARD_FORMAT, # 时间戳格式:年-月-日 时:分:秒 'datefmt': '%Y-%m-%d %H:%M:%S' # 时间戳格式 }, # 自定义格式二: 'simple': { # 自定义日志格式:# 日志级别 + 时间戳 + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志消息正文 # 这里要对应全局的 SIMPLE_FORMAT 配置 'format': SIMPLE_FORMAT }, }, # 过滤器 'filters': {}, # 日志处理器 'handlers': { # 自定义处理器名称 - 输出到控制台屏幕 'console': { # 设置日志等级 为INFO 'level': CONSOLE_LOG_LEVEL, # 表示该处理器将输出日志到流(stream):日志打印到控制台 'class': 'logging.StreamHandler', # 日志打印格式:日志级别 + 时间戳 + 发出日志调用的源文件名 + 发出日志调用的源代码行号 + 日志消息正文 # 这里的配置要对应 formatters 中的 simple 配置 'formatter': 'simple' }, # 自定义处理器名称 - 输出到文件 'default': { # 自定义日志等级 'level': FILE_LOG_LEVEL, # 标准输出到文件 'class': 'logging.handlers.RotatingFileHandler', # 日志打印格式:年-月-日 时:分:秒 # 这里的配置要对应 formatters 中的 standard 配置 'formatter': 'standard', # 这里 要注意声明配置文件输出端的文件路径 'filename': LOG_FILE_PATH, # 限制文件大小:1024 * 1024 * 5 = 5242880,意味着这个变量的值是 5MB(兆字节) 'maxBytes': 1024 * 1024 * 5, # 表示保留最近的5个日志文件备份。 # 当日志文件达到最大大小限制时,将会自动轮转并且保留最新的5个备份文件,以便查看先前的日志记录。 # 当日志文件达到最大大小限制时,会自动进行轮转,后续的文件名将会以数字进行命名, # 例如,第一个备份文件将被重命名为原始日志文件名加上".1"的后缀, # 第二个备份文件将被重命名为原始日志文件名加上“.2”的后缀, # 以此类推,直到保留的备份数量达到设定的最大值。 'backupCount': 5, # 日志存储文件格式 'encoding': 'utf-8', }, }, # 日志记录器,用于记录应用程序的运行状态和错误信息。 'loggers': { # 空字符串作为键 能够兼容所有的日志(当没有找到对应的日志记录器时默认使用此配置) # 默认日志配置 '': { # 日志处理器 类型:打印到控制台输出 + 写入本地日志文件 'handlers': ['default', 'console'], # 日志等级 : DEBUG 'level': 'DEBUG', # 默认情况下,当一个日志消息被发送到一个Logger对象且没有被处理时,该消息会被传递给它的父Logger对象,以便在更高层次上进行处理。 # 这个传递过程称为“传播(propagation)”,而propagate参数指定了是否要使日志消息向上传播。 # 将其设置为True表示应该传播消息到上一级的Logger对象;如果设置为False则不传播。 # 表示异常将会在程序中继续传播 # 也就是说,如果一个异常在当前的代码块中没有被处理,它将会在上级代码块或调用函数中继续向上传递,直到被某个代码块捕获或者程序退出。 # 这是 Python 中异常处理机制的默认行为。 # 如果将 'propagate' 设置为 False,则异常不会被传播,即使在上级代码块中没有处理异常的语句,程序也会忽略异常并继续执行。 'propagate': True, }, }, } return LOGGING_DIC def set_logging_color(name='', tag_path='User', username='Log'): LOGGING_DIC = create_log_config_dict(tag_path=tag_path, username=username) # 初始化日志处理器 - 使用配置字典初始化日志处理器(将自定义配置加载到日志处理器中) # logging.basicConfig(level=logging.WARNING) logging.config.dictConfig(LOGGING_DIC) # 实例化日志处理器对象 - 并赋予日志处理器等级 logger = logging.getLogger(name) # 将logger对象传递给coloredlogs.install()函数,并执行该函数以安装彩色日志记录器,使日志信息在控制台上呈现为带有颜色的格式。 # 具体来说,该函数会使用ANSI转义序列在终端上输出日志级别、时间戳和消息等信息,并按日志级别使用不同的颜色来区分它们。这可以让日志信息更易于阅读和理解。 coloredlogs.install(logger=logger) # 禁止日志消息向更高级别的父记录器(如果存在)传递。 # 通常情况下,当一个记录器发送一条日志消息时,该消息会被传递给其所有祖先记录器,直到传递到根记录器为止。但是,通过将logger.propagate设置为False,就可以阻止该记录器的消息向上层传递。 # 换句话说,该记录器的消息只会被发送到该记录器的处理程序(或子记录器)中,而不会传递给祖先记录器,即使祖先记录器的日志级别比该记录器要低。 # 这种方法通常适用于需要对特定记录器进行控制,并希望完全独立于其祖先记录器的情况。 # 确保 coloredlogs 不会将我们的日志事件传递给根 logger,这可以防止我们重复记录每个事件 logger.propagate = False # 配置 日志颜色 # 这段代码定义了一个名为coloredFormatter的变量,并将其赋值为coloredlogs.ColoredFormatter。 # 这是一个Python库中的类,用于创建带有彩色日志级别和消息的格式化器。 # 该变量可以用作日志记录器或处理程序的格式化程序,以使日志输出更易于阅读和理解。 coloredFormatter = coloredlogs.ColoredFormatter( # fmt表示格式字符串,它包含了一些占位符,用于在记录日志时动态地填充相关信息。 # [%(name)s]表示打印日志时将记录器的名称放在方括号内,其中name是一个变量名,将被记录器名称所替换。 # %(asctime)s表示打印日志时将时间戳(格式化为字符串)插入到消息中,其中asctime是时间的字符串表示形式。 # %(funcName)s表示打印日志时将函数名插入到消息中,其中funcName是函数的名称。 # %(lineno)-3d表示打印日志时将行号插入到消息中,并且将其格式化为3位数字,其中lineno表示行号。 # %(message)s表示打印日志时将消息本身插入到消息中。 # 综合起来,这个格式字符串将在记录日志时输出以下信息:记录器名称、时间戳、函数名称、行号和日志消息。 # 记录器名称 + 时间戳 + 函数名称 + 行号 + 日志消息 fmt='[%(name)s] %(asctime)s %(funcName)s %(lineno)-3d %(message)s', # 级别颜色字典 level_styles=dict( # debug 颜色:白色 debug=dict(color='white'), # info 颜色:蓝色 info=dict(color='blue'), # warning 颜色:黄色 且 高亮 warning=dict(color='yellow', bright=True), # error 颜色:红色 且 高亮 且 加粗 error=dict(color='red', bold=True, bright=True), # critical 颜色:灰色 且 高亮 且 背景色为红色 critical=dict(color='black', bold=True, background='red'), ), # 这段代码定义了一个名为field_styles的字典 , 其中包含四个键值对。 # 每个键代表日志记录中的不同字段,而每个值是一个字典,它指定了与该字段相关联的样式选项。 # 具体来说,这些字段和样式选项如下: # name:指定记录器的名称,将使用白色颜色。 # asctime:指定日志记录的时间戳,将使用白色颜色。 # funcName:指定记录消息的函数名称,将使用白色颜色。 # lineno:指定记录消息的源代码行号,将使用白色颜色。 field_styles=dict( name=dict(color='white'), asctime=dict(color='white'), funcName=dict(color='white'), lineno=dict(color='white'), ) ) ## 配置 StreamHandler:终端打印界面 # 这行代码定义了一个名为ch的日志处理器。 # 具体来说,它是logging.StreamHandler类的一个实例,用于将日志输出到标准输出流(即控制台)中。 # 在创建StreamHandler对象时,需要指定要使用的输出流 # 因此stream=sys.stdout参数指定了该对象将把日志写入到标准输出流中. ch = logging.StreamHandler(stream=sys.stdout) # 这段代码是 Python 中用于设置日志输出格式的语句。 # 它使用了一个名为 coloredFormatter 的格式化器对象,并将其传递给 ch.setFormatter() 方法来指定输出日志的样式。 # 具体来说,ch 是一个 Logger 对象,它代表了整个日志系统中的一个记录器。 # 可以通过该对象来控制日志的级别、输出位置等行为。而 setFormatter() 方法则用于设置该 Logger 输出日志的格式化方式 # 这里传递的是 coloredFormatter 格式化器对象。 # 在实际应用中,coloredFormatter 可以是自定义的 Formatter 类或者已经存在的 Formatter 对象。 # 这里 将 coloredFormatter - 彩色输出日志信息的格式化器 传入进去。 ch.setFormatter(fmt=coloredFormatter) # 这段代码是在Python中添加一个日志记录器(logger)的处理器(handler)。其中,hdlr参数是指定要添加到记录器(logger)中的处理器(handler)对象,ch是一个代表控制台输出的处理器对象。 # 这行代码的作用是将控制台输出的信息添加到日志记录器中。 logger.addHandler(hdlr=ch) # 这段代码用于设置日志级别为DEBUG,也就是最低级别的日志记录。 # 意思是在程序运行时,只有DEBUG级别及以上的日志信息才会被记录并输出,而比DEBUG级别更低的日志信息则不会被记录或输出。 # DEBUG(调试)、INFO(信息)、WARNING(警告)、ERROR(错误)和CRITICAL(严重错误)。 logger.setLevel(level=logging.DEBUG) # 返回日志生成对象 return logger def get_logger(name='', tag_path='User', username='Log'): ''' :param name: 日志等级 :param username: 用户名 :return: ''' LOGGING_DIC = create_log_config_dict(tag_path=tag_path, username=username) # 初始化日志处理器 - 使用配置字典初始化日志处理器(将自定义配置加载到日志处理器中) logging.config.dictConfig(LOGGING_DIC) # 实例化日志处理器对象 - 并赋予日志处理器等级 logger = logging.getLogger(name) # 返回日志生成对象 return logger
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了