Python - 日志管理模块: Loguru的使用

2023-05-16

python的日志管理模块可以用自带的logging模块,也可以用第三方的Loguru模块,关于logging和loguru模块的简单使用可以参考以下文章,写的还是不错的:logging 和 loguru的使用

关于logging模块的详细使用,可以参考这篇文章:logging模块详细使用。

本片文章只记录loguru模块的使用,包括简单的用法,以及在多模块多线程下的使用。

1、loguru的安装

1.1、pip安装

pip\pip3 install loguru

1.2、pycharm下安装

2、loguru的简单使用

2.1、使用非常简单

Use out of box without boilerplate。

loguru的用法非常简单,在 loguru 中有且仅有一个对象:logger。为了使用方便,logger在使用时,是提前配置好的,并且开始是默认输出至stderr(但是这些完全是可以再进行配置的),而且打印出的log信息默认是配置了颜色的。如下所示,loguru的使用真的是非常简单:

from loguru import logger
logger.debug("This's a log message")

上面的日志记录语句,默认向stderr(控制台)打印了一条输出语句,输出结果如下所示:

可以看出,loguru默认配置了一套日志输出格式,有时间、级别、模块名、行号以及日志信息,不需要手动创建 logger,直接使用即可,另外其输出还是彩色的,看起来会更加友好。所以我们不需要提前配置什么,直接用就可以。

2.2、add()函数

No Handler、no Formatter、no Filter:one function to rule them all。

在使用logging模块是,我们需要手动配置Handler、Formatter以及Filter,需要调用不同的函数进行配置,但是在loguru中,只需要一个add()函数即可。通过add()函数,我们可以设置Handler,设置Formatter,Filter Message以及设置Level。使用示例:

import sys
from loguru import logger

logger.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO")

logger.debug("This's a new log message")

在上述代码中,通过add()函数指明了Handler为控制台输出,指定了format的格式,以及filter和level。然后就可以输出日志信息了:

add()函数原型定义如下:

def add(
        self,
        sink,
        *,
        level=_defaults.LOGURU_LEVEL,
        format=_defaults.LOGURU_FORMAT,
        filter=_defaults.LOGURU_FILTER,
        colorize=_defaults.LOGURU_COLORIZE,
        serialize=_defaults.LOGURU_SERIALIZE,
        backtrace=_defaults.LOGURU_BACKTRACE,
        diagnose=_defaults.LOGURU_DIAGNOSE,
        enqueue=_defaults.LOGURU_ENQUEUE,
        catch=_defaults.LOGURU_CATCH,
        **kwargs
    ):
    pass

里面有好多参数可以用来配置不同的属性。 这里面有一个非常重要的参数sink。通过 sink 我们可以传入多种不同的数据结构,汇总如下:

  • sink 可以传入一个 file 对象,例如 sys.stderr 或者 open('file.log', 'w') 都可以。
  • sink 可以直接传入一个 str 字符串或者 pathlib.Path 对象,其实就是代表文件路径的,如果识别到是这种类型,它会自动创建对应路径的日志文件并将日志输出进去。
  • sink 可以是一个方法,可以自行定义输出实现。
  • sink 可以是一个 logging 模块的 Handler,比如 FileHandler、StreamHandler 等等,这样就可以实现自定义 Handler 的配置。
  • sink 还可以是一个自定义的类,具体的实现规范可以参见官方文档。

 

2.3、创建记录日志文件

Easier file logging with rotation / retention / compression。

2.3.1、创建日志文件

我们可以通过传入一个文件名字符串或者文件路径,loguru就会自动创建一个日志文件,如下所示:

from loguru import logger
logger.add("runtime.log")       # 创建了一个文件名为runtime的log文件

logger.debug("This's a log message in file")

上面的程序就会在程序文件所在目录下创建一个名为runtime.log的文件,而且会在文件中记录日志:

同时也会在控制台输出日志信息:

如果不想在控制台也输出日志信息,因为logger是默认输出至stderr的,所以只需要在之前把它给remove掉就好了:

from loguru import logger

logger.remove(handler_id=None)

logger.add("runtime.log")       # 创建了一个文件名为runtime的log文件

logger.debug("This's a log message in file")

这样就不会在控制台输出日志信息了。 

