Python日志系统详解:从基础配置到高级应用
1. Python日志系统概述logging模块是Python标准库中用于应用程序和库的灵活事件日志系统。它提供了一套完整的日志记录功能允许开发者根据不同的需求对日志进行分级、过滤和输出。日志系统的基本组件包括Logger记录器应用程序代码直接交互的接口Handler处理器决定日志输出的位置控制台、文件等Filter过滤器提供更细粒度的日志过滤功能Formatter格式化器控制日志的最终输出格式2. 日志级别详解Python logging模块定义了6个标准日志级别按严重性递增排列2.1 标准日志级别NOTSET (0)表示不设置级别会继承父logger的级别DEBUG (10)详细的调试信息通常只在开发时使用INFO (20)确认程序按预期运行的一般信息WARNING (30)表示发生了意外情况或即将发生问题ERROR (40)由于更严重的问题程序无法执行某些功能CRITICAL (50)严重错误程序本身可能无法继续运行提示在实际应用中建议根据环境设置不同的日志级别。开发环境可以使用DEBUG生产环境建议使用INFO或WARNING级别。2.2 日志级别设置方法设置日志级别有两种方式# 方式1使用数值 logger.setLevel(10) # 设置为DEBUG级别 # 方式2使用字符串推荐 logger.setLevel(DEBUG)3. Logger对象深入解析Logger是日志系统的核心组件每个Logger都有一个名称形成层次结构。3.1 Logger的层次结构Logger名称使用点号分隔如a、a.b、a.b.c。未命名的logger会返回root logger。import logging # 获取root logger root_logger logging.getLogger() # 获取名为app的logger app_logger logging.getLogger(app) # 获取名为app.module的logger是app的子logger module_logger logging.getLogger(app.module)3.2 Logger的继承机制子logger会继承父logger的日志级别和handler除非显式设置# 设置父logger级别 logging.getLogger(app).setLevel(INFO) # 子logger未设置级别会继承父logger的INFO级别 module_logger logging.getLogger(app.module) print(module_logger.getEffectiveLevel()) # 输出20INFO3.3 Logger的常用方法日志记录方法debug(msg, *args, **kwargs)info(msg, *args, **kwargs)warning(msg, *args, **kwargs)error(msg, *args, **kwargs)critical(msg, *args, **kwargs)log(lvl, msg, *args, **kwargs)配置方法setLevel(lvl)addHandler(hdlr)removeHandler(hdlr)addFilter(filter)removeFilter(filter)4. Handler处理器详解Handler决定日志的输出位置和方式。常用的内置Handler包括4.1 常用Handler类型StreamHandler输出到流如sys.stderrFileHandler输出到文件RotatingFileHandler按大小自动分割日志文件TimedRotatingFileHandler按时间自动分割日志文件SMTPHandler通过邮件发送日志SocketHandler通过TCP发送日志4.2 Handler配置示例import logging # 创建logger logger logging.getLogger(example) logger.setLevel(logging.DEBUG) # 创建控制台handler并设置级别 console_handler logging.StreamHandler() console_handler.setLevel(logging.DEBUG) # 创建文件handler并设置级别 file_handler logging.FileHandler(example.log) file_handler.setLevel(logging.WARNING) # 创建formatter并添加到handler formatter logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s) console_handler.setFormatter(formatter) file_handler.setFormatter(formatter) # 将handler添加到logger logger.addHandler(console_handler) logger.addHandler(file_handler) # 记录日志 logger.debug(Debug message) logger.info(Info message) logger.warning(Warning message) logger.error(Error message) logger.critical(Critical message)5. Formatter格式化器Formatter控制日志的最终输出格式支持丰富的属性替换。5.1 常用格式化属性属性名格式描述asctime%(asctime)s易读的时间格式created%(created)f时间戳time.time()返回值filename%(filename)s文件名部分funcName%(funcName)s包含日志调用的函数名levelname%(levelname)s日志级别文本DEBUG, INFO等levelno%(levelno)s日志级别数字lineno%(lineno)d源代码行号message%(message)s记录的消息module%(module)s模块名name%(name)slogger名称pathname%(pathname)s完整路径名process%(process)d进程IDprocessName%(processName)s进程名thread%(thread)d线程IDthreadName%(threadName)s线程名5.2 自定义Formatter示例# 创建详细的formatter detailed_formatter logging.Formatter( %(asctime)s - %(name)s - %(levelname)s - %(module)s.%(funcName)s:%(lineno)d - %(message)s, datefmt%Y-%m-%d %H:%M:%S ) # 创建简洁的formatter simple_formatter logging.Formatter(%(levelname)s: %(message)s) # 应用到不同的handler console_handler.setFormatter(simple_formatter) file_handler.setFormatter(detailed_formatter)6. 日志配置最佳实践6.1 基础配置方法最简单的配置方式是使用basicConfig()import logging logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, filenameapp.log, filemodea )6.2 从配置文件加载配置更复杂的配置可以从字典或文件加载import logging.config # 配置字典 config { version: 1, formatters: { detailed: { format: %(asctime)s %(name)-15s %(levelname)-8s %(processName)-10s %(message)s } }, handlers: { console: { class: logging.StreamHandler, level: INFO, formatter: detailed }, file: { class: logging.FileHandler, filename: mplog.log, level: DEBUG, formatter: detailed } }, root: { level: DEBUG, handlers: [console, file] } } logging.config.dictConfig(config)6.3 多模块日志实践在大型项目中建议在主模块中配置日志系统在各子模块中获取logger时使用__name__作为名称# 主模块 main.py import logging import my_module logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) logger.info(Starting application) my_module.do_something() logger.info(Finished) # 子模块 my_module.py import logging logger logging.getLogger(__name__) def do_something(): logger.info(Doing something)7. 高级日志技巧7.1 上下文信息添加可以通过extra参数添加上下文信息logger.info(User logged in, extra{ip: 192.168.1.1, user: admin})需要相应的formatter支持formatter logging.Formatter(%(asctime)s %(ip)-15s %(user)-8s %(message)s)7.2 异常日志记录记录异常信息的最佳实践try: 1 / 0 except ZeroDivisionError: logger.exception(Division by zero) # 会自动记录异常堆栈 # 等价于 # logger.error(Division by zero, exc_infoTrue)7.3 日志过滤自定义过滤器示例class InfoAndAboveFilter(logging.Filter): def filter(self, record): return record.levelno logging.INFO # 应用过滤器 handler.addFilter(InfoAndAboveFilter())7.4 日志轮转使用RotatingFileHandler实现日志轮转from logging.handlers import RotatingFileHandler handler RotatingFileHandler( app.log, maxBytes1024*1024, # 1MB backupCount5 # 保留5个备份 )8. 性能优化与线程安全8.1 日志性能优化避免在日志消息中进行字符串格式化# 不推荐即使日志级别高于DEBUG也会执行字符串格式化 logger.debug(Value: %s % expensive_function()) # 推荐使用%风格的格式化 logger.debug(Value: %s, expensive_function()) # 推荐使用{}或f-string风格的格式化 logger.debug(Value: {}.format(expensive_function()))使用isEnabledFor检查日志级别if logger.isEnabledFor(logging.DEBUG): logger.debug(Message with %s, expensive_data())8.2 线程安全logging模块是线程安全的但在信号处理函数中使用时需要注意import logging import signal # 不安全的信号处理函数 def handle_signal(signum, frame): logging.info(Received signal %s, signum) # 可能引发死锁 # 安全的替代方案 def handle_signal_safe(signum, frame): msg Received signal {}.format(signum) logging.Handler().emit(logging.LogRecord( name__name__, levellogging.INFO, pathname__file__, lineno0, msgmsg, argsNone, exc_infoNone )) signal.signal(signal.SIGINT, handle_signal_safe)9. 常见问题与解决方案9.1 日志重复输出问题原因多次添加handler导致 解决方案# 在添加handler前先移除现有handler logger.handlers.clear() logger.addHandler(handler) # 或者检查是否已有handler if not logger.handlers: logger.addHandler(handler)9.2 日志不输出问题检查步骤确认logger的级别设置确认handler的级别设置确认handler是否添加到logger确认formatter是否正确设置9.3 多进程日志问题在多进程环境下基本的FileHandler会导致日志混乱。解决方案from logging.handlers import QueueHandler, QueueListener import multiprocessing def worker_process(queue): # 所有日志通过QueueHandler发送到主进程 qh QueueHandler(queue) logger logging.getLogger() logger.addHandler(qh) logger.setLevel(logging.INFO) logger.info(Message from worker) def main(): queue multiprocessing.Queue() # 主进程设置QueueListener处理所有日志 handler logging.FileHandler(multiprocess.log) listener QueueListener(queue, handler) listener.start() processes [] for i in range(3): p multiprocessing.Process(targetworker_process, args(queue,)) processes.append(p) p.start() for p in processes: p.join() listener.stop() if __name__ __main__: main()10. 实际项目中的日志策略10.1 开发环境与生产环境配置建议根据环境使用不同的日志配置import logging import sys def setup_logging(envdev): logger logging.getLogger() logger.setLevel(logging.DEBUG) if env dev: # 开发环境详细日志输出到控制台 handler logging.StreamHandler(sys.stdout) formatter logging.Formatter( %(asctime)s - %(name)s - %(levelname)s - %(message)s ) handler.setFormatter(formatter) else: # 生产环境关键日志输出到文件并按日轮转 from logging.handlers import TimedRotatingFileHandler handler TimedRotatingFileHandler( app.log, whenmidnight, backupCount7 ) formatter logging.Formatter( %(asctime)s - %(levelname)s - %(message)s ) handler.setFormatter(formatter) handler.setLevel(logging.INFO) logger.addHandler(handler)10.2 结构化日志对于需要日志分析的系统建议使用JSON格式import json import logging class JsonFormatter(logging.Formatter): def format(self, record): log_record { timestamp: self.formatTime(record), level: record.levelname, message: record.getMessage(), logger: record.name, module: record.module, function: record.funcName, line: record.lineno, } if record.exc_info: log_record[exception] self.formatException(record.exc_info) return json.dumps(log_record) # 使用示例 handler logging.StreamHandler() handler.setFormatter(JsonFormatter()) logger.addHandler(handler)10.3 审计日志对于需要记录用户操作的场景audit_logger logging.getLogger(audit) audit_logger.propagate False # 避免被root logger处理 audit_handler logging.FileHandler(audit.log) audit_formatter logging.Formatter( %(asctime)s %(user)s %(action)s %(status)s %(details)s ) audit_handler.setFormatter(audit_formatter) audit_logger.addHandler(audit_handler) # 记录审计日志 def log_audit_event(user, action, status, detailsNone): extra { user: user, action: action, status: status, details: details or } audit_logger.info(, extraextra)11. 测试中的日志处理11.1 单元测试中的日志验证可以使用MemoryHandler捕获日志进行验证import logging import unittest from io import StringIO class TestLogging(unittest.TestCase): def setUp(self): self.log_stream StringIO() handler logging.StreamHandler(self.log_stream) handler.setFormatter(logging.Formatter(%(levelname)s:%(message)s)) self.logger logging.getLogger(test) self.logger.addHandler(handler) self.logger.setLevel(logging.INFO) def test_log_output(self): self.logger.info(Test message) log_content self.log_stream.getvalue() self.assertIn(INFO:Test message, log_content)11.2 模拟日志记录使用unittest.mock可以模拟日志记录from unittest.mock import patch class TestWithMockLogging(unittest.TestCase): patch(logging.getLogger) def test_logging(self, mock_get_logger): mock_logger mock_get_logger.return_value # 测试代码 some_function_that_logs() # 验证日志调用 mock_logger.info.assert_called_with(Expected message)12. 与其他日志系统集成12.1 与系统日志集成在Linux系统上可以输出到syslogfrom logging.handlers import SysLogHandler syslog_handler SysLogHandler(address/dev/log) syslog_handler.setFormatter(logging.Formatter(%(name)s: %(message)s)) logger.addHandler(syslog_handler)12.2 与日志收集系统集成对于ELK、Splunk等日志收集系统可以使用相应的Handler# 示例使用HTTPHandler发送日志到Logstash from logging.handlers import HTTPHandler http_handler HTTPHandler( logstash.example.com:8080, /log, methodPOST ) logger.addHandler(http_handler)13. 自定义日志级别虽然不推荐但可以添加自定义日志级别TRACE 5 logging.addLevelName(TRACE, TRACE) def trace(self, message, *args, **kwargs): if self.isEnabledFor(TRACE): self._log(TRACE, message, args, **kwargs) logging.Logger.trace trace # 使用 logger.setLevel(TRACE) logger.trace(Very detailed trace message)14. 性能关键代码的日志优化对于性能敏感的代码可以使用延迟日志记录class LazyMessage: def __init__(self, func, *args, **kwargs): self.func func self.args args self.kwargs kwargs def __str__(self): return str(self.func(*self.args, **self.kwargs)) def expensive_operation(): # 模拟耗时操作 import time time.sleep(1) return Result # 只有在日志级别足够时才会调用expensive_operation logger.debug(Result: %s, LazyMessage(expensive_operation))15. 日志文件管理策略15.1 按时间轮转from logging.handlers import TimedRotatingFileHandler handler TimedRotatingFileHandler( app.log, whenmidnight, # 每天轮转 interval1, backupCount7 # 保留7天 )15.2 按大小轮转from logging.handlers import RotatingFileHandler handler RotatingFileHandler( app.log, maxBytes10*1024*1024, # 10MB backupCount5 )15.3 压缩旧日志import gzip import os from logging.handlers import RotatingFileHandler class CompressedRotatingFileHandler(RotatingFileHandler): def doRollover(self): super().doRollover() # 压缩除当前日志外的文件 for i in range(1, self.backupCount 1): logname f{self.baseFilename}.{i} if os.path.exists(logname): with open(logname, rb) as f_in: with gzip.open(f{logname}.gz, wb) as f_out: f_out.writelines(f_in) os.remove(logname)

