您的当前位置:首页正文

python笔记46-史上最强大最好用的python日志模块nb_log

2023-05-20 来源:意榕旅游网
python笔记46-史上最强⼤最好⽤的python⽇志模块nb_log

前⾔

python的⽇志模块如何封装⼀值都是⼀个头疼的问题,封装的不好总是会出现重复打印等头疼问题。现在终于找到⼀个最好⽤的⽇志模块nb_log,此⽇志模块由这位⼤佬开发的

环境安装

使⽤pip即可安装使⽤

pip install nb_log

1.功能介绍

0)⾃动转换print效果,再也不怕有⼈在项⽬中随意print,导致很难找到是从哪⾥冒出来的print。只要import nb_log,项⽬所有地⽅的print⾃动现型并在控制台可点击⼏精确跳转到print的地⽅。

1)兼容性

使⽤的是python的内置logging封装的,返回的logger对象的类型是py官⽅内置⽇志的Logger类型,兼容性强,保证了第三⽅各种handlers扩展数量多和⽅便,和⼀键切换现有项⽬的⽇志。

⽐如logru和logbook这种三⽅库,完全重新写的⽇志,

它⾥⾯主要被⽤户使⽤的logger变量类型不是python内置Logger类型,

造成logger说拥有的属性和⽅法有的不存在或者不⼀致,这样的⽇志和python内置的经典⽇志兼容性差,只能兼容(⼀键替换logger类型)⼀些简单的debug info warning errror等⽅法,。

2) ⽇志记录到多个地⽅

内置了⼀键⼊参,每个参数是独⽴开关,可以把⽇志同时记录到8个常⽤的地⽅的任意⼏种组合,包括 控制台 ⽂件 钉钉 邮件 mongo kafka es 等等 。在第8章介绍实现这种效果的观察者模式。3) ⽇志命名空间独⽴,采⽤了多实例logger,按⽇志命名空间区分。

命名空间独⽴意味着每个logger单独的⽇志界别过滤,单独的控制要记录到哪些地⽅。

logger_aa = LogManager('aa').get_logger_and_add_handlers(10,log_filename='aa.log')

logger_bb = LogManager('bb').get_logger_and_add_handlers(30,is_add_stream_handler=False,ding_talk_token='your_dingding_token')

logger_cc = LogManager('cc').get_logger_and_add_handlers(10,log_filename='cc.log')

那么logger_aa.debug('哈哈哈')

将会同时记录到控制台和⽂件aa.log中,只要debug及debug以上级别都会记录。

logger_bb.warning('嘿嘿嘿')

将只会发送到钉钉群消息,并且logger_bb的info debug级别⽇志不会被记录,⾮常⽅便测试调试然后稳定了调⾼界别到⽣产。

logger_cc的⽇志会写在cc.log中,和logger_aa的⽇志是不同的⽂件。4) 对内置looging包打了猴⼦补丁,使⽇志永远不会使⽤同种handler重复记录例如,原⽣的

from logging import getLogger,StreamHandlerlogger = getLogger('hi')

getLogger('hi').addHandler(StreamHandler())getLogger('hi').addHandler(StreamHandler())getLogger('hi').addHandler(StreamHandler())logger.warning('啦啦啦')

明明只warning了⼀次,但实际会造成 啦啦啦 在控制台打印3次。

使⽤nb_log,对同⼀命名空间的⽇志,可以⽆惧反复添加同类型handler,不会重复记录。

5)⽀持⽇志⾃定义,运⾏此包后,会⾃动在你的python项⽬根⽬录中⽣成nb_log_config.py⽂件,按说明修改。

2.最简单的使⽤⽅式,这只是演⽰控制台⽇志

2.0)⾃动拦截改变项⽬中所有地⽅的print效果。(⽀持配置⽂件⾃定义关闭转化print)

