1 简单使用

代码:

  1. from loguru import logger
  2. logger.info("中文loguru")
  3. logger.debug("中文loguru")
  4. logger.error("中文loguru")
  5. logger.warning("中文loguru")

可以看到其默认的输出格式是包含【时间、级别、模块名、行号以及日志信息】,不需要手动创建 logger ,直接使用即可。

拓展

最重要的!loguru还提供了字符串格式化输出日志的功能,如下面代码

logger.info('If you are using Python {}, prefer {feature} of course!', 3.6, feature='f-strings')
n1 = "cool"
n2 = [1, 2, 3]
logger.info(f'If you are using Python {n1}, prefer {n2} of course!')

2 日志保存

一般情况,我们都需要将日志输出保存到文件中,loguru直接通过 add() 方法,就可以配置一个日志文件,如下代码所示:

代码

# coding:utf-8
from loguru import logger
logger.add("interface_log_{time}.log", rotation="500MB", encoding="utf-8", enqueue=True, compression="zip", retention="10 days")
logger.info("中文test")
logger.debug("中文test")
logger.error("中文test")
logger.warning("中文test")

add的参数

  1. 第一个参数是保存日志信息的文件路径,像我写的后缀多了个 {time} ,就是获取当前时间节点,这样就会自动创建新的日志;这个time应该是库里自带的变量,如果你想自己定义time也可以的哦,具体可以看看下面封装类的实现形式!
  2. 当你需要输出中文日志的时候,请加上 encoding=”utf-8” ,避免出现乱码
  3. enqueue=True 代表异步写入,官方的大概意思是:在多进程同时往日志文件写日志的时候使用队列达到异步功效
  4. rotation 可以理解成日志的创建时机,可以有多种写法
  • rotation=”500 MB” :当日志文件达到500MB时就会重新生成一个文件
  • rotation=”12:00” :每天12点就会创建新的文件、
  • rotation=”1 week” :每隔一周创建一个log
  1. retention 配置日志的最长保留时间,官方例子: “1 week, 3 days”、”2 months”
  2. compression 配置文件的压缩格式,可以配置常见的格式 zip、tar、gz、tar.gz 等

    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 可以传入一个 file 对象,例如 sys.stderr 或者 open(‘file.log’, ‘w’) 都可以。
    sink 可以直接传入一个 str 字符串或者 pathlib.Path 对象,其实就是代表文件路径的,如果识别到是这种类型,它会自动创建对应路径的日志文件并将日志输出进去。
    sink 可以是一个方法,可以自行定义输出实现。
    sink 可以是一个 logging 模块的 Handler,比如 FileHandler、StreamHandler 等等,或者上文中我们提到的 CMRESHandler 照样也是可以的,这样就可以实现自定义 Handler 的配置。
    sink 还可以是一个自定义的类,具体的实现规范可以参见官方文档。
    所以说,刚才第二章所演示的输出到文件,仅仅给它传了一个 str 字符串路径,他就给我们创建了一个日志文件,就是这个原理。(更加详细的常见文档【2】)

    Level

    DEBUG < INFO < WARNING < ERROR < CRITICAL
级别 日志函数 描述
DEBUG logging.debug() 最低级别,追踪问题时使用
INFO logging.info() 记录程序中一般事件的信息,或确认一切工作正常
WARNING logging.warning() 记录信息,用于警告
ERROR logging.error() 用于记录程序报错信息
CRITICAL logging.critical() 最高级别,记录可能导致程序崩溃的错误

基本参数

下面我们再了解下它的其他参数,例如 format、filter、level 等等。 其实它们的概念和格式和 logging 模块都是基本一样的了,例如这里使用 format、filter、level 来规定输出的格式。

3 Traceback 记录

在很多情况下,如果遇到运行错误,而我们在打印输出 log 的时候万一不小心没有配置好 Traceback 的输出,很有可能我们就没法追踪错误所在了。 但用了 loguru 之后,我们用它提供的装饰器就可以直接进行 Traceback 的记录,类似这样的配置即可:

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

