当前位置:首页 > 科技  > 软件

为什么不推荐使用Python原生日志库?

来源: 责编: 时间:2023-11-06 17:19:10 182观看
导读包括我在内的大多数人,当编写小型脚本时,习惯使用print来debug,肥肠方便,这没问题,但随着代码不断完善,日志功能一定是不可或缺的,极大程度方便问题溯源以及甩锅,也是每个工程师必备技能。Python自带的logging我个人不推介使

包括我在内的大多数人,当编写小型脚本时,习惯使用print来debug,肥肠方便,这没问题,但随着代码不断完善,日志功能一定是不可或缺的,极大程度方便问题溯源以及甩锅,也是每个工程师必备技能。DS628资讯网——每日最新资讯28at.com

Python自带的logging我个人不推介使用,不太Pythonic,而开源的Loguru库成为众多工程师及项目中首选,本期将同时对logging及Loguru进行使用对比,希望有所帮助。DS628资讯网——每日最新资讯28at.com

DS628资讯网——每日最新资讯28at.com

快速示例

在logging中,默认的日志功能输出的信息较为有限:DS628资讯网——每日最新资讯28at.com

import logginglogger = logging.getLogger(__name__)def main():    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")if __name__ == "__main__":    main()

输出(logging默认日志等级为warning,故此处未输出info与debug等级的信息):DS628资讯网——每日最新资讯28at.com

WARNING:root:This is a warning messageERROR:root:This is an error message

再来看看loguru,默认生成的信息就较为丰富了:DS628资讯网——每日最新资讯28at.com

from loguru import loggerdef main():    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")if __name__ == "__main__":    main()

DS628资讯网——每日最新资讯28at.com

提供了执行时间、等级、在哪个函数调用、具体哪一行等信息。DS628资讯网——每日最新资讯28at.com

格式化日志

格式化日志允许我们向日志添加有用的信息,例如时间戳、日志级别、模块名称、函数名称和行号。DS628资讯网——每日最新资讯28at.com

在logging中使用%达到格式化目的:DS628资讯网——每日最新资讯28at.com

import logging# Create a logger and set the logging levellogging.basicConfig(    level=logging.INFO,    format="%(asctime)s | %(levelname)s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",    datefmt="%Y-%m-%d %H:%M:%S",)logger = logging.getLogger(__name__)def main():    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")

输出:DS628资讯网——每日最新资讯28at.com

2023-10-18 15:47:30 | INFO | tmp:<module>:186 - This is an info message2023-10-18 15:47:30 | WARNING | tmp:<module>:187 - This is a warning message2023-10-18 15:47:30 | ERROR | tmp:<module>:188 - This is an error message

而loguru使用和f-string相同的{}格式,更方便:DS628资讯网——每日最新资讯28at.com