2.1)控制台⽇志变成可点击,精确跳转。(⽀持配置⽂件⾃定义修改或增加模板,内置了7种模板,部分模板⽣成的⽇志可以在pycharm控制台点击跳转)2.2)控制台⽇志根据⽇志级别⾃动变⾊。(⽀持配置⽂件关闭彩⾊或者关闭背景⾊块)

from nb_log import LogManager

logger = LogManager('lalala').get_logger_and_add_handlers()logger.debug('绿⾊')logger.info('蓝⾊')logger.warn('黄⾊')logger.error('紫红⾊')logger.critical('⾎红⾊')

print('print样式被⾃动发⽣变化')

3 ⽂件⽇志

3.1)这个⽂件⽇志的⾃定义filehandler是python史上性能最强⼤的 ⽀持多进程下⽇志⽂件按⼤⼩⾃动切割。在各种filehandler实现难度上 单进程永不切割 < 多进程按时间切割 < 单进程按⼤⼩切割 << 多进程按⼤⼩切割

因为每天⽇志⼤⼩很难确定,如果每天所有⽇志⽂件以及备份加起来超过40g了,硬盘就会满挂了,所以nb_log的⽂件⽇志filehandler采⽤的是按⼤⼩切割,不使⽤按时间切割。⽂件⽇志⾃动使⽤的是多进程安全切割的⾃定义filehandler, logging包的RotatingFileHandler多进程运⾏代码时候,如果要实现向⽂件写⼊到规定⼤⼩时候并⾃动备份切割,win和linux都100%报错。

⽀持多进程安全切⽚的知名的handler有ConcurrentRotatingFileHandler, 此handler能够确保win和linux切割正确不出错,此包在linux使⽤的是⾼效的fcntl⽂件锁, 在win上性能惨不忍睹,这个包在win的性能在三⽅包的英⽂说明注释中,作者已经提到了。

nb_log是基于⾃动批量聚合,从⽽减少写⼊次数(但⽂件⽇志的追加最多会有1秒的延迟),从⽽⼤幅度减少反复给⽂件加锁解锁, 使快速⼤量写⼊⽂件⽇志的性能⼤幅提⾼,在保证多进程安全且排列的前提下,对⽐这个ConcurrentRotatingFileHandler 使win的⽇志⽂件写⼊速度提⾼100倍,在linux上写⼊速度提⾼10倍。3.2)演⽰⽂件⽇志,并且直接演⽰最⾼实现难度的多进程安全切⽚⽂件⽇志

from multiprocessing import Processfrom nb_log import LogManager

#指定log_filename不为None 就⾃动写⼊⽂件了,并且默认使⽤的是多进程安全的切割⽅式的filehandler。

#默认都添加了控制台⽇志,如果不想要控制台⽇志,设置is_add_stream_handler=False#为了保持⽅法⼊场数量少,具体的切割⼤⼩和备份⽂件个数有默认值,

#如果需要修改切割⼤⼩和⽂件数量,在当前python项⽬根⽬录⾃动⽣成的nb_log_config.py⽂件中指定。logger = LogManager('ha').get_logger_and_add_handlers(is_add_stream_handler=True,log_filename='ha.log')

def f():

for i in range(1000000000):

logger.debug('测试⽂件写⼊性能,在满⾜ 1.多进程运⾏ 2.按⼤⼩⾃动切割备份 3切割备份瞬间不出错'

'这3个条件的前提下,验证这是不是python史上⽂件写⼊速度遥遥领先 性能最强的python logging handler')

if __name__ == '__main__':

[Process(target=f).start() for _ in range(10)]

4 钉钉⽇志

from nb_log import LogManager

logger4 = LogManager('hi').get_logger_and_add_handlers(is_add_stream_handler=True, log_filename='hi.log',ding_talk_token='your_dingding_token')logger4.debug('这条⽇志会同时出现在控制台 ⽂件 和钉钉群消息')

5 其他handler包括kafka⽇志,elastic⽇志,邮件⽇志,mongodb⽇志

