本文首發於 Gevin的博客python
原文連接:基於MongoDB的python日誌功能git
未經 Gevin 受權,禁止轉載github
我幾個月前在《Python 日誌功能詳解》中介紹了Python log模塊的基本使用方法,但按照那篇文章的內容組織,還有一些東西很差放進去展開,本來打算單獨開一篇文章把剩下的事情再講明白的,結果被各類事情耽誤,一直拖到如今,只能按照如今的思路繼續展開了。本文就講一下Python log 模塊與mongodb的結合。mongodb
MongoDB是專爲可擴展性,高性能和高可用性而設計的數據庫,能夠應用於各類規模的企業、各個行業以及各種應用程序,其數據模式能夠隨着應用程序的發展而靈活地更新。數據庫
服務器的平常運維一般會產生大量的日誌信息(如錯誤、警告和用戶行爲),這些日誌信息一般是以文本格式存儲於服務器本機的日誌文件中。文本格式的日誌雖然具備很好的可讀性,但每次都要打開服務器本機查看,使用和分析日誌比較麻煩,再結合當今微服務架構的潮流,基於本機日誌文件的日誌存儲方式也會給開發和運維帶來很多的附加的、可避免的工做量,將日誌存儲於數據庫會可讓使用和分析日誌的更加高效。MongoDB性能高,易於擴展,且schama freeness
,將日誌存儲於 MongoDB 很是合適,有很多開發者和企業都把日誌存儲於MongoDB中。flask
那麼,基於Python開發時,如何用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,即下面這一行:app
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')複製代碼
基於log4mongo
將日誌信息寫入MongoDB後,能夠經過RoboMongo或MongoChef等MongoDB客戶端查看日誌信息,並利用各類MongoDB的數據庫查詢語言,對日誌進行分析處理。
題圖來自Logging Application Behavior to MongoDB 相關內容。