Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志

 

Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志
Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志

Pypi version Build status Documentation Coverage Code quality Python versions License

Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志
Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志

 

loguru:是一个 Python 简易日志库,该库旨在通过添加一系列有用的功能来解决标准记录器的注意事项,从而减少 Python 日志记录的痛苦。

GitHub 地址:https://github.com/Delgan/logurugithub.com/Delgan/loguru

 

前言

keep it simple , keep it stupid . loguru模块大概是符合这一精神的,其让你把精力从一些日志的调配的琐碎事情上抽离出来,好让你有更多的精力去解决核心问题。基本上使用过之后,就好像使用了python的新特性 f-string 一样,you just can not stop to use it. 你会忍不住想要使用它。

就最简单的使用:

from loguru import logger

 

接触过logging的马上就知道这个logger是个什么东西了,然后就想通常那样 logger.info('what') 之类的去打日志即可。默认的logger的日志格式就已经非常好了。

通常这个就已经够用了,实际上容器化了的应用或者某些应用场景,是要求你的日志都打印在默认终端上的,还有某些专门管理日志的工具,也要求你的应用就打印在默认终端。

 

某些情况下你可能需要将日志同时打印到文件中:

logger.add('<filename>.log')

 

此外还支持这样带时间戳的文件名:

logger.add('file_{time}.log')

 

文件控制更高级的用法如下:

logger.add("file_1.log", rotation="500 MB")    # 文件过大自动开启新的日志文件
logger.add("file_2.log", rotation="12:00")     # 每天12:00 开启新的文件
logger.add("file_3.log", rotation="1 week")    # 一周的时间之后开启新的文件

logger.add("file_X.log", retention="10 days")  # 10天之后清除旧日志

logger.add("file_Y.log", compression="zip")    # 压缩日志

 

loguru还有很多高级用法,这个以后再看,现在最关键的一个问题是如何兼容别的logger,比如说tornado或者django有一些默认的logger。

经过研究,最好的解决方案是参考官方文档的,完全整合logging的工作方式。比如下面将所有的logging都用loguru的logger再发送一遍消息。

class InterceptHandler(logging.Handler):
    def emit(self, record):
        # Retrieve context where the logging call occurred, this happens to be in the 6th frame upward
        logger_opt = logger.opt(depth=6, exception=record.exc_info)
        logger_opt.log(record.levelno, record.getMessage())

logging.basicConfig(handlers=[InterceptHandler()], level=0)

 

这个 depth=6 大有讲究,似乎只有设置为6才能正确追踪原日志代码所在地,因为我们是日志信号再发送了的。

然后上面的 record.levelno 我发现可能换成 record.levelname 也是不错的。

这样原logging的日志流就和loguru整合起来了。

 

解决中文乱码问题

项目地址 github: https://github.com/Delgan/loguru
文档:https://loguru.readthedocs.io/en/stable/index.html

 

安装

pip install loguru

 

1、输出日志

from loguru import logger 
logger.debug("这是一条debug日志")

终端执行后出现带颜色的日志,挺酷的

Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志
Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志

 

2、输出到文件

from loguru import logger 
logger.add("file_{time}.log") 
logger.debug("这是一条debug日志") 
logger.info("这是一条info日志")

目录下多出一个日志文件 :file_2019-03-14_19-53-25_661314.log

Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志
Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志

 

3、日志规则

设置日志格式,过滤器,日志级别

from loguru import logger 
logger.add("file.log", format="{time} {level} {message}", filter="", level="INFO") 
logger.debug("这是一条debug日志") 
logger.info("这是一条info日志")
from loguru import logger
logger.add('logs/z_project.log',
           level='DEBUG',
           format='{time:YYYY-MM-DD 
:mm:ss} - {level} - {file} - {line} - {message}',
           rotation="10 MB")
logger.info('可以写日志了')

 

输出

2019-03-14T20:01:25.392454+0800 INFO 这是一条info日志

 

4、日志文件

文件管理方式

logger.add("file_1.log", rotation="500 MB")    # 文件过大就会重新生成一个文件
logger.add("file_2.log", rotation="12:00")     # 每天12点创建新文件
logger.add("file_3.log", rotation="1 week")    # 文件时间过长就会创建新文件
logger.add("file_X.log", retention="10 days")  # 一段时间后会清空
logger.add("file_Y.log", compression="zip")    # 保存zip格式

 

5、其他参数

logger.add("somefile.log", enqueue=True)  # 异步写入
logger.add("somefile.log", serialize=True)  # 序列化为json

 

6、时间格式化

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

配合notifiers模块
github: https://github.com/notifiers/notifiers
文档:https://notifiers.readthedocs.io/en/latest/

 

7、在工程中创建多个文件处理器对象并解决中文乱码问题

# 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!")
logger.debug("中文日志可以不")
logger.error("严重错误")

 

Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志
Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志
Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志
Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志

 

8. 捕获异常

from loguru import logger

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

 

9. 为日志添加颜色

import sys

from loguru import logger

logger.add(sys.stdout, colorize=True, format="<green>{time}</green> <level>{message}</level>")

 

10. 异步、线程安全、多进程安全

from loguru import logger

logger.add("file.log", enqueue=True)

 

11. 全描述异常

记录代码中发生的异常对于跟踪错误很重要,但是如果您不知道为什么失败,则记录日志就毫无用处。 Loguru通过允许显示整个堆栈跟踪(包括变量值)来帮助您发现问题

from loguru import logger

logger.add("output.log", backtrace=True, diagnose=True)  # Set 'False' to not leak sensitive data in prod

 

12. 配置到flask

import logging
import sys

from pathlib import Path

from flask import Flask
from loguru import logger

app = Flask(__name__)

class InterceptHandler(logging.Handler):
    def emit(self, record):
        logger_opt = logger.opt(depth=6, exception=record.exc_info)
        logger_opt.log(record.levelname, record.getMessage())



def configure_logging(flask_app: Flask):
    """配置日志"""
    path = Path(flask_app.config['LOG_PATH'])
    if not path.exists():
        path.mkdir(parents=True)
    log_name = Path(path, 'sips.log')


    logging.basicConfig(handlers=[InterceptHandler(level='INFO')], level='INFO')
    logger.configure(handlers=[{"sink": sys.stderr, "level": 'INFO'}])  # 配置日志到标准输出流
    logger.add(
        log_name, rotation="500 MB", encoding='utf-8', colorize=False, level='INFO'
    )   # 配置日志到输出到文件

 

实例一个:

from loguru import logger

logger.add("logger_3days.log", format="[{time:YYYY-MM-DD HH:mm:ss}] <lvl>{message}</lvl>", level="INFO", retention="3 days")
logger.info("If you're using Python {}, prefer {feature} of course!", 3.6, feature="f-strings")
logger.info("test info")
logger.debug("test debug")
logger.error("test error")

本文:Python: 日志记录方案 loguru, 日志模块, loguru模块, logger日志

Leave a Reply