Python方便又强大的日志记录器——loguru

Python方便又强大的日志记录器——loguru

Loguru是一个旨在使Python日志记录变得愉快的库。该库通过添加一系列有用的功能来解决标准记录器的警告,从而减少Python日志记录的痛苦。

日志记录对每个应用程序都是基本的,它简化了调试过程。在应用程序中使用日志应该是一种自动化,Loguru试图让它既愉快又强大。

优点:

  • loguru的核心是只有一个记录器,默认是stderr

  • 记录器只是一个接口,它将日志消息分派给已配置的处理程序。如何添加处理程序?如何设置日志格式?如何过滤邮件?如何设置级别? 答案:add()函数
    logger.add(sys.stderr, format=“{time} {level} {message}”, filter=“my_module”, level=“INFO”)

  • 取代默认的stderr处理程序,只需调用logger.remove()

  • 将日志记录到文件
    logger.add(“file_{time}.log”)
    logger.add(“file_1.log”, rotation=“500 MB”) # 文件过大时自动滚动
    logger.add(“file_2.log”, rotation=“12:00”) # 每天中午12:00创建新文件
    logger.add(“file_3.log”, rotation=“1 week”) # 超过一周,自动创建新文件
    logger.add(“file_X.log”, retention=“10 days”) # 一段时间10天后清除
    logger.add(“file_Y.log”, compression=“zip”) # 压缩节省空间
    logger.info(“If you’re using Python {}, prefer {feature} of course!”, 3.6, feature=“f-strings”) # 有比%更强大的格式化,{}占位符

  • 线程或主线程内异常捕获
    @logger.catch
    def my_function(x, y, z):
    return 1 / (x + y + z)

  • 用颜色记录日志
    logger.add(sys.stdout, colorize=True, format=“{time} {message}”)

  • 异步,进程安全,多线程安全的记录日志,通过排队的方式记录日志
    logger.add(“somefile.log”, enqueue=True)

  • 希望日志序列化以便于分析或传递:使用serialize参数,每个日志消息将在发送到配置的接收器之前转换为JSON字符串。
    logger.add(custom_sink_function, serialize=True)

  • 使用bind记录日志上下文
    logger.add(“file.log”, format=“{extra[ip]} {extra[user]} {message}”)
    context_logger = logger.bind(ip=“192.168.0.1”, user=“someone”)
    context_logger.info(“Contextualize your logger easily”)
    context_logger.bind(user=“someone_else”).info(“Inline binding of extra attribute”)
    context_logger.info(“Use kwargs to add context during formatting: {user}”, user=“anybody”)

  • 使用contextualize()临时修改上下文本地状态:

  • 通过结合bind()和filter,可以对日志进行更细粒度的控制:
    logger.add(“special.log”, filter=lambda record: “special” in record[“extra”])
    logger.debug(“This message is not logged to the file”)
    logger.bind(special=True).info(“This message, though, is logged to the file!”)

  • patch()方法允许动态值附加到每个新消息的记录dict
    logger.add(sys.stderr, format=“{extra[utc]} {message}”)
    logger = logger.patch(lambda record: record[“extra”].update(utc=datetime.utcnow()))

  • 希望在生产中记录详细信息而不降低性能,可以使用opt()方法来实现这一点
    logger.opt(lazy=True).debug(“If sink level <= DEBUG: {x}”, x=lambda: expensive_function(2 ** 64))

  • opt()有很多用途
    logger.opt(exception=True).info(“Error stacktrace added to the log message (tuple accepted too)”) # 错误堆栈跟踪添加到日志消息
    logger.opt(colors=True).info(“Per message colors”)
    logger.opt(record=True).info(“Display values from the record (eg. {record[thread]})”)
    logger.opt(raw=True).info(“Bypass sink formatting\n”)
    logger.opt(depth=1).info(“Use parent stack context (useful within wrapped functions)”)
    logger.opt(capture=False).info(“Keyword arguments not added to {dest} dict”, dest=“extra”)

    new_level = logger.level(“SNAKY”, no=38, color=“”, icon=“🐍”)
    logger.log(“SNAKY”, “Here we go!”)

  • 更好的时间日期处理
    logger.add(“file.log”, format=“{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}”)

  • 脚本的日志记录器示例
    config = {
    “handlers”: [
    {“sink”: sys.stdout, “format”: “{time} - {message}”},
    {“sink”: “file.log”, “serialize”: True},
    ],
    “extra”: {“user”: “someone”}
    }
    logger.configure(**config)

  • 库的日志记录器
    logger.disable(“my_library”)
    logger.info(“No matter added sinks, this message is not displayed”)
    logger.enable(“my_library”)
    logger.info(“This message however is propagated to the sinks”)

  • 与标准日志库兼容:希望将内置日志处理程序用作Loguru接收器
    handler = logging.handlers.SysLogHandler(address=(‘localhost’, 514))
    logger.add(handler)

  • 拦截向Loguru接收器发送的标准日志消息

  • 详尽的通知者:Loguru可以很容易地与强大的通知程序库(必须单独安装)相结合,以便在程序意外失败时接收电子邮件或发送许多其他类型的通知。
    import notifiers

    params = {
    “username”: “you@gmail.com”,
    “password”: “abc123”,
    “to”: “dest@gmail.com”
    }

  • 发送一条单独提醒
    notifier = notifiers.get_notifier(“gmail”)
    notifier.notify(message=“The application is running!”, **params)

  • 每条错误消息一个提醒
    from notifiers.logging import NotificationHandler

    handler = NotificationHandler(“gmail”, defaults=params)
    logger.add(handler, level=“ERROR”)

  • 比内置日志记录快10倍
    尽管在大多数情况下,日志对性能的影响可以忽略不计,但零成本日志可以在任何地方使用它,而无需太多担心。
    在即将发布的版本中,Loguru的关键功能将以C语言实现,以实现最高速度。

