在Python中,一般情况下,我们可能会直接使用内置的logging模块来记录日志,包括我之前的时候。在使用的时候,我们需要配置一些Handlers和Formatters来进行一些处理,比如将日志输出到不同的位置,或者设置不同的输出格式,或者设置日志分块和备份等。但其实我个人觉得logging并没有那么好用。其实主要还是配置比较繁琐。常见的使用先来看看日志的常见解决方案。我通常将输出配置为文件、控制台和Elasticsearch。输出到控制台只是为了直接查看;输出到文件,方便所有历史记录的直接存储和备份;输出到Elasticsearch直接以Elasticsearch为中心存储分析,使用Kibana运行情况分析查看非常方便。所以这里我基本上会写如下日志包:importloggingimportsysfromosimportmakedirsfromos.pathimportdirname,existsfromcmreslogging.handlersimportCMRESHandlerloggers={}LOG_ENABLED=True#是否启用日志LOG_TO_CONSOLE=True#是否输出到LOG_TO_FILE=True#是否输出到文件LOG_TO_ES=True#是否输出到ElasticsearchLOG_PATH='./runtime.log'#日志文件路径LOG_LEVEL='DEBUG'#日志级别LOG_FORMAT='%(levelname)s-%(asctime)s-process:%(process)d-%(filename)s-%(name)s-%(lineno)d-%(module)s-%(message)s'#每种日志输出格式ELASTIC_SEARCH_HOST='eshost'#ElasticsearchHostELASTIC_SEARCH_PORT=9200#ElasticsearchPortELASTIC_SEARCH_INDEX='runtime'#ElasticsearchIndexNameAPP_ENVIRONMENT='dev'#运行环境,比如测试环境或者生产环境defget_logger(name=None):"""getloggerby名称:参数名称:记录器的名称:返回:记录器“”"globalloggersifnotname:name=__name__ifloggers.get(name):returnloggers.get(name)logger=logging.getLogger(name)logger.setLevel(LOG_LEVEL)#如果LOG_ENABLED和LOG_TO_CONSOLE输出到控制台:.setFormatter(formatter)logger.addHandler(stream_handler)#OutputtofileifLOG_ENABLEDandLOG_TO_FILE:#如果路径不存在,创建日志文件夹log_dir=dirname(log_path)ifnotexists(log_dir):makedirs(log_dir)#添加文件处理程序file_handler=logging.FileHandler(log_path,encoding='utf-8')file_handler.setLevel(level=LOG_LEVEL)formatter=logging.Formatter(LOG_FORMAT)file_handler.setFormatter(formatter)logger.addHandler(file_handler)#输出到ElasticsearchifLOG_ENABLEDandLOG_TO_ES:#添加CMRESHandleres_handler=CMRESHandler(hosts=[{'host':ELASTIC_SEARCH_HOST,'port':ELASTIC_SEARCH_PORT}],#可以配置对应的认证权限auth_type=CMRESHandler.AuthType.NO_AUTH,es_index_name=ELASTIC_SEARCH_INDEX,#每月一个Indexindex_name_frequency=CMRESHandler.IndexNameFrequency.MONTHLY,#添加额外的环境标识es_additional_fields={'environment':APP_ENVIRONMENT})es_handler.setLevel(level=LOG_LEVEL)formatter=logging.Formatter(LOG_FORMAT)es_handler.setFormatter(formatter)logger.addHandler(es_handler)#保存到全局记录器loggers[name]=loggerreturn定义后如何使用记录器?只需要使用定义的方法获取一个logger,然后记录相应的内容即可:logger=get_logger()logger.debug('thisisamessage')运行结果如下:DEBUG-2019-10-1122:27:35,923-进程:99490-logger.py-__main__-81-记录器-这是一条消息让我们看看定义的基本实现。首先,这里的一些常量用于定义日志模块的一些基本属性。比如LOG_ENABLED表示是否开启日志功能,LOG_TO_ES表示是否将日志输出到Elasticsearch,还有很多其他的基本日志配置,比如LOG_FORMAT配置了每条日志条目输出的基本格式,还有一些连接所需的信息。这些变量可以在运行时与命令行或环境变量连接,可以轻松实现一些开关和配置的替换。然后定义这样一个接收参数名的get_logger方法。首先,方法获取名称后,会在全局的loggers变量中查找。loggers变量是一个全局字典。如果有声明的logger,可以直接获取并返回,无需重新初始化。如果在loggers中没有找到name对应的logger,就创建一个。创建logger后,可以为其添加各种对应的Handler,如输出到控制台的StreamHandler,输出到文件的FileHandler或RotatingFileHandler,输出到Elasticsearch的CMRESHandler,并分别配置相应的信息。最后将新建的logger保存在全局loggers中并返回即可,这样如果有同名的log??ger可以直接找到loggers直接返回。这里我们依赖一个额外的输出到Elasticsearch的包,叫做CMRESHandler,它支持输出日志到Elasticsearch。如果你想使用它,你可以安装它:pipinstallCMRESHandler,它的GitHub地址是:https://github.com/cmanaha/py...,具体使用可以参考它的官方说明,比如配置认证信息,配置索引分离信息等。嗯,以上是我之前使用的日志记录配置。通过上面的配置,我可以将logging输出到三个位置,达到相应的效果。比如输出到Elasticsearch之后,我可以很方便的用Kibana查看当前的运行状态,ERRORLog的占比等等,我还可以在它的基础上做进一步的统计分析。loguru上面的实现已经是比较可行的配置方案了。不过还是觉得有些Handlers搭配起来比较麻烦,尤其是新建项目的时候懒得写一些配置。即使不使用上面的配置,也使用最基本的日志配置,比如下面的通用配置:importlogginglogging.basicConfig(level=logging.INFO,format='%(asctime)s-%(name)s-%(levelname)s-%(message)s')logger=logging.getLogger(__name__)懒得写了,感觉不是很优雅的实现方式。哪里有需求,哪里就有动力。这不,有人实现了这样一个叫loguru的库,可以让log的配置和使用更加简单方便。让我们来看看它是如何使用的。安装首先,这个库的安装方法很简单,使用基本的pip安装即可,Python3版本的安装如下:pip3installloguru安装完成后,我们就可以在项目中使用这个loguru库了。基本使用那么如何使用这个库呢?我们先用一个例子感受一下:fromloguruimportloggerlogger.debug('thisisadebugmessage')看吧,什么都不用配置,直接导入一个logger,然后调用它的debug方法即可。loguru中只有一个主要对象,就是logger。loguru中只有一个logger,并且已经预先配置了一些基本信息,比如友好的格式、文本颜色信息等等。上面代码运行结果如下:2019-10-1322:46:12.367|调试|__main__:
