python-loguru



目录



摘要

loguru是 python 的一个第三方的日志记录包

项目地址 github: ​​https://github.com/Delgan/loguru​

文档:​​https://loguru.readthedocs.io/en/stable/index.html​

安装

pip install loguru


简单使用

在 ​​loguru​​ 里面有且仅有一个主要对象,那就是 ​​logger​

from loguru import logger

logger.debug('this is a debug message')
logger.info('this is another debug message')
logger.warning('this is another debug message')
logger.error('this is another debug message')
logger.info('this is another debug message')
logger.success('this is success message!')
logger.critical('this is critical message!')


python-日志-loguru_自定义

其默认的输出格式是有时间、级别、模块名、行号以及日志信息,不需要手动创建 ​​logger​​,直接使用即可,另外其输出还是彩色的,看起来会更加友好。

配置使用

loguru 对输出到文件的配置有非常强大的支持,比如支持输出到多个文件,分级别分别输出,过大创建新文件,过久自动删除等等


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,
rotation=None
retention=None
compression=None

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 还可以是一个自定义的类,具体的实现规范可以参见官方文档。

基本使用

logger.add('runtime.log', format="{time} {level} {message}", level="INFO")

logger.debug('this is a debug message')
logger.info('this is another debug message')
logger.warning('this is another debug message')
logger.error('this is another debug message')
logger.info('this is another debug message')
logger.success('this is success message!')
logger.critical('this is critical message!')


输出到​​runtime.log​​ 中为:

2021-09-12T20:05:20.148300+0800 INFO this is another debug message
2021-09-12T20:05:20.149300+0800 WARNING this is another debug message
2021-09-12T20:05:20.149300+0800 ERROR this is another debug message
2021-09-12T20:05:20.149300+0800 INFO this is another debug message
2021-09-12T20:05:20.149300+0800 SUCCESS this is success message!
2021-09-12T20:05:20.149300+0800 CRITICAL this is critical message!


format、filter、level

logger.add('runtime.log', format="{time} {level} {message}", filter="my_module", level="INFO")

#时间格式化
logger.add("file-{time}.log", format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}")


  • 第一个参数是保存日志信息的文件路径,在后缀多了个 {time} ,就是获取当前时间节点,这样就会自动创建新的日志,支持自定义时间
  • 当你需要输出中文日志的时候,请加上 encoding="utf-8" ,避免出现乱码
  • enqueue=True 代表异步写入,在多进程同时往日志文件写日志的时候使用队列达到异步功效
  • rotation可以理解成日志的创建时机,可以有多种写法
  • rotation="500 MB" :当日志文件达到500MB时就会重新生成一个文件
  • rotation="12:00" :每天12点就会创建新的文件、
  • rotation="1 week" :每隔一周创建一个log
  • retention 配置日志的最长保留时间,官方例子: "1 week, 3 days"、"2 months"
  • compression 配置文件的压缩格式,可以配置常见的格式 zip、tar、gz、tar.gz 等

删除 sink

from loguru import logger

trace = logger.add('runtime.log')
logger.debug('this is a debug message')
logger.remove(trace)
logger.debug('this is another debug message')


在调用 remove 方法之后,确实将历史 log 删除

控制台输出如下:

2019-10-13 23:18:26.469 | DEBUG    | __main__:<module>:4 - this is a debug message
2019-10-13 23:18:26.469 | DEBUG | __main__:<module>:6 - this is another debug message


日志文件 runtime.log 内容如下:

2019-10-13 23:18:26.469 | DEBUG    | __main__:<module>:4 - this is a debug message


rotation 配置

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

实现定时创建 log 文件

每隔一周创建一个 log 文件

设置日志文件最长保留 10 天

logger.add('runtime_{time}.log', rotation="500 MB")
logger.add('runtime_{time}.log', rotation='00:00')
logger.add('runtime_{time}.log', rotation='1 week')
logger.add('runtime.log', retention='10 days')


compression 配置

配置文件的压缩格式,比如使用 zip 文件格式保存

logger.add('runtime.log', compression='zip')

可选格式为"gz", "bz2", "xz", "lzma", "tar", "tar.gz", "tar.bz2",
"tar.xz", "zip"


enqueue异步

要记录的消息是否应该在到达接收器之前首先通过一个多进程安全的队列。这在通过多个进程记录文件时非常有用。

logger.add("somefile.log", enqueue=True)  # 异步写入


serialize序列化

logger.add("somefile.log", serialize=True)  # 序列化为json


Traceback

提供的装饰器就可以直接进行 Traceback 的记录

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

my_function(0, 0, 0)


# 运行完毕之后,可以发现 log 里面就出现了 Traceback 信息
> File "run.py", line 15, in <module>
my_function(0, 0, 0)
<function my_function at 0x1171dd510>

File "/private/var/py/logurutest/demo5.py", line 13, in my_function
return 1 / (x + y + z)
0
0
0

ZeroDivisionError: division by zero


loguru封装类

"""
操作日志记录
"""
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!')