按照get_logger_and_add_handler函数的⼊参说明就可以了,和上⾯的2 3 4中的写法⽅式差不多,都是⼀参 傻⽠式,设置了,⽇志记录就会记载在各种地⽅。

6 ⽇志优先默认配置

只要项⽬任意⽂件运⾏了,带有import nb_log的脚本,就会在项⽬根⽬录下⽣成nb_log_config.py配置⽂件。 nb_log_config.py的内容如下,默认都是⽤#注释了,如果放开某项配置则优先使⽤这⾥的配置,否则使⽤nb_log_config_default.py中的配置。配置⽰例如下:

如果反对⽇志有各种彩⾊,可以设置 DEFAULUT_USE_COLOR_HANDLER = False

如果反对⽇志有块状背景彩⾊,可以设置 DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = False

如果想屏蔽nb_log包对怎么设置pycahrm的颜⾊的提⽰,可以设置 WARNING_PYCHARM_COLOR_SETINGS = False如果想改变⽇志模板,可以设置 FORMATTER_KIND 参数,只带了7种模板,可以⾃定义添加喜欢的模板

import logging

ELASTIC_HOST = '127.0.0.1'ELASTIC_PORT = 9200

KAFKA_BOOTSTRAP_SERVERS = ['192.168.199.202:9092']

ALWAYS_ADD_KAFKA_HANDLER_IN_TEST_ENVIRONENT = FalseMONGO_URL = 'mongodb://myUserAdmin:mima@127.0.0.1:27016/admin'

DEFAULUT_USE_COLOR_HANDLER = True # 是否默认使⽤有彩的⽇志。

DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = True # 在控制台是否显⽰彩⾊块状的⽇志。为False则不使⽤⼤块的背景颜⾊。AUTO_PATCH_PRINT = True # 是否⾃动打print的猴⼦补丁,如果打了后指不定,print⾃动变⾊和可点击跳转。WARNING_PYCHARM_COLOR_SETINGS = True

DEFAULT_ADD_MULTIPROCESSING_SAFE_ROATING_FILE_HANDLER = False # 是否默认同时将⽇志记录到记log⽂件记事本中。LOG_FILE_SIZE = 100 # 单位是M,每个⽂件的切⽚⼤⼩,超过多少后就⾃动切割LOG_FILE_BACKUP_COUNT = 3

LOG_LEVEL_FILTER = logging.DEBUG # 默认⽇志级别,低于此级别的⽇志不记录了。例如设置为INFO,那么logger.debug的不会记录,只会记录logger.info以上级别的。RUN_ENV = 'test'