我们做个测试,我们在调用时三个参数都传入 0,直接引发除以 0 的错误,看看会出现什么情况:
my_function(0, 0, 0)
运行完毕之后,可以发现 log 里面就出现了 Traceback 信息,而且给我们输出了当时的变量值,真的是不能再赞了!结果如下:

结果

image.png

4 封装的类

日志输出路径:你的项目路径下的log文件夹下
注意:这个是工具类,需要放在项目路径下的util文件夹之类的,不能直接放项目路径下哈,不然路径会生成错误哦

案例一:

"""操作日志记录
"""
import time
from loguru import logger
from pathlib import Path

project_path = Path.cwd().parent
log_path = Path(project_path, "log")
t = time.strftime("%Y_%m_%d")

class Loggings:
    __instance = None
    logger.add(f"{log_path}/interface_log_{t}.log", rotation="500MB", encoding="utf-8", enqueue=True,
               retention="10 days")

    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(Loggings, cls).__new__(cls, *args, **kwargs)
        return cls.__instance

    def info(self, msg):
        return logger.info(msg)
    def debug(self, msg):
        return logger.debug(msg)
    def warning(self, msg):
        return logger.warning(msg)
    def error(self, msg):
        return logger.error(msg)

loggings = Loggings()
if __name__ == '__main__':
    loggings.info("中文test")
    loggings.debug("中文test")
    loggings.warning("中文test")
    loggings.error("中文test")

    logger.info('If you are using Python {}, prefer {feature} of course!', 3.6, feature='f-strings')
    n1 = "cool"
    n2 = [1, 2, 3]
    logger.info(f'If you are using Python {n1}, prefer {n2} of course!')

结果-文件内的部分

image.png

结果-控制台的部分

image.png

案例二:

# coding=utf-8
import os
import sys
from loguru import logger

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

log_file_path = os.path.join(BASE_DIR, 'Log/my.log')
err_log_file_path = os.path.join(BASE_DIR, 'Log/err.log')

logger.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO")
# logger.add(s)
logger.add(log_file_path, rotation="500 MB", encoding='utf-8')  # Automatically rotate too big file
logger.add(err_log_file_path, rotation="500 MB", encoding='utf-8',
           level='ERROR')  # Automatically rotate too big file
logger.debug("That's it, beautiful and simple logging!")

结果-文档

image.png

结果-控制板

image.png

说明

没有定义level的将包含所有的log信息。
位置关系如下
image.png

方案三:

from loguru import logger
class Loggings():
    __instance = None
    logger.add(f"data_clean_info_log.log",level='INFO', rotation='02:00', encoding="utf-8", enqueue=True,retention="30 days")
    logger.add(f"data_clean_error_log.log", level='ERROR', rotation='100 MB', retention='60 days', encoding='utf-8')

    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = super(Loggings, cls).__new__(cls, *args, **kwargs)
        return cls.__instance

    def info(self, msg):
        return logger.info(msg)
    # def debug(self, msg):
    #     return logger.debug(msg)
    # def warning(self, msg):
    #     return logger.warning(msg)
    def error(self, msg):
        return logger.error(msg)
    def catch(self):
        return logger.catch()

loggings = Loggings()

@loggings.catch()
def my_function(x, y, z):
    return 1 / (x + y + z)
res = my_function(0,0,0)
print(res)

结果:

image.png
2个文档都有相同的错误提示:

5 使用模板

from datetime import datetime
from loguru import logger
logger.add(f"./log/{str(datetime.today())[:10]}_info.log", level='INFO', encoding="utf-8", enqueue=True)

logger.info("Training complete!")

6 注意事项

logger.add文件需要放到最前面,否则在它之前的信息只会输出到控制台,而不会记录到文档中;

参考文档

【1】项目地址 github: https://github.com/Delgan/loguru
【2】文档:https://loguru.readthedocs.io/en/stable/index.html
【3】Python 中更优雅的日志记录方案 loguru,内涵logging部分: https://cuiqingcai.com/7776.html