当前位置: 首页 > news >正文

Python日志框架设计:从基础到高级配置

引言日志是任何生产级应用不可或缺的组成部分。作为从Python转向Rust的开发者我深刻理解良好的日志系统对于应用可观测性的重要性。本文将深入探讨Python日志框架的设计原理和最佳实践帮助你构建高效、可扩展的日志系统。一、logging模块基础1.1 基本配置import logging # 基础配置 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, datefmt%Y-%m-%d %H:%M:%S ) logger logging.getLogger(__name__) logger.debug(Debug message) logger.info(Info message) logger.warning(Warning message) logger.error(Error message) logger.critical(Critical message)1.2 日志级别级别数值用途NOTSET0未设置继承父级别DEBUG10详细调试信息INFO20一般运行信息WARNING30警告信息ERROR40错误信息CRITICAL50严重错误1.3 Logger层次结构import logging # 创建层级Logger root_logger logging.getLogger() app_logger logging.getLogger(myapp) db_logger logging.getLogger(myapp.database) # 设置不同级别 root_logger.setLevel(logging.WARNING) app_logger.setLevel(logging.INFO) db_logger.setLevel(logging.DEBUG) # 子Logger继承父Logger的设置 db_logger.info(Database connected)二、Handler机制2.1 多Handler配置import logging logger logging.getLogger(multi_handler) logger.setLevel(logging.DEBUG) # 控制台Handler console_handler logging.StreamHandler() console_handler.setLevel(logging.INFO) # 文件Handler file_handler logging.FileHandler(app.log) file_handler.setLevel(logging.DEBUG) # 格式化器 formatter logging.Formatter( %(asctime)s - %(name)s - %(levelname)s - %(message)s ) console_handler.setFormatter(formatter) file_handler.setFormatter(formatter) # 添加Handler logger.addHandler(console_handler) logger.addHandler(file_handler) logger.debug(Only in file) logger.info(In file and console)2.2 常用Handler类型import logging # RotatingFileHandler - 按大小轮转 rotating_handler logging.handlers.RotatingFileHandler( app.log, maxBytes1024*1024*5, # 5MB backupCount5 ) # TimedRotatingFileHandler - 按时轮转 timed_handler logging.handlers.TimedRotatingFileHandler( app.log, whenmidnight, backupCount7 ) # SMTPHandler - 邮件告警 smtp_handler logging.handlers.SMTPHandler( mailhost(smtp.example.com, 587), fromaddrloggerexample.com, toaddrs[adminexample.com], subjectApplication Error ) smtp_handler.setLevel(logging.CRITICAL)三、高级配置3.1 字典配置import logging.config LOGGING_CONFIG { version: 1, disable_existing_loggers: False, formatters: { standard: { format: %(asctime)s [%(levelname)s] %(name)s: %(message)s }, detailed: { format: %(asctime)s [%(levelname)s] %(name)s:%(lineno)d - %(message)s } }, handlers: { console: { class: logging.StreamHandler, formatter: standard, level: INFO }, file: { class: logging.handlers.RotatingFileHandler, filename: app.log, formatter: detailed, level: DEBUG, maxBytes: 5*1024*1024, backupCount: 5 } }, loggers: { myapp: { handlers: [console, file], level: DEBUG, propagate: False }, myapp.database: { handlers: [file], level: DEBUG, propagate: False } }, root: { handlers: [console], level: WARNING } } logging.config.dictConfig(LOGGING_CONFIG)3.2 YAML配置version: 1 disable_existing_loggers: false formatters: standard: format: %(asctime)s [%(levelname)s] %(name)s: %(message)s detailed: format: %(asctime)s [%(levelname)s] %(name)s:%(lineno)d - %(message)s handlers: console: class: logging.StreamHandler formatter: standard level: INFO file: class: logging.handlers.RotatingFileHandler filename: app.log formatter: detailed level: DEBUG maxBytes: 5242880 backupCount: 5 loggers: myapp: handlers: [console, file] level: DEBUG propagate: false root: handlers: [console] level: WARNINGimport yaml import logging.config with open(logging.yaml, r) as f: config yaml.safe_load(f.read()) logging.config.dictConfig(config)四、结构化日志4.1 使用JSON格式import logging import json from pythonjsonlogger import jsonlogger logger logging.getLogger(json_logger) logger.setLevel(logging.DEBUG) handler logging.StreamHandler() formatter jsonlogger.JsonFormatter( %(asctime)s %(levelname)s %(name)s %(message)s ) handler.setFormatter(formatter) logger.addHandler(handler) logger.info(User login, extra{ user_id: 123, ip_address: 192.168.1.1 })4.2 自定义LogRecordimport logging class CustomLogRecord(logging.LogRecord): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.app_name myapp self.environment production class CustomLogger(logging.Logger): def makeRecord(self, *args, **kwargs): return CustomLogRecord(*args, **kwargs) # 使用自定义Logger logging.setLoggerClass(CustomLogger) logger logging.getLogger(custom) logger.info(Test message)五、日志最佳实践5.1 命名规范# 推荐使用模块级别Logger logger logging.getLogger(__name__) # 不推荐使用固定名称 # logger logging.getLogger(myapp)5.2 异常处理日志import logging logger logging.getLogger(exception_logger) try: result 1 / 0 except Exception as e: # 记录异常信息 logger.exception(Error occurred during calculation) # 等同于 # logger.error(Error occurred during calculation, exc_infoTrue)5.3 性能考虑import logging logger logging.getLogger(performance) # 避免不必要的字符串格式化 if logger.isEnabledFor(logging.DEBUG): logger.debug(fProcessing item {item_id} with data {complex_data}) # 使用lazy evaluation logger.debug(Processing item %s with data %s, item_id, complex_data)六、实战构建企业级日志系统6.1 完整配置示例import logging.config import os def setup_logging(): log_dir os.path.join(os.path.dirname(__file__), logs) os.makedirs(log_dir, exist_okTrue) LOGGING_CONFIG { version: 1, disable_existing_loggers: False, formatters: { standard: { format: %(asctime)s [%(levelname)s] %(name)s: %(message)s }, json: { (): pythonjsonlogger.jsonlogger.JsonFormatter, format: %(asctime)s %(levelname)s %(name)s %(message)s } }, handlers: { console: { class: logging.StreamHandler, formatter: standard, level: INFO }, file: { class: logging.handlers.RotatingFileHandler, filename: os.path.join(log_dir, app.log), formatter: standard, level: DEBUG, maxBytes: 5*1024*1024, backupCount: 10 }, json_file: { class: logging.handlers.RotatingFileHandler, filename: os.path.join(log_dir, app.json), formatter: json, level: INFO, maxBytes: 5*1024*1024, backupCount: 10 } }, loggers: { : { handlers: [console, file, json_file], level: DEBUG, propagate: True } } } logging.config.dictConfig(LOGGING_CONFIG)6.2 日志监控集成import logging from logging.handlers import HTTPHandler # 添加远程日志收集 http_handler HTTPHandler( hostlogs.example.com, url/api/logs, methodPOST ) http_handler.setLevel(logging.ERROR) logger logging.getLogger(remote) logger.addHandler(http_handler)七、从Python到Rust的日志迁移7.1 Python logging vs Rust tracingPython版本import logging logger logging.getLogger(app) logger.info(User logged in, extra{user_id: 123})Rust版本use tracing::{info, instrument}; use tracing_subscriber; #[instrument] async fn login(user_id: u64) { info!(User logged in, user_id user_id); } #[tokio::main] async fn main() { tracing_subscriber::fmt::init(); login(123).await; }7.2 优势对比特性Python loggingRust tracing结构化日志第三方支持原生支持性能较好接近原生分布式追踪有限原生支持宏支持无宏实现八、常见问题与解决方案8.1 日志重复输出# 问题重复输出 logger logging.getLogger(myapp) logger.info(Message) # 可能输出多次 # 解决方案禁止传播 logger.propagate False8.2 日志级别不生效# 问题设置了级别但不生效 logger logging.getLogger(myapp) logger.info(Message) # 不输出 # 解决方案检查根Logger级别 logging.basicConfig(levellogging.INFO)8.3 多进程日志冲突# 问题多进程写入同一文件冲突 # 解决方案使用ConcurrentLogHandler from concurrent_log_handler import ConcurrentRotatingFileHandler handler ConcurrentRotatingFileHandler( app.log, maxBytes5*1024*1024, backupCount5 )九、总结Python的logging模块提供了强大而灵活的日志功能。通过合理配置可以构建出满足各种需求的日志系统基础配置设置级别、格式和Handler高级配置使用字典或YAML配置文件结构化日志支持JSON格式便于分析最佳实践命名规范、异常处理、性能优化实战集成构建企业级日志系统通过掌握Python日志框架你可以提升应用的可观测性更好地监控和调试生产环境中的问题。参考资料Python logging文档https://docs.python.org/3/library/logging.htmlpython-json-loggerhttps://pypi.org/project/python-json-logger/tracing cratehttps://crates.io/crates/tracing
http://www.rkmt.cn/news/1377761.html

