找回密码
 会员注册
查看: 22|回复: 0

Python日志记录库——loguru

[复制链接]

10

主题

0

回帖

31

积分

新手上路

积分
31
发表于 2024-9-8 14:20:44 | 显示全部楼层 |阅读模式
文章目录一.概述二、基本使用2.1安装2.2日志输出三、进阶用法3.1显示格式3.2写入文件3.3模块名参数化3.4日志留存、压缩与清理3.5序列化为json格式3.6并发安全参考资料一.概述在Python中用到日志记录,那就不可避免地会用到内置的logging标准库。虽然logging库采用的是模块化设计,你可以设置不同的handler来进行组合,但是在配置上通常较为繁琐;而且如果不是特别处理,在一些多线程或多进程的场景下使用logging还会导致日志记录会出现错乱或是丢失的情况。关于Python内置的logging标准库介绍可参见博客:Python日志记录工具logging标准库logging的替代品是loguru,loguru使用起来就简单的多。它不仅能够减少繁琐的配置过程还能实现和logging类似的功能,同时还能保证日志记录的线程进程安全,又能够和logging相兼容,并进一步追踪异常也能进行代码回溯。loguru默认的输出格式是:时间、级别、模块、行号以及日志内容。loguru不需要手动创建logger,开箱即用;另外,日志输出内置了彩色功能,颜色和非颜色控制很方便,更加友好。loguru官方文档:https://loguru.readthedocs.io/en/stable/index.html二、基本使用2.1安装loguru是非标准库,需要事先安装,命令是:pipinstallloguru1logger本身就是一个已经实例化好的对象,如果没有特殊的配置需求,那么自身就已经带有通用的配置参数;同时它的用法和logging库输出日志时的用法一致。2.2日志输出(1)输出到控制台安装后,最简单的使用样例如下:fromloguruimportloggerlogger.debug('hello,thisdebugloguru')logger.info('hello,thisisinfologuru')logger.warning('hello,thisiswarningloguru')logger.error('hello,thisiserrorloguru')logger.critical('hello,thisiscriticalloguru')1234567上述代码输出:(2)输出到控制台+文件日志打印到文件的用法也很简单,代码如下:fromloguruimportloggerlogger.add('myloguru.log')logger.debug('hello,thisdebugloguru')logger.info('hello,thisisinfologuru')logger.warning('hello,thisiswarningloguru')logger.error('hello,thisiserrorloguru')logger.critical('hello,thisiscriticalloguru')123456789上述代码运行时,可以打印到console,也可以打印到文件中去。三、进阶用法3.1显示格式loguru默认格式是时间、级别、名称+模块和日志内容,其中名称+模块是写死的,是当前文件的__name__变量,此变量最好不要修改。工程比较复杂的情况下,自定义模块名称,是非常有用的,容易定界定位,避免陷入细节中。我们可以通过logger.configure手工指定模块名称。如下如下:importsysfromloguruimportloggerlogger.configure(handlers=[{"sink":sys.stderr,"format":"{time:YYYY-MM-DDHH:mm:ss.SSS}|{level:8}|{name}:{module}:{line:4}|mymodule|-{message}","colorize":True},])logger.debug('thisisdebug')logger.info('thisisinfo')logger.warning('thisiswarning')logger.error('thisiserror')logger.critical('thisiscritical')1234567891011121314151617上述代码中:handlers:表示日志输出句柄或者目的地,sys.stderr表示输出到命令行终端。“sink”:sys.stderr,表示输出到终端“format”:表示日志格式化。{level:8}表示按照日志级别显示颜色。8表示输出宽度为8个字符。“colorize”:True**:表示显示颜色。上述代码的输出为:这里写死了模块名称,每个日志都这样设置也是比较繁琐。下面会介绍指定不同模块名称的方法。3.2写入文件日志一般需要持久化,除了输出到命令行终端外,还需要写入文件。标准日志库可以通过配置文件配置logger,在代码中也可以实现,但过程比较繁琐。loguru相对而已就显得稍微简单一些,我们看下在代码中如何实现此功能。日志代码如下:importsysfromloguruimportloggerlogger.configure(handlers=[{"sink":sys.stderr,"format":"{time:YYYY-MM-DDHH:mm:ss.SSS}|{level:8}|{name}:{module}:{line:4}|mymodule|-{message}","colorize":True},{"sink":'first.log',"format":"{time:YYYY-MM-DDHH:mm:ss.SSS}|{level:8}|{name}:{module}:{line:4}|mymodule|-{message}","colorize":False},])logger.debug('thisisdebug')logger.info('thisisinfo')logger.warning('thisiswarning')logger.error('thisiserror')logger.critical('thisiscritical')12345678910111213141516171819202122与3.1唯一不同的地方,logger.configure新增了一个handler,写入到日志文件中去。用法很简单。3.3模块名参数化上述只是通过logger.configure设置日志格式,但是模块名不是可变的,实际项目开发中,不同模块写日志,需要指定不同的模块名称。因此,模块名称需要参数化,这样实用性更强。样例代码如下:importsysfromloguruimportloggerlogger.configure(handlers=[{"sink":sys.stderr,"format":"{time:YYYY-MM-DDHH:mm:ss.SSS}|{level:8}|{name}:{module}:{line:4}|{extra[module_name]}|-{message}","colorize":True},{"sink":'first.log',"format":"{time:YYYY-MM-DDHH:mm:ss.SSS}|{level:8}|{name}:{module}:{line:4}|{extra[module_name]}|-{message}","colorize":False},])log=logger.bind(module_name='my-loguru')log.debug("thisishello,moduleismy-loguru")log2=logger.bind(module_name='my-loguru2')log2.info("thisishello,moduleismy-loguru2")12345678910111213141516171819202122logger.bind(module_name=‘my-loguru’)通过bind方法,实现module_name的参数化。bind返回一个日志对象,可以通过此对象进行日志输出,这样就可以实现不同模块的日志格式。loguru中自定义模块名称的功能比标准日志库有点不同。通过bind方法,可以轻松实现标准日志logging的功能。而且,可以通过bind和logger.configure,轻松实现结构化日志。上述代码的输出如下:3.4日志留存、压缩与清理通常来说如果程序或服务的量级较大,那么就可以通过集成的日志平台或数据库来对日志信息进行存储和留存,后续有需要的话也方便进行日志分析。但对我们个人或者一些中小型项目来说,通常只需要以文件的形式留存输出的日志即可。尽管我们需要将日志写入到相应的文件中,如果是少量的日志那还好,但是如果是日志输出或记录时间较长的情况,那么单个日志文件就十分之大,倘若仍然是将日志都写入到一个文件中,那么当日志中的内容增长到一定数量时我们想要读取并查找相应的部分时就十分困难。这时候我们就需要对日志文件进行留存、压缩,甚至在必要时及时进行清理。基于以上,我们可以通过对rotation、compression和retention三个参数进行设定来满足我们的需要:rotation:rotation参数能够帮助我们将日志记录以文件大小、时间等方式进行分割或划分。#设置每天0点新创建一个log文件:logger.add('runtime_{time}.log',rotation='00:00')#设置超过500MB新创建一个log文件:logger.add('runtime_{time}.log',rotation="500MB")#设置每隔一个周新创建一个log文件:logger.add('runtime_{time}.log',rotation='1week')12345678compression:随着分割文件的数量越来越多之后,我们也可以进行压缩对日志进行留存,这里就要使用到compression参数,该参数只要你传入通用的压缩文件扩展名即可,如zip、tar、gz等。#设置使用zip文件格式保存logger.add('runtime_{time}.log',compression='zip')12retention:如果你不想对日志进行留存,或者只想保留一段时间内的日志并对超期的日志进行删除,那么可以使用retention参数。#设置日志文件最长保留15天:logger.add('runtime_{time}.log',retention='15days')#设置日志文件最多保留10个:logger.add('runtime_{time}.log',retention=10)#retention的参数也可以是一个datetime.timedelta对象,比如设置日志文件最多保留5个小时:importdatetimelogger.add('runtime_{time}.log',retention=datetime.timedelta(hours=5))1234567893.5序列化为json格式如果在实际中你不太喜欢以文件的形式保留日志,那么你也可以通过serialize参数将其转化成序列化的json格式,最后将导入类似于MongoDB、ElasticSearch这类数NoSQL数据库中用作后续的日志分析。loguru保存成结构化json格式非常简单,只需要设置serialize=True参数即可。代码如下:fromloguruimportloggerlogger.add('json.log',serialize=True,encoding='utf-8')logger.debug('thisisdebugmessage')logger.info('thisisinfomessage')logger.error('thisiserrormessage')123456输出内容如下:3.6并发安全loguru默认是线程安全的,但不是多进程安全的,如果使用了多进程安全,需要添加参数enqueue=True,样例代码如下:logger.add("somefile.log",enqueue=True)1参考资料Python学习:loguru日志库loguru简单且强大的日志记录库
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 19:25 , Processed in 0.800343 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表