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!')
其默认的输出格式是有时间、级别、模块名、行号以及日志信息,不需要手动创建 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!
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
可以理解成日志的创建时机,可以有多种写法
retention
配置日志的最长保留时间,官方例子: "1 week, 3 days"、"2 months"
compression
配置文件的压缩格式,可以配置常见的格式 zip、tar、gz、tar.gz 等
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
每 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')
配置文件的压缩格式,比如使用 zip 文件格式保存
logger.add('runtime.log', compression='zip')
可选格式为"gz", "bz2", "xz", "lzma", "tar", "tar.gz", "tar.bz2", "tar.xz", "zip"
要记录的消息是否应该在到达接收器之前首先通过一个多进程安全的队列。这在通过多个进程记录文件时非常有用。
logger.add("somefile.log", enqueue=True) # 异步写入
logger.add("somefile.log", serialize=True) # 序列化为json
提供的装饰器就可以直接进行 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
""" 操作日志记录 """ 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!')
参考
https://blog.csdn.net/cui_yonghua/article/details/107498535
https://www.cnblogs.com/poloyy/p/12435089.html