相关新闻

C#邮件发送方案:从基础实现到高级应用

C#邮件发送方案:从基础实现到高级应用

1. C#发送Email的核心实现方案 在.NET生态中发送电子邮件主要有三种主流方案,每种方案都有其适用场景和优缺点: 1.1 System.Net.Mail命名空间 这是.NET Framework原生提供的邮件发送方案,无需依赖第三方库。核心类包括: MailMe…

2026/7/28 10:05:27 阅读更多 →
口碑好的UPVC门窗加工机器哪个口碑最佳

口碑好的UPVC门窗加工机器哪个口碑最佳

在门窗加工行业,UPVC门窗加工机器的口碑好坏直接关系到企业的生产效率和产品质量。那么,众多品牌中哪个口碑最佳呢?下面为您详细分析。市场口碑的重要衡量因素一款口碑好的UPVC门窗加工机器,通常在精度、稳定性、耐用性和售后服务…

2026/7/26 7:13:09 阅读更多 →
Matlab神经网络模型在Android端的部署与优化

Matlab神经网络模型在Android端的部署与优化

1. 神经网络在Matlab与Android混合编程中的核心挑战在移动端部署神经网络模型时,许多开发者会遇到一个典型困境:Matlab提供的神经网络工具箱训练效果优异,但生成的模型难以直接移植到Android平台。我曾在一个工业质检项目中深有体会——当尝试…