FORMATTER_DICT = { 1: logging.Formatter(

'⽇志时间【%(asctime)s】 - ⽇志名称【%(name)s】 - ⽂件【%(filename)s】 - 第【%(lineno)d】⾏ - ⽇志等级【%(levelname)s】 - ⽇志信息【%(message)s】', \"%Y-%m-%d %H:%M:%S\"), 2: logging.Formatter(

'%(asctime)s - %(name)s - %(filename)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s', \"%Y-%m-%d %H:%M:%S\"), 3: logging.Formatter(

'%(asctime)s - %(name)s - 【 File \"%(pathname)s\】 - %(levelname)s - %(message)s', \"%Y-%m-%d %H:%M:%S\"), # ⼀个模仿traceback异常的可跳转到打印⽇志地⽅的模板 4: logging.Formatter(

'%(asctime)s - %(name)s - \"%(filename)s\" - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s - File \"%(pathname)s\ \"%Y-%m-%d %H:%M:%S\"), # 这个也⽀持⽇志跳转 5: logging.Formatter(

'%(asctime)s - %(name)s - \"%(pathname)s:%(lineno)d\" - %(funcName)s - %(levelname)s - %(message)s', \"%Y-%m-%d %H:%M:%S\"), # 我认为的最好的模板,推荐

6: logging.Formatter('%(name)s - %(asctime)-15s - %(filename)s - %(lineno)d - %(levelname)s: %(message)s', \"%Y-%m-%d %H:%M:%S\"),

7: logging.Formatter('%(levelname)s - %(filename)s - %(lineno)d - %(message)s',\"%Y-%m-%d %H:%M:%S\"), # ⼀个只显⽰简短⽂件名和所处⾏数的⽇志模板}

FORMATTER_KIND = 5 # 如果get_logger_and_add_handlers不指定⽇志模板,则默认选择第⼏个模板

7. 各種⽇志截圖钉钉

控制台⽇志模板之⼀

控制台⽇⼦模板之⼆

邮件⽇志

⽂件⽇志

elastic⽇志

mongo⽇志

8 关于⽇志的观察者模式

不会扩展⽇志记录到什么地⽅,主要是不懂什么叫观察者模式

# 例如 ⽇志想实现记录到 控制台、⽂件、钉钉群、redis、mongo、es、kafka、发邮件其中的⼏种的任意组合。# low的⼈,会这么写,以下是伪代码,实现记录到控制台、⽂件、钉钉群这三种的任意⼏种组合。def 记录到控制台(msg):

\"\"\"实现把msg记录到控制台\"\"\"def 记录到⽂件(msg):

\"\"\"实现把msg记录到⽂件\"\"\"def 记录到钉钉(msg):

\"\"\"实现把msg记录到钉钉\"\"\"def 记录到控制台和⽂件(msg):

\"\"\"实现把msg记录到控制台和⽂件\"\"\"def 记录到控制台和钉钉(msg):

\"\"\"实现把msg记录到控制台和钉钉\"\"\"def 记录到⽂件和钉钉(msg):

\"\"\"实现把msg记录到⽂件和钉钉\"\"\"def 记录到控制台和⽂件和钉钉(msg):

\"\"\"实现把msg记录到控制台和⽂件和钉钉\"\"\"

#当需要把msg记录到⽂件时候,调⽤函数 记录到⽂件(msg)#当需要把msg记录到控制台时候,调⽤函数 记录到控制台(msg)#当需要把msg记录到钉钉时候,调⽤函数 记录到钉钉(msg)

#当需要把msg记录到控制台和⽂件,调⽤函数 记录到控制台和⽂件(msg)#当需要把msg记录到控制台和钉钉,调⽤函数 记录到控制台和钉钉(msg)

#当需要把msg记录到控制台和⽂件和钉钉,调⽤函数 记录到控制台和⽂件和钉钉(msg)

\"\"\"

这样会造成,仅记录到控制台 ⽂件 钉钉这三种的任意⼏个,需要写6个函数,调⽤时候需要调⽤不同的函数名。

但是现在⽇志可以记录到8种地⽅,如果还这么low的写法,需要写8的阶乘个函数,调⽤时候根据场景需要会调⽤8的阶乘个函数名。8的阶乘结果是 40320 ,如果很low不学设计模式做到灵活组合,需要多写 4万多个函数,不学设计模式会多么吓⼈。\"\"\"

观察者模式图⽚

菜鸟教程的观察者模式demo连接

这个uml图上分为Subject 和 基类Observer,以及各种继承或者实现Observer的XxObserver类, 其中每个不同的Observer需要实现doOperation⽅法。如果对应到python内置的logging⽇志包的实现,那么关系就是:Logger是uml图的Subject

loging.Handler类是uml图的Observer类

StreamHandler FileHandler DingTalkHandler 是uml图的各种XxObservers类。StreamHandler FileHandler DingTalkHandler类的 emit⽅法是uml图的doOperation⽅法

只有先学设计模式,才能知道经典固定套路达到快速看代码,能够达到秒懂源码是怎么规划设计实现的。

如果不先学习经典设计模式,每次看包的源码,需要多浪费很多时间看他怎么设计实现的,不懂设计模式,会觉得太难了看着就放弃了。在python⽇志的使⽤和理解上,能够和风神打成平⼿的,国内没有⼏⼈。转⾃

因篇幅问题不能全部显示,请点此查看更多更全内容