2.3.2、指定创建日志文件名

在add()创建日志文件的时候,可以通过添加占位符的方式添加文件的日期,如下所示:

from loguru import logger

logger.add("runtime_{time}.log")       # 创建了一个文件名为runtime的log文件

logger.debug("This's a log message in file")

这样就会创建一个带有日期的log文件。

2.3.3、rotation 滚动记录日志文件

通过配置rotation参数,指定日志文件滚动记录的条件,如下所示:

 1)、

logger.add("file_1.log", rotation="500 MB")    # Automatically rotate too big file

通过这样的配置我们就可以实现每 500MB 存储一个文件,每个 log 文件过大就会新创建一个新的 log 文件。我们可以在创建文件的时候加一个(time)占位符,这样在生成时可以自动将时间替换进去,生成一个文件名包含时间的 log 文件。

2)、

logger.add("file_2.log", rotation="12:00")     # New file is created each day at noon

通过上面的配置,可以实现没填中午12:00创建一个log文件输出了。 

3)、

logger.add("file_3.log", rotation="1 week")    # Once the file is too old, it's rotated

通过上面的配置可以实现每隔1周创建一个新的log文件输出了。

2.3.4、retention 指定日志保留时长

通过配置retention参数,可以指定日志的保留时长:

logger.add("file_X.log", retention="10 days")  # Cleanup after some time

通过上面的配置,就可以指定日志最多保留10天,每隔10天之后就会清理旧的日志,这样就不会造成内存浪费。

2.3.4、compression 配置文件压缩格式

通过配置compression参数可以指定日志文件的压缩格式:

logger.add("file_Y.log", compression="zip")    # Save some loved space

通过上面的配置,可以指定日志文件的压缩格式为zip格式,可以节省存储空间。

2.4、异常捕获

Exceptions catching within threads or main。

最让我感到loguru模块功能强大的地方就是它的异常捕获功能。如果程序在运行过程出现崩溃或错误,记录日志是我们回溯程序执行过程的一个重要方式,但是很多时候,根据日志并不知道程序为什么出错或者看不出来程序具体出错在哪些地方,此时如果我们能在日志中记录当异常发生时的情况或者信息,那么多我们解决程序问题来说,简直事半功倍。

在loguru模块中,异常的捕获有两种方式:

2.4.1、catch装饰器 方法

通过catch装饰器的方式实现异常捕获:

from loguru import logger

logger.add("runtime.log") 

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

my_function(0, 0, 0)

 上面的代码中,通过catch装饰器对函数my_function进行装饰,这样,当该函数出现异常时,就会打印出异常日志信息,如下所示:

在日志信息中,不仅指明了异常出现的地方,而且把参数的值也记录下来了。

2.4.2、exception 方法

通过exception方法也可以实现异常的捕获与记录:

from loguru import logger

logger.add("runtime.log") 

def my_function1(x, y, z):
    try:
        return 1 / (x + y + z)
    except ZeroDivisionError:
        logger.exception("What?!")

my_function1(0, 0, 0)

记录的日志信息如下所示:

3、loguru在多模块情况下的使用

Asynchronous, Thread-safe, Multiprocess-safe。

由于在 loguru 中有且仅有一个对象:logger。所以loguru是可以在多块module文件中使用的,而且不会出现冲突:

exceptions_catching2_03.py:

from loguru import logger

def func(a, b):
    logger.info("Process func")
    return a / b

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

test.py:

#coding:utf-8

from loguru import logger

import exceptions_catching2_03 as ec3

if __name__=='__main__':

    logger.add("run.log")

    logger.info("Start!")

    ec3.nested(0)

    logger.info("End!")

运行结果如下所示:

4、loguru在多线程情况下的使用

Asynchronous, Thread-safe, Multiprocess-safe

所有添加至logger的sink默认都是线程安全的,所以loguru也可以很安全的在多线程的情形下使用:

#coding:utf-8

from atexit import register
from random import randrange
from threading import Thread, Lock, current_thread
from time import sleep, ctime

from loguru import logger

class CleanOutputSet(set):
    def __str__(self):
        return ','.join(x for x in self)

lock = Lock()
loops = (randrange(2, 5) for x in range(randrange(3, 7)))
remaining = CleanOutputSet()