2026/7/26 22:44:17 阅读更多 →

最新新闻

真理映射型人工智能(TMAI)研究综述——基于鸽姆智库与贾子理论体系(KTS)的范式革命分析

真理映射型人工智能(TMAI)研究综述——基于鸽姆智库与贾子理论体系(KTS)的范式革命分析

真理映射型人工智能(TMAI)研究综述——基于鸽姆智库与贾子理论体系(KTS)的范式革命分析 摘要 真理映射型人工智能(Truth-Mapping AI,TMAI)是由鸽姆智库(GG3M Think Tank&#xff0…

2026/7/29 1:00:44 阅读更多 →
贾子时空缩微定律(KSTS)在后摩尔时代的统一作用:面向全球 AI 芯片、大模型与具身智能的文明级工程范式研究

贾子时空缩微定律(KSTS)在后摩尔时代的统一作用:面向全球 AI 芯片、大模型与具身智能的文明级工程范式研究

贾子时空缩微定律(KSTS)在后摩尔时代的统一作用:面向全球 AI 芯片、大模型与具身智能的文明级工程范式研究 The Unified Role of Jias Kinetic Spatiotemporal Scaling (KSTS) in the Post-Moore Era: A Civilizational-Level Engineering Pa…

2026/7/29 1:00:44 阅读更多 →
真理的异化与重构:基于贾子理论对主流学术范式的结构性批判及独立认知评价体系的建立

真理的异化与重构:基于贾子理论对主流学术范式的结构性批判及独立认知评价体系的建立

真理的异化与重构:基于贾子理论对主流学术范式的结构性批判及独立认知评价体系的建立摘要当代全球学术体系正面临一场深刻的认识论危机。本文基于“贾子理论”的核心框架,对以西方主流学术界为代表的现行科学范式进行了系统性的解构与批判。研究指出&…

2026/7/29 1:00:44 阅读更多 →
Codex 接入生产后,效率瓶颈竟在权限与日志?

Codex 接入生产后,效率瓶颈竟在权限与日志?

聊《一次Codex项目复盘,问题最后出在流程而不是模型》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。 摘要 本文基于一个真实项目复盘,探讨将 Codex 接入团队开发流程后的实际效果。重点分…

2026/7/29 1:00:44 阅读更多 →
大模型Demo遍地跑,为什么简历上没权限和日志就挂?

大模型Demo遍地跑,为什么简历上没权限和日志就挂?

聊《AI大模型就业怎么选方向?先回答几个现实问题》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要本文以一线工程实践为基准,拆解大模型应用从Demo到生产落地的关键门槛,特别…

2026/7/29 1:00:43 阅读更多 →
从起床到入睡,AI已接管你一天的12个关键节点(一线工程师私藏自动化清单)

从起床到入睡,AI已接管你一天的12个关键节点(一线工程师私藏自动化清单)

更多请点击: https://intelliparadigm.com 第一章:AI如何重塑人类日常节律 人工智能正悄然重构我们的时间感知与行为节奏——从清晨唤醒到深夜休憩,AI不再仅是工具,而是嵌入生活肌理的“节律协作者”。智能助手根据用户历史睡眠数…

2026/7/29 0:59:43 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