文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用loguru优雅的输出日志

2024-12-02 17:04

关注

loguru 是一个 Python 简易且强大的第三方日志记录库,该库旨在通过添加一系列有用的功能来解决标准记录器的注意事项,从而减少 Python 日志记录的痛苦。

1. 引入原因

简单且方便的帮助我们输出需要的日志信息!

  1. import logging  
  2. logger = logging.getLogger('xxx')  
  3. handler = logging.StreamHandler()  
  4. formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')  
  5. handler.setFormatter(formatter)  
  6. logger.addHandler(handler)  
  7. logger.setLevel(logging.DEBUG)  
  8. logger.debug('This is a %s', 'test') 
  1. # pip  
  2. $ pip install loguru 

2. 功能特性

有很多优点,以下列举了其中比较重要的几点!

3. 快速上手

介绍 loguru 的常用操作和功能介绍!

[1] 开箱即用,无需准备

  1. from loguru import logger  
  2. logger.debug("That's it, beautiful and simple logging!")  

[2] 无需初始化,导入函数即可使用

  1. # add  
  2. logger.add(sys.stderr, \  
  3.     format="{time} {level} {message}",\  
  4.     filter="my_module",\  
  5.     level="INFO"

[3] 更容易的文件日志记录与转存/保留/压缩方式 

  1. # 日志文件记录  
  2. logger.add("file_{time}.log")  
  3. # 日志文件转存  
  4. logger.add("file_{time}.log", rotation="500 MB" 
  5. logger.add("file_{time}.log", rotation="12:00" 
  6. logger.add("file_{time}.log", rotation="1 week" 
  7. # 多次时间之后清理  
  8. logger.add("file_X.log", retention="10 days" 
  9. # 使用zip文件格式保存  
  10. logger.add("file_Y.log", compression="zip"

[4] 更优雅的字符串格式化输出 

  1. logger.info(  
  2.     "If you're using Python {}, prefer {feature} of course!",  
  3.     3.6, feature="f-strings"

[5] 在线程或主线程中捕获异常 

  1. @logger.catch  
  2. def my_function(x, y, z):  
  3.     # An error? It's caught anyway!  
  4.     return 1 / (x + y + z)  
  5. my_function(0, 0, 0) 

[6] 可以设置不同级别的日志记录样式

  1. logger.add(sys.stdout,  
  2.     colorize=True 
  3.     format="{time} {message}" 
  4. logger.add('logs/z_{time}.log',  
  5.            level='DEBUG' 
  6.            format='{time:YYYY-MM-DD :mm:ss} - {level} - {file} - {line} - {message}' 
  7.            rotation="10 MB"

[7] 支持异步且线程和多进程安全

  1. # 异步写入  
  2. logger.add("some_file.log", enqueue=True 

[8] 异常的完整性描述

  1. logger.add("out.log", backtrace=Truediagnose=True 
  2. def func(a, b):  
  3.     return a / b  
  4. def nested(c):  
  5.     try:  
  6.         func(5, c)  
  7.     except ZeroDivisionError:  
  8.         logger.exception("What?!")  
  9. nested(0) 

[9] 结构化日志记录

  1. # 序列化为json格式  
  2. logger.add(custom_sink_function, serialize=True 
  3. # bind方法的用处  
  4. logger.add("file.log", format="{extra[ip]} {extra[user]} {message}" 
  5. context_logger = logger.bind(ip="192.168.0.1"user="someone" 
  6. context_logger.info("Contextualize your logger easily")  
  7. context_logger.bind(user="someone_else").info("Inline binding of extra attribute")  
  8. context_logger.info("Use kwargs to add context during formatting: {user}", user="anybody" 
  9. # 粒度控制  
  10. logger.add("special.log", filter=lambda record: "special" in record["extra"])  
  11. logger.debug("This message is not logged to the file")  
  12. logger.bind(special=True).info("This message, though, is logged to the file!")  
  13. # patch()方法的用处  
  14. logger.add(sys.stderr, format="{extra[utc]} {message}" 
  15. loggerlogger = logger.patch(lambda record: record["extra"].update(utc=datetime.utcnow())) 

[10] 惰性计算

  1. logger.opt(lazy=True).debug("If sink level <= DEBUG: {x}", x=lambda: expensive_function(2**64))  
  2. # By the way, "opt()" serves many usages  
  3. logger.opt(exception=True).info("Error stacktrace added to the log message (tuple accepted too)")  
  4. logger.opt(colors=True).info("Per message <blue>colorsblue>")  
  5. logger.opt(record=True).info("Display values from the record (eg. {record[thread]})")  
  6. logger.opt(raw=True).info("Bypass sink formatting\n")  
  7. logger.opt(depth=1).info("Use parent stack context (useful within wrapped functions)")  
  8. logger.opt(capture=False).info("Keyword arguments not added to {dest} dict", dest="extra"

[11] 可定制的级别 

  1. new_level = logger.level("SNAKY", no=38color=""icon="🐍" 
  2. logger.log("SNAKY", "Here we go!") 

[12] 适用于脚本和库 

  1. # For scripts  
  2. config = {  
  3.     "handlers": [  
  4.         {"sink": sys.stdout, "format": "{time} - {message}"},  
  5.         {"sink": "file.log", "serialize": True},  
  6.     ],  
  7.     "extra": {"user": "someone"}  
  8.  
  9. logger.configure(**config)  
  10. # For libraries  
  11. logger.disable("my_library")  
  12. logger.info("No matter added sinks, this message is not displayed")  
  13. logger.enable("my_library")  
  14. logger.info("This message however is propagated to the sinks") 

[13] 完全兼容标准日志记录

  1. handler = logging.handlers.SysLogHandler(address=('localhost', 514)) 
  2. logger.add(handler)  
  1. class PropagateHandler(logging.Handler):  
  2.     def emit(self, record):  
  3.         logging.getLogger(record.name).handle(record)  
  4. logger.add(PropagateHandler(), format="{message}" 
  1. class InterceptHandler(logging.Handler):  
  2.     def emit(self, record):  
  3.         # Get corresponding Loguru level if it exists  
  4.         try:  
  5.             level = logger.level(record.levelname).name  
  6.         except ValueError:  
  7.             level = record.levelno  
  8.         # Find caller from where originated the logged message  
  9.         frame, depth = logging.currentframe(), 2  
  10.         while frame.f_code.co_filename == logging.__file__:  
  11.             frameframe = frame.f_back  
  12.             depth += 1  
  13.         logger.opt(depthdepth=depth, exception=record.exc_info).log(level, record.getMessage())  
  14. logging.basicConfig(handlers=[InterceptHandler()], level=0

[14] 方便的解析器

  1. pattern = r"(?P  # Regex with named groups  
  2. caster_dict = dict(time=dateutil.parser.parse, level=int)        # Transform matching groups  
  3. for groups in logger.parse("file.log", pattern, cast=caster_dict):  
  4.     print("Parsed:", groups) 
  5.     # {"level": 30, "message": "Log example", "time": datetime(2018, 12, 09, 11, 23, 55)} 

[15] 通知机制 

  1. import notifiers  
  2. params = {  
  3.     "username": "you@gmail.com",  
  4.     "password": "abc123",  
  5.     "to": "dest@gmail.com"  
  6.  
  7. # Send a single notification  
  8. notifier = notifiers.get_notifier("gmail")  
  9. notifier.notify(message="The application is running!", **params)  
  10. # Be alerted on each error message  
  11. from notifiers.logging import NotificationHandler  
  12. handler = NotificationHandler("gmail", defaults=params 
  13. logger.add(handler, level="ERROR"

[16] Flask 框架集成

  1. import logging  
  2. import sys  
  3. from pathlib import Path  
  4. from flask import Flask  
  5. from loguru import logger  
  6. app = Flask(__name__)  
  7. class InterceptHandler(logging.Handler):  
  8.     def emit(self, record):  
  9.         loggerlogger_opt = logger.opt(depth=6exception=record.exc_info)  
  10.         logger_opt.log(record.levelname, record.getMessage())  
  11. def configure_logging(flask_app: Flask):  
  12.     """配置日志"""  
  13.     path = Path(flask_app.config['LOG_PATH'])  
  14.     if not path.exists():  
  15.         path.mkdir(parents=True 
  16.     log_name = Path(path, 'sips.log')  
  17.     logging.basicConfig(handlers=[InterceptHandler(level='INFO')], level='INFO' 
  18.     # 配置日志到标准输出流  
  19.     logger.configure(handlers=[{"sink": sys.stderr, "level": 'INFO'}])  
  20.     # 配置日志到输出到文件  
  21.     logger.add(log_name, rotation="500 MB"encoding='utf-8'colorize=Falselevel='INFO'

4. 要点解析

介绍,主要函数的使用方法和细节 - add()的创建和删除

  1. def add(self, sink, *,  
  2.     level=_defaults.LOGURU_LEVEL, format=_defaults.LOGURU_FORMAT,  
  3.     filter=_defaults.LOGURU_FILTER, colorize=_defaults.LOGURU_COLORIZE,  
  4.     serialize=_defaults.LOGURU_SERIALIZE, backtrace=_defaults.LOGURU_BACKTRACE,  
  5.     diagnose=_defaults.LOGURU_DIAGNOSE, enqueue=_defaults.LOGURU_ENQUEUE,  
  6.     catch=_defaults.LOGURU_CATCH, **kwargs  
  7. ): 
  1. from loguru import logger  
  2. trace = logger.add('runtime.log')  
  3. logger.debug('this is a debug message')  
  4. logger.remove(trace)  
  5. logger.debug('this is another debug message')  

 

来源:马哥Linux运维内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