python 日志库loguru
python 日志库loguru
安装
pip install loguru
最简单的基本使用
from loguru import loggerlogger.success("Hello from success!")
logger.info("Hello from info!")
logger.debug("Hello from debug!")
logger.warning("Hello from warning!")
logger.error("Hello from error!")
# 严重错误
logger.critical("Hello from critical!")
输出结果
自定义日志处理器(输出样式, 显示日志等级, 输出方式等)
import sysfrom loguru import logger# 移除默认的日志处理器, 否则会重复输出
logger.remove()
# 添加一个自定义日志处理器
logger.add(sys.stdout,format="<green>{time:YYYYMMDD HH:mm:ss}</green> | " # 颜色>时间"{process.name} | " # 进程名"{thread.name} | " # 进程名"<level>{module}</level>.<cyan>{function}</cyan>" # 模块名.方法名":<cyan>{line}</cyan> | " # 行号"<level>{level}</level>: " # 等级"<level>{message}</level>", # 日志内容# 可选值: TRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL# 越后的值, 显示的日志越少level='TRACE')def main():logger.success("Hello from success!")logger.info("Hello from info!")logger.debug("Hello from debug!")logger.warning("Hello from warning!")logger.error("Hello from error!")logger.critical("Hello from critical!")if __name__ == '__main__':main()
使用配置方式定义
import sysfrom loguru import loggerconfig = {"handlers": [{"sink": sys.stdout,"format": "<green>{time:YYYYMMDD HH:mm:ss}</green> | " # 颜色>时间"{process.name} | " # 进程名"{thread.name} | " # 进程名"<level>{module}</level>.<cyan>{function}</cyan>" # 模块名.方法名":<cyan>{line}</cyan> | " # 行号"<level>{level}</level>: " # 等级"<level>{message}</level>", # 日志内容"level": 'TRACE'},{"sink": "loguru.log", # 日志文件名"rotation": "1 week", # 按周滚动"retention": "10 days", # 保留10天"enqueue": True, # 异步写入"compression": "zip", # 压缩格式"serialize": True # 序列化日志为json格式},],"extra": {"user": "Tiam"}
}
logger.configure(**config)
保存日志文件
from loguru import logger# 添加一个文件日志处理器, 指定日志等级, 日志文件名, 日志文件大小, 日志文件数量, 日志文件切割方式# 添加 compression="zip" 参数, 可以压缩日志文件
# logger.add("file.log", level="INFO", rotation="10 KB", compression="zip")# 日志文件每达到 10 KB 时, 会自动切割
logger.add("file.log", level="INFO", rotation="10 KB")def main():logger.success("Hello from success!")logger.info("Hello from info!")logger.debug("Hello from debug!")logger.warning("Hello from warning!")logger.error("Hello from error!")logger.critical("Hello from critical!")if __name__ == '__main__':for i in range(100):main()
线程异常捕获
import threading
from concurrent.futures import ThreadPoolExecutorfrom loguru import logger@logger.catch
def thread_task():print(threading.current_thread().name)a = 1 / 0if __name__ == '__main__':with ThreadPoolExecutor(max_workers=1) as executor:executor.submit(thread_task)
@logger.catch
会捕获打印完整的异常信息以及堆栈信息,
如果没有@logger.catch
注解将不会抛出任何错误, 因为没有调用未来对象的返回结果(退出代码返回0)
使用logger.exception()
方法,可以打印出异常的堆栈信息, logger.error
只能记录信息
def main():try:a = 1 / 0except:# 使用logger.exception()方法,可以打印出异常的堆栈信息logger.exception("这里出现了异常")
多任务/多线程日志
多任务时, 分任务写入不同文件
from loguru import loggerlogger.add("file_A.log", filter=lambda record: record["extra"]["task"] == "A")
logger.add("file_B.log", filter=lambda record: record["extra"]["task"] == "B")def task_a():logger_a = logger.bind(task="A")logger_a.info("Task A")def task_b():logger_b = logger.bind(task="B")logger_b.info("Task B")task_a()
task_b()
多线程, 为每个线程分配一个日志文件
import copy
import time
from concurrent.futures import ThreadPoolExecutorfrom loguru import loggerlogger.remove()def task(task_id, logger):logger.info("Starting task {}", task_id)# do somethingtime.sleep(3)logger.success("End of task {}", task_id)tasks = ["A", "B", "C", "D", "E"]
with ThreadPoolExecutor(max_workers=len(tasks)) as executor:for task_id in tasks:# 深拷贝一个新的logger对象logger_ = copy.deepcopy(logger)# 给新的logger对象添加一个文件输出logger_.add("file_%s.log" % task_id)# 后续使用新的logger进行日志记录executor.submit(task, task_id, logger_)
与进度条tqdm
这里配置使用 tqdm.write
作为日志输出
from tqdm import tqdm
from loguru import logger
import timelogger.remove()
logger.add(lambda msg: tqdm.write(msg, end=""), colorize=True)logger.info("Initializing")for x in tqdm(range(100)):logger.info("Iterating #{}", x)time.sleep(0.1)
这是不使用tqdm.write
的输出效果, em…没体会到作用…
参考:
- 与tqDM一起使用· 议题 #135 · Delgan/loguru — Usage with tqdm · 议题 #135 · Delgan/loguru (github.com)
- loguru的代码片段和食谱- loguru文档 — Code snippets and recipes for loguru — loguru documentation
自定义日志等级
from loguru import logger
from functools import partialmethodlogger.level("simple", no=33, icon="🤖", color="<fg #b168f2>")logger.__class__.simple = partialmethod(logger.__class__.log, "simple")
logger.log("simple", "A message")
logger.simple("A message")
更多颜色可选值: loguru.logger — loguru documentation
icon=“🤖”, color=“<fg #b168f2>”)
logger.class.simple = partialmethod(logger.class.log, “simple”)
logger.log(“simple”, “A message”)
logger.simple(“A message”)
更多颜色可选值: [loguru.logger — loguru documentation](https://loguru.readthedocs.io/en/stable/api/logger.html#color)更多: [Overview — loguru documentation](https://loguru.readthedocs.io/en/stable/overview.html)