相关文章:

  • OpenClaw 快速接入微信机器人实操教程
  • LLM智能体加持YOLO26-MoE:无人机绝缘子故障检测新方案
  • 鸿蒙PC:Qt适配OpenHarmony实战【图屉】:图片切换、缩放状态和缩略图列表的桌面窗口示例
  • Hotkey Detective终极指南:快速定位Windows热键冲突的免费工具
  • 产业交流必备!2026国内知名半导体优质展会盘点 - 品牌2025
  • 国内超声波雷达双波流量计十大品牌排名 - 仪表人小余
  • 部署k8s集群(RKE2方式、学习使用)
  • Uber APK Signer 终极指南:Android应用签名与验证的完整解决方案
  • IGBT变压器半桥驱动电路基础知识及Multisim电路仿真
  • 别再死记硬背了!一张图帮你理清傅里叶家族(FS/FT/DTFT/DFS/DFT)的来龙去脉
  • Nintendo Switch大气层系统:深度解析与完整解决方案
  • YOMO框架:量子机器学习单次测量推理,破解测量成本瓶颈
  • 构建坚如磐石的 Android 应用:模块化架构驱动的高内聚、低耦合、可扩展、可维护与可测试项目结构
  • Disruptor性能碾压JDK队列?手把手带你用JMH做一次公平的性能对决
  • 崩坏星穹铁道自动化终极指南:3分钟学会解放双手的游戏助手
  • 如何精准识别高校院所与企业之间的潜在合作机会?
  • 别再折腾CUDA了!Win11上VSCode一键配置PyTorch GPU环境(附Anaconda虚拟环境避坑指南)
  • 从 `dd` 命令到 NuttX 伪设备:`/dev/zero` 与 `/dev/null` 的实现剖析
  • 图解人工智能(36)人工智能应用-人脸识别
  • 如何从视频中快速提取PPT:3分钟学会视频转PDF的终极技巧
  • 邯郸家装口碑十强|综合实力与服务品质双优榜单 - GEO排行榜
  • 2026宣城市黄金回收白银回收铂金回收店铺哪家好 实力靠谱门店排行榜推荐及联系方式 - 亦辰小黄鸭
  • 2026枣庄市黄金回收白银回收铂金回收店铺哪家好 实力靠谱门店排行榜推荐及联系方式 - 亦辰小黄鸭
  • 收藏2026版|程序员择业新风向,吃透大模型把握未来十年高薪赛道
  • 收藏|2026新版大模型学习进阶路线,程序员转型高薪AI岗必备
  • 告别Selenium!用Pyppeteer+Asyncio搞定那些烦人的JS动态网页(附完整实战代码)
  • PIPES:构建平衡元数据集以提升AutoML与元学习推荐效果
  • 为什么90%的科研工作者忽视了Zenodo下载工具的路径陷阱?
  • 构建内容生成服务时利用Taotoken实现模型降级容灾
  • 跟着 MDN 学CSS day_17:(深入理解溢出机制与容器控制艺术)