源码

# loguru的核心是只有一个记录器,默认是stderr
import logging.handlers
import sys
from datetime import datetime

from loguru import logger

logger.debug("That's it, beautiful and simple logging!")

# 记录器只是一个接口,它将日志消息分派给已配置的处理程序。
# 如何添加处理程序?如何设置日志格式?如何过滤邮件?如何设置级别? 答案:add()函数。
logger.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO")

# 取代默认的stderr处理程序,只需调用logger.remove()

# 将日志记录到文件
logger.add("file_{time}.log")

logger.add("file_1.log", rotation="500 MB")  # 文件过大时自动滚动
logger.add("file_2.log", rotation="12:00")  # 每天中午12:00创建新文件
logger.add("file_3.log", rotation="1 week")  # 超过一周,自动创建新文件
logger.add("file_X.log", retention="10 days")  # 一段时间10天后清除
logger.add("file_Y.log", compression="zip")  # 压缩节省空间

logger.info("If you're using Python {}, prefer {feature} of course!", 3.6, feature="f-strings")  # 有比%更强大的格式化,{}占位符


# 线程或主线程内异常捕获
@logger.catch
def my_function(x, y, z):
    # An error? It's caught anyway!
    return 1 / (x + y + z)


my_function(1, 0, 0, 0)

# 用颜色记录日志
logger.add(sys.stdout, colorize=True, format="<green>{time}</green> <level>{message}</level>")

# 异步,进程安全,多线程安全的记录日志,通过排队的方式记录日志
logger.add("somefile.log", enqueue=True)

logger.add("out.log", backtrace=True, diagnose=True)  # #注意,可能会泄漏敏感数据


def func(a, b):
    return a / b


def nested(c):
    try:
        func(5, c)
    except ZeroDivisionError:
        logger.exception("What?!")


nested(0)

# 希望日志序列化以便于分析或传递:使用serialize参数,每个日志消息将在发送到配置的接收器之前转换为JSON字符串。
# logger.add(custom_sink_function, serialize=True)