def loop(nsec):
    myname = current_thread().name

    logger.info("Startted {}", myname)

    '''
    锁的申请和释放交给with上下文管理器
    '''
    with lock:
        remaining.add(myname)
    sleep(nsec)

    logger.info("Completed {} ({} secs)", myname, nsec)

    with lock:
        remaining.remove(myname)
        logger.info("Remaining:{}", (remaining or 'NONE'))

'''
_main()函数是一个特殊的函数,只有这个模块从命令行直接运行时才会执行该函数(不能被其他模块导入)
'''
def _main():
    for pause in loops:
        Thread(target=loop, args=(pause,)).start()

'''
这个函数(装饰器的方式)会在python解释器中注册一个退出函数,也就是说,他会在脚本退出之前请求调用这个特殊函数
'''
@register
def _atexit():
    logger.info("All Thread DONE!")
    logger.info("\n===========================================================================\n")

if __name__=='__main__':
    logger.add("run.log")

    _main()

日志记录文件如下所示:

上面代码创建了3个线程,每个线程都正确打印出了日志信息。 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python - 日志管理模块: Loguru的使用 的相关文章

  • 如何在Python中使用tcp套接字发送和接收网络摄像头流?

    我正在尝试重新创建这个项目 https github com hamuchiwa AutoRCCar 我拥有的是服务器 我的电脑 和客户端 我的树莓派 我所做的与原始项目不同的是我尝试使用一个简单的网络摄像头而不是树莓派摄像头将图像从我的
  • Python requests_toolbelt MultipartEncoder 文件名

    使用 requests toolbelt 以多部分形式上传大文件 我构建了一个方法 可以成功上传文件 但是我无法访问发布的文件名 如何访问服务器上的文件名 client side file open Volumes Extra test m
  • 如何使用Python将RGB565字节数组转换为RGB888字节数组?

    根据我的问题RGB888 转 RGB565 https stackoverflow com questions 61519934 how can i use opencv python to convert rgb888 to rgb565
  • lxml 中的通配符命名空间

    如何使用 xpath 忽略 xml 命名空间进行查询 我正在使用 python lxml 库 我尝试了以下解决方案this https stackoverflow com questions 13463871 xpath selecting
  • 如何在Python中每次运行脚本时增加变量?

    我有一个 Python 脚本 我想在每次运行时增加一个全局变量 这可能吗 使用外部文件很容易做到这一点 您可以创建一个函数来为您执行此操作 这样您就可以根据需要将多个文件用于多个变量 尽管在这种情况下您可能想要研究某种序列化并将所有内容存储
  • Bokeh 相当于 matplotlib 子图

    我正在寻找一种方法来创建包含多个子图的绘图 例如 fig ax0 ax1 plt subplots nrows 2 sharex True 可以在 matplotlib 中完成 然后可以通过以下方式解决ax0 and ax1 有没有办法在
  • 在heroku实例上安装PIL

    我创建了一个python flask托管在heroku上的应用程序 我很有趣PILpython 中的图像库 我无法安装PIL在heroku实例中 我尝试过以下几种方法 方法一 Added PIL 1 1 7 in requirements
  • 在 Spark-submit 上的 _find_and_load 中获取文件“”,第 991 行

    我目前使用的是Python 3 7 9 spark spark 2 4 6 bin hadoop2 6 在这个项目 venv 中 我的设置为 kafka python 2 0 2 pip 21 2 4 py4j 0 10 9 pyspark
  • 如何从numpy数组中获取两个最小值

    我想从数组中取出两个最小值x 但是当我使用np where A B np where x x min 0 1 我收到此错误 ValueError 需要超过 1 个值才能解压 我该如何修复这个错误 我需要在数组中按升序排列数字吗 您可以使用n
  • 抓取多个帐户,即多次登录

    我可以成功抓取单个帐户的数据 我想在一个网站上抓取多个帐户 这意味着多次登录 如何管理登录 注销 您可以在每个帐户会话中使用多个 cookiejar 并行抓取多个帐户 请参阅 cookiejar 请求元密钥http doc scrapy o
  • 读取 JSON 文件并将其漂亮打印到另一个文件

    我有一个复杂 嵌套 的 json 文本文件 它是文本文件中的一长行 有什么方法可以读取文件 在 python 中 并将 json 缩进 漂亮地打印到新的文本文件中吗 使用读取文件json load 并使用json dump 在指定缩进值时将
  • Python 2to3 Windows CMD

    我已经安装了 python 32 包到 C python32 我还设置了路径 Python 路径 C Python32 Lib C Python32 DLLs C Python32 Lib lib tk 路径 C Python32 我想使用
  • 使用多索引列对多列求和

    我有一个从数据透视表创建的数据框 看起来类似于 import pandas as pd d company1 False Negative April 2012 112 0 April 2013 370 0 April 2014 499 0
  • Pandas 数据框列总和并收集结果

    给定以下数据框 import pandas as pd p1 name willy age 11 interest Lego p2 name willy age 11 interest games p3 name zoe age 9 int
  • Pytest 插件:覆盖 pytest_runtest_call 和朋友

    我正在为我的一个项目使用 pytest 开发一个测试套件 由于项目的性质 我需要创建一个 Pytest 插件来控制测试的运行方式 它们不是在本地运行 而是发送到不同的进程来运行 我知道关于xdist但我认为这并不能解决我的问题 我一直在通过
  • 为什么 Python 的 argparse 对 SystemExit 使用错误代码 2?

    当我给 Python 的 argparse 输入它不喜欢的输入时 它会引发一个代码为 2 的 SystemExit 其中似乎意味着 没有这样的文件或目录 https docs python org 2 library errno html
  • matplotlib 轴标签偏移量的因素和变化

    在 matplotlib 中的轴刻度标签上 有两种可能的偏移量 factors and shifts 在右下角 1e 8 是一个 因子 1 441249698e1 是一个 移位 这里有很多答案展示了如何操纵两个都 matplotlib 将轴
  • 第 100 次避免循环导入

    Summary 我继续有一个ImportError在一个复杂的项目中 我已经将其蒸馏到仍然会出现错误的最低限度 Example 巫师有装有绿色和棕色药水的容器 这些可以添加在一起 产生同样是绿色或棕色的新药水 我们有一个PotionABC
  • 在 python 中将数组作为参数传递

    我是Python新手 现在我需要声明大小为 20 的数组并将该数组传递给函数 需要数组的函数如下 function args The args是一个输入function 谁能帮我 如何在 python 中传递数组 当你说 数组 时 我假设你
  • 在 python 中使用 org.mpris.mediaplayer2.player PlaybackStatus 属性

    The 规格页 http specifications freedesktop org mpris spec latest Player Interface html summary对于这个特定的接口说 PlaybackStatus s P

