我几个月前在《Python 日志功能详解》中介绍了Python log模块的基本使用方法,但按照那篇文章的内容组织,还有一些东西不好放进去展开,原本打算单独开一篇文章把剩下的事情再讲明白的,结果被各种事情耽误,一直拖到现在,只能按照现在的思路继续展开了。本文就讲一下Python log 模块与mongodb的结合。
MongoDB是专为可扩展性,高性能和高可用性而设计的数据库,可以应用于各种规模的企业、各个行业以及各类应用程序,其数据模式可以随着应用程序的发展而灵活地更新。
服务器的日常运维通常会产生大量的日志信息(如错误、警告和用户行为),这些日志信息通常是以文本格式存储于服务器本机的日志文件中。文本格式的日志虽然具有很好的可读性,但每次都要打开服务器本机查看,使用和分析日志比较麻烦,再结合当今微服务架构的潮流,基于本机日志文件的日志存储方式也会给开发和运维带来不少的附加的、可避免的工作量,将日志存储于数据库会可以让使用和分析日志的更加高效。MongoDB性能高,易于扩展,且 schama freeness
,将日志存储于 MongoDB 非常合适,有不少开发者和企业都把日志存储于MongoDB中。
log4mongo-python 为Python logging 模块提供了一个 mongodb的handler,它依赖于 pymongo driver ,可以无缝应用到Python logging 模块,所以只要理解《Python 日志功能详解》中介绍的内容,log4mongo-python就能直接上手。因此本文不再赘述Python logging 模块的使用,直接提供一个参考样例(也可以在 GitHub 中查看最新版本):
#!/usr/local/bin/python # -*- coding: utf-8 -*- import logging from log4mongo.handlers import MongoHandler logger = logging.getLogger('mongo_example') mon = MongoHandler(host='localhost', database_name='mongo_logs') mon.setLevel(logging.WARNING) ch = logging.StreamHandler() ch.setLevel(logging.ERROR) logger.addHandler(mon) logger.addHandler(ch) logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
上面例子中,使用MongoDB存储日志的核心是创建了相应的handler,即下面这一行:
mon = MongoHandler(host='localhost', database_name='mongo_logs')
创建MongoHandler非常简单,大部分参数都有默认值,如果想配置更多参数,直接看一下 MongoHandler
的 __init__
函数即可:
def __init__(self, level=logging.NOTSET, host='localhost', port=27017, database_name='logs', collection='logs', username=None, password=None, authentication_db='admin', fail_silently=False, formatter=None, capped=False, capped_max=1000, capped_size=1000000, reuse=True, **kwargs)
基于我个人的开发实践,中大型项目开发中,通过Dict配置logging模块用的最多,由于 log4mongo-python
只是在logging模块上增加了一个新的handler,所以Dict与《Python 日志功能详解》中的写法一致,并根据实际情况赋上 MongoHandler
初始化的参数值即可。举例如下:
#!/usr/local/bin/python # -*- coding: utf-8 -*- import logging import logging.config from log4mongo.handlers import MongoHandler config = { 'version': 1, 'formatters': { 'simple': { 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'level': 'DEBUG', 'formatter': 'simple' }, 'file': { 'class': 'logging.FileHandler', 'filename': 'logging.log', 'level': 'DEBUG', 'formatter': 'simple' }, 'mongo': { 'class': 'log4mongo.handlers.MongoHandler', 'host': 'localhost', # 'port': 27017, 'database_name': 'mongo_logs2', # 'collection': 'logs', 'level': 'DEBUG', }, }, 'loggers':{ 'root': { 'handlers': ['console'], 'level': 'DEBUG', # 'propagate': True, }, 'simple': { 'handlers': ['console', 'file'], 'level': 'WARN', }, 'mongo': { 'handlers': ['console', 'mongo'], 'level': 'DEBUG', } } } logging.config.dictConfig(config) # print 'logger:' # logger = logging.getLogger('root') # logger.debug('debug message') # logger.info('info message') # logger.warn('warn message') # logger.error('error message') # logger.critical('critical message') # print 'logger2:' # logger2 = logging.getLogger('simple') # logger2.debug('debug message') # logger2.info('info message') # logger2.warn('warn message') # logger2.error('error message') # logger2.critical('critical message') print 'logger3:' logger2 = logging.getLogger('mongo') logger2.debug('debug message') logger2.info('info message') logger2.warn('warn message') logger2.error('error message') logger2.critical('critical message')