# 使用bind记录日志上下文
logger.add("file.log", format="{extra[ip]} {extra[user]} {message}")
context_logger = logger.bind(ip="192.168.0.1", user="someone")
context_logger.info("Contextualize your logger easily")
context_logger.bind(user="someone_else").info("Inline binding of extra attribute")
context_logger.info("Use kwargs to add context during formatting: {user}", user="anybody")

# 使用contextualize()临时修改上下文本地状态:
# with logger.contextualize(task=task_id):
#     do_something()
#     logger.info("End of task")

# 通过结合bind()和filter,可以对日志进行更细粒度的控制:
logger.add("special.log", filter=lambda record: "special" in record["extra"])
logger.debug("This message is not logged to the file")
logger.bind(special=True).info("This message, though, is logged to the file!")

# patch()方法允许动态值附加到每个新消息的记录dict
logger.add(sys.stderr, format="{extra[utc]} {message}")
logger = logger.patch(lambda record: record["extra"].update(utc=datetime.utcnow()))


def expensive_function(a):
    print(a)


# 希望在生产中记录详细信息而不降低性能,可以使用opt()方法来实现这一点
logger.opt(lazy=True).debug("If sink level <= DEBUG: {x}", x=lambda: expensive_function(2 ** 64))

# opt()有很多用途
logger.opt(exception=True).info("Error stacktrace added to the log message (tuple accepted too)")  # 错误堆栈跟踪添加到日志消息
logger.opt(colors=True).info("Per message <blue>colors</blue>")
logger.opt(record=True).info("Display values from the record (eg. {record[thread]})")
logger.opt(raw=True).info("Bypass sink formatting\n")
logger.opt(depth=1).info("Use parent stack context (useful within wrapped functions)")
logger.opt(capture=False).info("Keyword arguments not added to {dest} dict", dest="extra")

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

# 更好的时间日期处理
logger.add("file.log", format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}")

# 脚本的日志记录器示例
config = {
    "handlers": [
        {"sink": sys.stdout, "format": "{time} - {message}"},
        {"sink": "file.log", "serialize": True},
    ],
    "extra": {"user": "someone"}
}
logger.configure(**config)

# 库的日志记录器
logger.disable("my_library")
logger.info("No matter added sinks, this message is not displayed")
logger.enable("my_library")
logger.info("This message however is propagated to the sinks")

# 与标准日志库兼容:希望将内置日志处理程序用作Loguru接收器
handler = logging.handlers.SysLogHandler(address=('localhost', 514))
logger.add(handler)

# 拦截向Loguru接收器发送的标准日志消息
class PropagateHandler(logging.Handler):
    def emit(self, record):
        logging.getLogger(record.name).handle(record)

logger.add(PropagateHandler(), format="{message}")

class InterceptHandler(logging.Handler):
    def emit(self, record):
        # 获取loguru日志level 如果村存在的话
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno

        # Find caller from where originated the logged message.
        frame, depth = sys._getframe(6), 6
        while frame and frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1

        logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())

logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)

# 详尽的通知者:Loguru可以很容易地与强大的通知程序库(必须单独安装)相结合,以便在程序意外失败时接收电子邮件或发送许多其他类型的通知。
import notifiers

params = {
    "username": "xxx@gmail.com",
    "password": "xxx",
    "to": "destxxx@gmail.com"
}

# 发送一条单独提醒
notifier = notifiers.get_notifier("gmail")
notifier.notify(message="The application is running!", **params)

# 每条错误消息一个提醒
from notifiers.logging import NotificationHandler

handler = NotificationHandler("gmail", defaults=params)
logger.add(handler, level="ERROR")

# 比内置日志记录快10倍
# 尽管在大多数情况下,日志对性能的影响可以忽略不计,但零成本日志可以在任何地方使用它,而无需太多担心。
# 在即将发布的版本中,Loguru的关键功能将以C语言实现,以实现最高速度。

参考

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛一枚~

您的鼓励是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值