from loguru import loggerlogger.add(    sys.stdout,    level="INFO",    format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{function}:{line} - {message}",)

日志保存

在logging中,实现日志保存与日志打印需要两个额外的类,FileHandler 和 StreamHandler:DS628资讯网——每日最新资讯28at.com

import logginglogging.basicConfig(    level=logging.DEBUG,    format="%(asctime)s | %(levelname)s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",    datefmt="%Y-%m-%d %H:%M:%S",    handlers=[        logging.FileHandler(filename="/your/save/path/info.log", level=logging.INFO),        logging.StreamHandler(level=logging.DEBUG),    ],)logger = logging.getLogger(__name__)def main():    logging.debug("This is a debug message")    logging.info("This is an info message")    logging.warning("This is a warning message")    logging.error("This is an error message")if __name__ == "__main__":    main()

但是在loguru中,只需要使用add方法即可达到目的:DS628资讯网——每日最新资讯28at.com

from loguru import loggerlogger.add(    'info.log',    format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{function}:{line} - {message}",    level="INFO",)def main():    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")if __name__ == "__main__":    main()

日志轮换

日志轮换指通过定期创建新的日志文件并归档或删除旧的日志来防止日志变得过大。DS628资讯网——每日最新资讯28at.com

在logging中,需要一个名为 TimedRotatingFileHandler 的附加类,以下代码示例代表每周切换到一个新的日志文件 ( when=“WO”, interval=1 ),并保留最多 4 周的日志文件 ( backupCount=4 ):DS628资讯网——每日最新资讯28at.com

import loggingfrom logging.handlers import TimedRotatingFileHandlerlogger = logging.getLogger(__name__)logger.setLevel(logging.DEBUG)# Create a formatter with the desired log formatformatter = logging.Formatter(    "%(asctime)s | %(levelname)-8s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",    datefmt="%Y-%m-%d %H:%M:%S",)file_handler = TimedRotatingFileHandler(    filename="debug2.log", when="WO", interval=1, backupCount=4)file_handler.setLevel(logging.INFO)file_handler.setFormatter(formatter)logger.addHandler(file_handler)def main():    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")if __name__ == "__main__":    main()

在loguru中,可以通过将 rotation 和 retention 参数添加到 add 方法来达到目的,如下示例,同样肥肠方便:DS628资讯网——每日最新资讯28at.com

from loguru import loggerlogger.add("debug.log", level="INFO", rotation="1 week", retention="4 weeks")def main():    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")if __name__ == "__main__":    main()

日志筛选

日志筛选指根据特定条件有选择的控制应输出与保存哪些日志信息。DS628资讯网——每日最新资讯28at.com

在logging中,实现该功能需要创建自定义日志过滤器类:DS628资讯网——每日最新资讯28at.com

import logginglogging.basicConfig(    filename="test.log",    format="%(asctime)s | %(levelname)-8s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",    level=logging.INFO,)class CustomFilter(logging.Filter):    def filter(self, record):        return "Cai Xukong" in record.msg# Create a custom logging filtercustom_filter = CustomFilter()# Get the root logger and add the custom filter to itlogger = logging.getLogger()logger.addFilter(custom_filter)def main():    logger.info("Hello Cai Xukong")    logger.info("Bye Cai Xukong")if __name__ == "__main__":    main()

在loguru中,可以简单地使用lambda函数来过滤日志:DS628资讯网——每日最新资讯28at.com

from loguru import loggerlogger.add("test.log", filter=lambda x: "Cai Xukong" in x["message"], level="INFO")def main():    logger.info("Hello Cai Xukong")    logger.info("Bye Cai Xukong")if __name__ == "__main__":    main()

捕获异常

在logging中捕获异常较为不便且难以调试,如:DS628资讯网——每日最新资讯28at.com

import logginglogging.basicConfig(    level=logging.DEBUG,    format="%(asctime)s | %(levelname)s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",    datefmt="%Y-%m-%d %H:%M:%S",)def division(a, b):    return a / bdef nested(c):    try:        division(1, c)    except ZeroDivisionError:        logging.exception("ZeroDivisionError")if __name__ == "__main__":    nested(0)
Traceback (most recent call last):  File "logging_example.py", line 16, in nested    division(1, c)  File "logging_example.py", line 11, in division    return a / bZeroDivisionError: division by zero

上面输出的信息未提供触发异常的c值信息,而在loguru中,通过显示包含变量值的完整堆栈跟踪来方便用户识别:DS628资讯网——每日最新资讯28at.com

Traceback (most recent call last):  File "logging_example.py", line 16, in nested    division(1, c)  File "logging_example.py", line 11, in division    return a / bZeroDivisionError: division by zero

DS628资讯网——每日最新资讯28at.com

值得一提的是,loguru中的catch装饰器允许用户捕获函数内任何错误,且还会标识发生错误的线程:DS628资讯网——每日最新资讯28at.com

from loguru import loggerdef division(a, b):    return a / b@logger.catchdef nested(c):    division(1, c)if __name__ == "__main__":    nested(0)

DS628资讯网——每日最新资讯28at.com

OK,作为普通玩家以上功能足以满足日常日志需求,通过对比logging与loguru应该让大家有了直观感受,哦对了,loguru如何安装?DS628资讯网——每日最新资讯28at.com

pip install loguru

以上就是本期的全部内容,期待点赞在看,我是啥都生,下次再见。DS628资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-17257-0.html为什么不推荐使用Python原生日志库?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 如何将Docker的构建时间减少40%

下一篇: Gorm 中的迁移指南

标签:
  • 热门焦点
  • 5月iOS设备好评榜:iPhone 14仅排第43?

    5月iOS设备好评榜:iPhone 14仅排第43?

    来到新的一月,安兔兔的各个榜单又重新汇总了数据,像安卓阵营的榜单都有着比较大的变动,不过iOS由于设备的更新换代并没有那么快,所以相对来说变化并不大,特别是iOS好评榜,老款设
  • 轿车从天而降电动车主被撞身亡 超速抢道所致:现场视频让网友吵翻

    轿车从天而降电动车主被撞身亡 超速抢道所致:现场视频让网友吵翻

    近日,上海青浦区法院判决轿车从天而降电动车主被撞身亡案,轿车车主被判有期徒刑一年。案件显示当时男子驾驶轿车在上海某路段行驶,前车忽然转弯提速超车,
  • 使用LLM插件从命令行访问Llama 2

    使用LLM插件从命令行访问Llama 2

    最近的一个大新闻是Meta AI推出了新的开源授权的大型语言模型Llama 2。这是一项非常重要的进展:Llama 2可免费用于研究和商业用途。(几小时前,swyy发现它已从LLaMA 2更名为Lla
  • 为什么你不应该使用Div作为可点击元素

    为什么你不应该使用Div作为可点击元素

    按钮是为任何网络应用程序提供交互性的最常见方式。但我们经常倾向于使用其他HTML元素,如 div span 等作为 clickable 元素。但通过这样做,我们错过了许多内置浏览器的功能。
  • 腾讯盖楼,字节拆墙

    腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之&ldquo;想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!&rdquo;曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • 阿里大调整

    阿里大调整

    来源:产品刘有媒体报道称,近期淘宝天猫集团启动了近年来最大的人力制度改革,涉及员工绩效、层级体系等多个核心事项,目前已形成一个初步的&ldquo;征求意见版&rdquo;:1、取消P序列
  • 消息称小米汽车开始筛选交付中心:需至少120个车位

    消息称小米汽车开始筛选交付中心:需至少120个车位

    IT之家 7 月 7 日消息,日前,有微博简介为“汽车行业从业者、长三角一体化拥护者”的微博用户 @长三角行健者 发文表示,据经销商集团反馈,小米汽车目前
  • iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
  • 引领旗舰级影像能力向中端机普及 OPPO K11 系列发布 1799 元起

    引领旗舰级影像能力向中端机普及 OPPO K11 系列发布 1799 元起

    7月25日,OPPO正式发布K系列新品—— OPPO K11 。此次 K11 在中端手机市场长期被忽视的影像板块发力,突破性地搭载索尼 IMX890 旗舰大底主摄,支持 OIS
Top