Loguru:更优雅的日志记录解决方案!loguru是一个简单而强大的Python第三方日志记录库,旨在通过添加一组有用的功能来解决标准记录器的注意事项,从而减少Python中的日志记录痛苦。1.原因介绍简单方便帮我们输出需要的日志信息!如果你用Python写程序或者脚本,经常遇到的问题就是需要删除日志。一方面可以在程序出错的时候帮助我们排查问题,另一方面可以帮助我们记录需要注意的信息。但是,使用内置的日志模块需要我们进行不同的初始化等相关工作。对于不熟悉这个模块的同学来说还是有点难度,比如需要配置Handler/Formatter等importlogginglogger=logging.getLogger('xxx')handler=logging.StreamHandler()formatter=logging。格式化程序('%(asctime)s%(名称)-12s%(级别名称)-8s%(消息)s')处理程序。setFormatter(formatter)logger.addHandler(handler)logger.setLevel(logging.DEBUG)logger.debug('Thisisa%s','test')而loguru是开箱即用的日志模块,我们不再需要进行复杂的初始化操作,可以使用如下命令记录日志信息。#pip$pipinstallloguru2。功能特点有很多优点,比较重要的几点列举如下!开箱即用,无需准备,无需初始化,导入函数即可使用更简单的文件日志记录和转储/保留/压缩更优雅的字符串格式输出可以在线程或主线程中捕获异常可以设置不同的级别日志记录样式支持异步、线程和多进程安全,支持惰性计算。它适用于脚本和库。它与标准日志记录完全兼容。更好的日期和时间处理。3.快速介绍loguru的常用操作和功能![1]开箱即用,无需准备loguru没有什么黑科技,但它帮我们提前设置好相关配置,导入后就可以直接使用了。fromloguruiimportloggerlogger.debug("That'sit,beautifulandsimplelogging!")[2]无需初始化,导入函数即可如何添加处理程序(handler)?如何设置日志格式(logsformatting)?如何过滤消息(filtermessages)?如何设置级别(日志级别)?#addlogger.add(sys.stderr,\format="{time}{level}{message}",\filter="my_module",\level="INFO")[3]更轻松的文件记录和转储/保留/压缩method#log文件记录logger.add("file_{time}.log")#log文件传输logger.add("file_{time}.log",rotation="500MB")logger.add("file_{time}.log",rotation="12:00")logger.add("file_{time}.log",rotation="1week")#清理logger.add("file_X.logafterseveraltimes)",retention="10days")#Savelogger.add("file_Y.log",compression="zip")[4]更优雅的字符串格式输出logger.info("Ifyou'reusingPython{},prefer{feature}ofcourse!",3.6,feature="f-strings")[5]在线程或主线程中捕获异常@logger.catchdefmy_function(x,y,z):#Anerror?It'scaughtanway!返回1/(x+y+z)my_function(0,0,0)[6]您可以设置不同级别的日志记录样式。Loguru会自动为不同的日志级别添加不同的颜色来区分。当然我们也可以自定义自己喜欢的logger.add(sys.stdout,colorize=True,format="{time}{message}")logger.add('logs/z_{time}.log',level='DEBUG',format='{time:YYYY-MM-DD:mm:ss}-{level}-{file}-{line}-{message}',rotation="10MB")[7]异步且线程多进程安全默认情况下,添加到logger中的日志信息是线程安全的。但这不是多进程安全的,我们可以通过添加enqueue参数来保证日志的完整性。如果我们想在异步任务中使用日志记录,我们也可以使用相同的参数来保证。并传递complete()等待执行完成。#Asynchronouslywritetologger.add("some_file.log",enqueue=True)[8]异常的完整描述用于记录代码中发生的异常的bugtrace,Loguru允许显示整个堆栈跟踪(包括变量值)以帮助您识别问题。logger.add("out.log",backtrace=True,diagnose=True)deffunc(a,b):returna/bdefnested(c):try:func(5,c)exceptZeroDivisionError:logger.exception("什么?!")nested(0)[9]结构化日志记录序列化日志以便于解析或传递数据结构,使用序列化参数,转换每个日志消息,然后将其作为JSON字符串发送到配置的接收器。此外,使用bind()方法,可以通过修改附加记录属性来将记录器消息上下文化。通过结合bind()和过滤器,还可以对日志记录进行更细粒度的控制。最后,patch()方法允许将动态值附加到每个新消息的记录字典中。#序列化为json格式logger.add(custom_sink_function,serialize=True)#bind方法的用处logger.add("file.log",format="{extra[ip]}{extra[user]}{message}")context_logger=logger.bind(ip="192.168.0.1",user="someone")context_logger.info("Contextualizeyourloggereasily")context_logger.bind(user="someone_else").info("Inlinebindingofextraattribute")context_logger.info("Usekwargstoaddcontextduringformatting:{user}",user="anybody")#Granularcontrollogger.add("special.log",filter=lambdarecord:"special"inrecord["extra"])logger.debug("Thismessageis未记录到文件”)logger.bind(special=True).info(“不过,这条消息已记录到文件中!”)#patch()方法logger.add(sys.stderr,format="{extra[utc]}{message}")loggerlogger=logger.patch(lambdarecord:record["extra"].update(utc=datetime.utcnow()))[10]惰性计算有时你想记录生产中的详细信息在不影响性能的情况下,可以使用opt()方法为了达成这个logger.opt(lazy=True).debug("Ifsinklevel<=DEBUG:{x}",x=lambda:expensive_function(2**64))#Bytheway,"opt()"servesmanyusageslogger.opt(exception=True).info("Errorstacktraceaddedtothelogmessage(tupleacceptedtoo)")logger.opt(colors=True).info("Permessagecolors")logger.opt(record=True).info("Displayvaluesfromtherecord(eg.{记录[线程]})")logger.opt(raw=True).info("Bypasssinkformatting\n")logger.opt(depth=1).info("Useparentstackcontext(usefulwithinwrappedfunctions)")logger.opt(capture=False).info("Keywordargumentsnotaddedto{dest}dict",dest="extra")[11]自定义级别new_level=logger.level("SNAKY",no=38,color="",icon="🐍")logger.log("SNAKY","Herewego!")[12]适用于脚本和库#Forscriptsconfig={"handlers":[{"sink":sys.stdout,"format":"{时间}-{消息}"},{"sink":"file.log","serialize":True},],"extra":{"user":"someone"}}logger.configure(**config)#Forlibrarieslogger.disable("my_library")logger.info("Nomatteraddedsinks,thismessageisnotdisplayed")logger.启用(“my_library”)记录器。info("Thismessagehoweverispropagatedtothesinks")[13]与标准日志记录完全兼容想使用Loguru作为内置日志处理程序吗?需要将Loguru消息记录到标准日志中吗?想在Loguru中拦截标准日志消息进行聚合?handler=logging.handlers.SysLogHandler(address=('localhost',514))logger.add(handler)classPropagateHandler(logging.Handler):defemit(self,record):logging.getLogger(record.name).handle(记录)logger.add(PropagateHandler(),format="{message}")classInterceptHandler(logging.Handler):defemit(self,record):#GetcorrespondingLogururevelfitexiststry:level=logger.level(record.levelname).nameexceptValueError:level=记录.levelno#Findcallerfromwhereoriginatedtheloggedmessageframe,depth=logging.currentframe(),2whileframe.f_code.co_filename==logging.__file__:frameframe=frame.f_backdepth+=1logger.opt(depthdepth=depth,exception=record.exc_info).log(level,record.getMessage())logging.basicConfig(handlers=[InterceptHandler()],level=0)[14]Handyparser从生成的日志中提取特定信息通常很有用,这就是为什么Loguru提供了一个parse()方法来帮助处理日志和常规表达pattern=r"(?P