Python loguru
在使用Python进行程序开发的过程中,会遇到需要记录的日志的需求,常常会用到Python自带的logging模块,但是logging需要我们进行不同的初始化等相关工作。对应不熟悉该模块的同学来说,还是有些费劲的,比如需要配置 Handler/Formatter 等。而且随着业务的复杂度提升, 对日志收集有着更高的要求, 例如: 日志分类, 文件存储, 异步写入, 自定义类型等等。
loguru 是一个 Python 简易且强大的第三方日志记录库,该库旨在通过添加一系列有用的功能来解决标准记录器的注意事项,从而减少 Python 日志记录的痛苦。
Installation
log to console 1 2 3 4 5 6 from loguru import logger logger.debug("That's it, beautiful and simple logging!" )
loguru
默认格式是时间、级别、名称+模块和日志内容,其中名称+模块是写死的,一般场景下不建议修改,但在业务复杂的场景下,自定义模块名称,是非常有用的,我们可以通过logger.configure
手工指定模块名称。如下如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import sysfrom loguru import logger logger.configure(handlers=[ { "sink" : sys.stderr, "format" : "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | <cyan>mymodule</> | - <lvl>{message}</>" , "colorize" : True }, ]) logger.debug('this is debug' ) logger.info('this is info' ) logger.warning('this is warning' ) logger.error('this is error' ) logger.critical('this is critical' ) logger.info("this is {}" , "a info log" ) logger.info("this is {}" , 3 ) logger.info("this is {:.2f}" , 3 )
1 2 3 4 5 6 7 8 import sysfrom loguru import logger logger.remove() logger.add(sys.stdout, format ="{time:YYYY-MM-DD at HH:mm:ss} | <red>{level}</red> | <green>{file}</green> | <b><i>{message}</i></b>" ) logger.info("Hello, world!" ) logger.info("Hello, {name}!" , name="everyone" )
在 format
中,可以通过 {param}
的形式设置内容,通过 <tag></tag>
的形式设置格式。
常见的内容参数有:
参数
含义
time
时间
level
日志等级
file
文件名
message
日志信息
path
文件路径
function
函数
line
行数
module
模块
process
进程信息
thread
线程信息
tzinfo
时区信息
exception
异常信息
log to file 1 2 3 logger.add("log/file_1.log" ) logger.info("this is a info log" )
log rotation 1 2 3 4 5 6 7 8 logger.add("log/file_2.log" , rotation='10 KB' )for i in range (100 ): logger.info("this is a info log" ) logger.debug("this is a debug log" ) logger.warning("this is a warning log" ) logger.error("this is a error log" ) logger.critical("this is a critical log" )
关于rptation参数还有常见的如下用法:
1 2 3 4 logger.add("log.log" , rotation="50 MB" ) logger.add("log.log" , rotation="00:00" ) logger.add("log.log" , rotation="1 week" ) logger.add("log.log" , rotation="10 days" )
其他常用设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 logger.add("log.log" , retention="10 days" ) logger.add("log.log" , compression="zip" ) logger.add("log.log" , enqueue=True ) logger.add("log.log" , filter =lambda x: "hello" not in x["message" ]) logger.add("log.log" , encoding="utf-8" , level="INFO" ) logger.add("log.log" , enqueue=True ) logger.add("log1.log" , serialize=True )
常用的推荐设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import osimport timefrom loguru import logger logger_dir = "./log" log_path = os.path.join(logger_dir, f'{time.strftime("%Y%m" )} ' , '{time:YYYY_MM_DD}.log' ) logger.add( log_path, rotation="00:00" , retention="30 days" , enqueue=True , encoding="utf-8" , level="INFO" )
与PyTest结合使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import pytestfrom _pytest.logging import LogCaptureFixturefrom loguru import loggerdef some_func (i, j ): logger.info('Oh no!' ) logger.info('haha' ) return i + j@pytest.fixture def caplog (caplog: LogCaptureFixture ): handler_id = logger.add(caplog.handler, format ="{message}" ) yield caplog logger.remove(handler_id)def test_some_func_logs_warning (caplog ): assert some_func(-1 , 3 ) == 2 assert "Oh no!" in caplog.text
简单封装日志方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 from loguru import loggerimport osdef get_pro_path (): pro_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) return pro_pathdef get_logger (): logger.add(os.path.join(get_pro_path(), "mytest.log" ), rotation="500 MB" ) return logger
pytest case调用
1 2 3 4 5 6 7 8 9 10 11 12 """ loguru使用 """ from public_fun.log_fun import get_loggerfrom assertpy import assert_that logger = get_logger()def test_fun1 (): logger.info('我需要比较1' ) assert_that(1 ).is_not_equal_to(1 )