本文首发于 Gevin的博客
原文链接:基于MongoDB的python日志功能
未经 Gevin 授权,禁止转载
基于MongoDB的python日志功能
我几个月前在《Python 日志功能详解》中介绍了Python log模块的基本使用方法,但按照那篇文章的内容组织,还有一些东西不好放进去展开,原本打算单独开一篇文章把剩下的事情再讲明白的,结果被各种事情耽误,一直拖到现在,只能按照现在的思路继续展开了。本文就讲一下Python log 模块与mongodb的结合。
MongoDB是专为可扩展性,高性能和高可用性而设计的数据库,可以应用于各种规模的企业、各个行业以及各类应用程序,其数据模式可以随着应用程序的发展而灵活地更新。
服务器的日常运维通常会产生大量的日志信息(如错误、警告和用户行为),这些日志信息通常是以文本格式存储于服务器本机的日志文件中。文本格式的日志虽然具有很好的可读性,但每次都要打开服务器本机查看,使用和分析日志比较麻烦,再结合当今微服务架构的潮流,基于本机日志文件的日志存储方式也会给开发和运维带来不少的附加的、可避免的工作量,将日志存储于数据库会可以让使用和分析日志的更加高效。MongoDB性能高,易于扩展,且schama freeness
,将日志存储于 MongoDB 非常合适,有不少开发者和企业都把日志存储于MongoDB中。
那么,基于Python开发时,如何用MongoDB存储日志?
1. log4mongo-python
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)
2. 通过Dict对象配置log4mongo-python
基于我个人的开发实践,中大型项目开发中,通过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')
3. What's More?
基于log4mongo
将日志信息写入MongoDB后,可以通过RoboMongo或MongoChef等MongoDB客户端查看日志信息,并利用各种MongoDB的数据库查询语言,对日志进行分析处理。
题图来自Logging Application Behavior to MongoDB 相关内容。
网友评论