随机推荐

  • windows下编译64位ffmpeg的问题。以64位 zlib为例

    x264 265 等等10几个库都很顺利的编译过去了 xff0c zlib的64位库在vs2015下下编译通过了 放到ffmpeg环境里 死活找不到 卡了我整整两天 怎么折腾 xff0c 始终提升error zlib requested b
  • windows11安装kali linux子系统

    一 开启windows子系统 打开控制面板 系统和安全 程序 程序和功能 启用或关闭Windows功能 适用于linux的Windows子系统 打勾 在微软商店搜索Kali 下载安装并打开 二 配置子系统 刚安装完成的Kali Linux是
  • 使用 Ajax 发送的PUT、DELETE请求

    一 方式一 xff1a 将 POST 请求转化为相应的 PUT 和 DELETE 请求 1 在 Web xml 中添加如下配置 xff1a 用于将 POST 请求转化为相应的 PUT 和 DELETE 请求 lt filter gt lt
  • python+pycharm+pyqt5安装教程

    现在教大家在Windows系统下如何安装Python 43 PyCharm 43 PyQt5 1 安装Python 访问官网https www python org xff0c 下载对应Python版本 2 安装PyQt5 1 xff09
  • pytest+seleniumUI自动化框架设计

    前言 selenium自动化 43 pytest测试框架 本章你需要 一定的python基础 一定的selenium基础 不讲selenium xff0c 不会的自己去看selenium中文翻译网 测试框架简介 测试框架有什么优点呢 xff
  • selenium的UI自动化时遇到了谷歌浏览器与驱动不兼容的问题解决方案

    问题背景 xff1a 在做selenium的UI自动化时 xff0c 遇到了谷歌浏览器与驱动不兼容的问题 去很多其他网站下载谷歌浏览器驱动 xff0c 结果下载下来的都是2 23版本的 xff08 困扰了很久啊 xff0c 一群骗子 xff
  • 如何使用apipost做接口测试?

    今天给大家推荐一款好用的接口测试工具 xff1a apipost 这是一款国产的接口测试工具 xff0c 非常类似于postman xff0c 但是整体使用上感觉要比postman更适合咱们使用 xff0c 毕竟是全中文的 话不多说直接上图
  • 如何使用pycharm将github上的代码同步到本地

    1 首先确定你安装了git exe 具体的话是在pycharm里面的settings version control 2 打开pycharm xff0c 新建版本使用git 3 从github上复制代码链接 4 填入相关内容点击clone即
  • StrokeStart与StrokeEnd动画

    通过修改CAShapeLayer的StrokeStart与StrokeEnd的值来实现画图动画 效果图 代码部分 import 34 ViewController h 34 64 interface ViewController 64 pr
  • GUI编程之路内计费工具

    span class token keyword import span os span class token keyword import span sys span class token keyword from span PyQt
  • 提高测试人员测试效率之GUI工具

    如何有效的去提高测试效率 xff0c 在一个团队当中 xff0c 肯定会存在部分人员无法熟悉数据库操作的情况 xff0c 这个时候我们就可以通过GUI编程将工具界面会 xff0c 使之快速的上手 本次通过一个GUI工具来带领大家如何制作这么
  • GUI编程之智慧交通自动化测试计费

    最终实现效果 本工具实现了案例搜索 xff0c 导入案例 xff0c 测试类型选择 xff0c 自动化测试 xff0c 测试报告 xff0c 邮件发送等功能 xff0c 能有效的提升回归测试效率 xff0c 保证测试质量 源码暂不提供 xf
  • Ubuntu14.04 Wifi 连接不稳定、掉线重连问题(终极解决办法)

    Ubuntu14 04 Wifi 连接不稳定 上不了网 掉线问题 xff08 终极解决办法 xff09 这可能是我写的最短的一篇博客 用Ubuntu系统的人知道 xff0c 有线连接比较稳定 xff1b 一般台式机不带网卡 xff0c 自己
  • 【Ubuntu】Ubuntu上搭建本地源,做离线安装

    一 实验背景 Ubuntu作为最优秀的Linux发行版之一 xff0c 是初学者入门的不二选择 xff0c 但Linux有个最大的问题 xff0c 就是离了网络就废了 在Windows系统中 xff0c 安装软件十分方便 xff0c 下载安
  • gitlab-ce 备份还原 迁移新系统

    https blog csdn net foupwang article details 94362292 迁移前首先要保证新旧服务器上的GitLab版本号一致 查看当前GitLab版本 cat opt gitlab embedded se
  • linux虚拟网络设备之vlan配置详解

    https www jb51 net article 130486 htm 注意VLAN方式达到了网络隔离 xff0c 但是mac地址是相同的 xff0c 意思就是基于同一个网卡出来的vlan mac地址相同 要想不通 xff0c 可以用m
  • jacoco的使用

    一 概述Java 覆盖率 Jacoco 插桩的不同形式总结和踩坑记录 TesterHome 测试覆盖率 xff0c 老生常谈的话题 因为我测试理论基础不是很好 xff0c 就不提什么需求覆盖率啦这样那样的主题了 xff0c 直奔主题 xff
  • mysql bin-log,relay-log删除方法

    master的bin log日志清理 xff1a 方法1 RESET MASTER 1 1 解释 xff1a 该方法可以删除列于索引文件中的所有二进制日志 xff0c 把二进制日志索引文件重新设置为空 xff0c 并创建一个以 000001
  • ubuntu18 网络问题

    在 etc netplan yaml配置文件中 xff1a renderer的值可以是networkd xff0c 或者是NetworkManager 它俩的其中一个区别为 xff1a networkd在图像界面 xff0c network
  • Python - 日志管理模块: Loguru的使用

    python的日志管理模块可以用自带的logging模块 xff0c 也可以用第三方的Loguru模块 xff0c 关于logging和loguru模块的简单使用可以参考以下文章 xff0c 写的还是不错的 xff1a logging 和