1 简介
这个是用在生产环境中的一个MongoDB慢查询日志自动收集脚本,当初想写这个脚本的思路就是为了方便收集慢查询日志并且利于分析。由于公司的mognodb不多,就4台,所以这个小脚本也只是适用普通的生产环境。
页面主要使用了 bootstrap 为前端显示,datatable 为分析的时候使用。
2 流程
主要的流程是:
1 通过 pymongo 连接到 mongodb
2 使用find()命令查询 system.profile下的所有慢查询日志
3 使用jinjia2模块,把查询到的日志信息整合到一个HTML模版中去。
4 把整合后的HTML文件,以附件的形式发送邮件给本人(使用sendmail模块)
5 将脚本写到 crontab 中去,每天定时发送邮件。
注意: 前提是要开启慢查询日志,开启方法见:http://yucanghai.blog.51cto.com/5260262/1705195
3 代码
3.1 文件结构
config.py # 配置文件 mongodb_slowlog.html #生成的html文件 mongodb_slowlog.py # 主文件 myhtml.py # html模块
3.2 代码信息
1 config.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
mail_to_list = [‘xxxx@xx.cn‘] #收件人列表
mail_host = ‘smtp.163.com‘
mail_user = ‘xxx‘ #发件人用户
mail_pass = ‘xxx‘
mail_postfix = ‘163.com‘
#mongodb 的用户和密码
usename = ‘root‘
password = ‘xxx‘
# db 为要分析的 数据库
ip_db_list = [
{‘ip‘:‘10.18.96.86‘,‘port‘:27017,‘db‘:‘test‘,‘hostname‘:‘test1‘,‘property‘:‘primary‘,‘slow_log‘:[]},
]2 mongodb_slowlog.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pymongo
import bson
from jinja2 import Template
from myhtml import html_str
import config
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import time
import datetime
def _conn(ip,port):
try:
conn = pymongo.MongoClient(‘%s‘%ip,port)
except Exception,e:
conn = None
print e
return conn
#将系统时间转化为 mongodb能识别的时间
def convert_time(t):
tm = bson.Timestamp(t,1)
return tm.as_datetime()
#发送邮件 -- 有附件
def send_mail():
msg = MIMEMultipart()
att = MIMEText(open(‘mongodb_slowlog.html‘,‘rb‘).read(),‘base64‘,‘gb2312‘)
att[‘Content-Type‘] = ‘application/octet-stream‘
att["Content-Disposition"] = ‘attachment; filename="MongoDB-Slow-Log%s.html"‘%time.strftime(‘%Y-%m-%d %H:%M:%S‘)
msg.attach(att)
me = ‘MongoDB‘+‘<‘+config.mail_user+"@"+config.mail_postfix+">"
msg[‘Subject‘] = ‘MongoDB Slow Log -- %s‘%time.strftime(‘%Y-%m-%d %H:%M:%S‘)
msg[‘From‘] = me
msg[‘To‘] = ‘;‘.join(config.mail_to_list)
try:
server = smtplib.SMTP()
server.connect(config.mail_host)
server.login(config.mail_user,config.mail_pass)
server.sendmail(me,config.mail_to_list,msg.as_string())
server.quit()
return True
except Exception,e:
print e
return False
#获取慢日志信息
def profile_info(today,yesterday):
for ip_db in config.ip_db_list:
conn = _conn(ip_db[‘ip‘],ip_db[‘port‘])
#用户验证
#auth_db = conn.admin
#auth_db.authenticate(config.usename,config.password)
db_conn = getattr(conn,ip_db[‘db‘])
if db_conn.profiling_level():
#获取 一天内的 排除 getmore 和 comadn 后的 慢日志
ip_db[‘slow_log‘].append(list(db_conn.system.profile.find({‘ts‘:{"$lt":today,"$gt":yesterday}, "op":{"$nin":[‘getmore‘,‘command‘]}})))
#print ip_db[‘slow_log‘]
#解析获取到的日志到 html中
template = Template(html_str)
rest_html = template.render(db_info = ip_db)
#print rest_html
#将获取到的html 写如文件,作为附件发送给 用户
with open(‘mongodb_slowlog.html‘,‘w‘) as f:
f.write(rest_html)
print ‘发送成功!‘ if send_mail() else ‘发送失败!‘
if __name__ == ‘__main__‘:
today_time = convert_time(datetime.datetime.today())
yesterday_time = convert_time(today_time + datetime.timedelta(days=-1))
profile_info(today_time,yesterday_time)备注:
可以根据自己的需求更改,思路不变
3 myhtml.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
html_str =‘‘‘
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<title>MongoDB Slow Log</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="http://cdn.datatables.net/1.10.9/css/jquery.dataTables.min.css">
<!--[endif]-->
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">MongoDB Slow Log</a>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-9 col-sm-offset-1 col-md-10 col-md-offset-1 main">
<br><br><br><br>
<h4 class="page-header" style="display: inline">IP:{{ db_info.ip }}</h4>
<h4 class="page-header" style="display: inline">HostName:{{ db_info.hostname }}</h4>
<h4 class="page-header" style="display: inline">Property:{{ db_info.property }}</h4>
<br><br>
<div class="table-responsive">
<table id="myTable" class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Namespace</th>
<th>Option</th>
<th>Query</th>
<th>Millis</th>
<th>Nscanned</th>
<th>Nreturned</th>
<th>ResponseLength</th>
<th>Ts</th>
</tr>
</thead>
<tbody>
{% for item in db_info.slow_log %}
{% for i in item %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ i.ns }}</td>
<td>{{ i.op }}</td>
<td>{{ i.query }}</td>
<td>{{ i.millis }}</td>
<td>{{ i.nscanned }}</td>
<td>{{ i.nreturned }}</td>
<td>{{ i.responseLength }}</td>
<td>{{ i.ts }}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="http://cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js"></script>
<script type="text/javascript">
$(‘#myTable‘).DataTable( {
select: true
} );
</script>
</body>
</html>
‘‘‘4 mongodb_slowlog.html
主要为通过 myhtml.py 生成的模版
这个脚本写的比较匆忙,还有不完善的地方,有什么疑问大家都可以来问我呀
本文出自 “一个奋斗的小运维” 博客,请务必保留此出处http://yucanghai.blog.51cto.com/5260262/1705559
mongodb+python 实现自动收集mongodb的慢查询日志(附代码)
原文地址:http://yucanghai.blog.51cto.com/5260262/1705559