root / plugins / mongodb / mongo_collection_ @ 9121b90e
Historique | Voir | Annoter | Télécharger (6,95 ko)
| 1 |
#!/usr/bin/env python |
|---|---|
| 2 |
# -*- coding: utf-8 -*- |
| 3 |
# vim: set sts=4 sw=4 encoding=utf-8 |
| 4 |
|
| 5 |
# Based on plugins from https://github.com/pcdummy/mongomon |
| 6 |
# Copyright (c) 2015, Tomas Zvala |
| 7 |
# Copyright (c) 2010, Rene Jochum |
| 8 |
# All rights reserved. |
| 9 |
# |
| 10 |
# Redistribution and use in source and binary forms, with or without |
| 11 |
# modification, are permitted provided that the following conditions are met: |
| 12 |
# * Redistributions of source code must retain the above copyright |
| 13 |
# notice, this list of conditions and the following disclaimer. |
| 14 |
# * Redistributions in binary form must reproduce the above copyright |
| 15 |
# notice, this list of conditions and the following disclaimer in the |
| 16 |
# documentation and/or other materials provided with the distribution. |
| 17 |
# * Neither the name of the Rene Jochum nor the |
| 18 |
# names of its contributors may be used to endorse or promote products |
| 19 |
# derived from this software without specific prior written permission. |
| 20 |
# |
| 21 |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 22 |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 23 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 24 |
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY |
| 25 |
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 26 |
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 27 |
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 28 |
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 30 |
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 |
|
| 32 |
#%# family=auto |
| 33 |
#%# capabilities=suggest autoconf |
| 34 |
|
| 35 |
|
| 36 |
import pymongo |
| 37 |
from operator import itemgetter |
| 38 |
|
| 39 |
settings_host = '127.0.0.1' |
| 40 |
settings_port = 27017 |
| 41 |
# mongodb_uri will override host and port |
| 42 |
settings_mongodb_uri = '' |
| 43 |
settings_db = 'mydb' |
| 44 |
settings_user = '' |
| 45 |
settings_password = '' |
| 46 |
settings_ignoredb = {}
|
| 47 |
|
| 48 |
typeIndex = {}
|
| 49 |
typeIndex['collcount'] = {}
|
| 50 |
typeIndex['collcount']['index'] = 'count' |
| 51 |
typeIndex['collcount']['title'] = 'per collection document count' |
| 52 |
typeIndex['collcount']['yaxis'] = 'documents' |
| 53 |
typeIndex['collcount']['base'] = '1000' |
| 54 |
typeIndex['collcount']['scale'] = '--logarithmic -l1' |
| 55 |
typeIndex['collcount']['category'] = 'MongoDB' |
| 56 |
|
| 57 |
typeIndex['collsize'] = {}
|
| 58 |
typeIndex['collsize']['index'] = 'size' |
| 59 |
typeIndex['collsize']['title'] = 'per collection data size' |
| 60 |
typeIndex['collsize']['yaxis'] = 'Byte' |
| 61 |
typeIndex['collsize']['base'] = '1024' |
| 62 |
typeIndex['collsize']['scale'] = '--logarithmic -l1 --units=si' |
| 63 |
typeIndex['collsize']['category'] = 'MongoDB' |
| 64 |
|
| 65 |
typeIndex['avgsize'] = {}
|
| 66 |
typeIndex['avgsize']['index'] = 'avgObjSize' |
| 67 |
typeIndex['avgsize']['title'] = 'average object size' |
| 68 |
typeIndex['avgsize']['yaxis'] = 'Byte' |
| 69 |
typeIndex['avgsize']['base'] = '1024' |
| 70 |
typeIndex['avgsize']['scale'] = '--logarithmic --units=si' |
| 71 |
typeIndex['avgsize']['category'] = 'MongoDB' |
| 72 |
|
| 73 |
typeIndex['storage'] = {}
|
| 74 |
typeIndex['storage']['index'] = 'storageSize' |
| 75 |
typeIndex['storage']['title'] = 'per collection storage size' |
| 76 |
typeIndex['storage']['yaxis'] = 'Byte' |
| 77 |
typeIndex['storage']['base'] = '1024' |
| 78 |
typeIndex['storage']['scale'] = '--logarithmic -l1 --units=si' |
| 79 |
typeIndex['storage']['category'] = 'MongoDB' |
| 80 |
|
| 81 |
typeIndex['indexsize'] = {}
|
| 82 |
typeIndex['indexsize']['index'] = 'totalIndexSize' |
| 83 |
typeIndex['indexsize']['title'] = 'per collection index size' |
| 84 |
typeIndex['indexsize']['yaxis'] = 'Byte' |
| 85 |
typeIndex['indexsize']['base'] = '1024' |
| 86 |
typeIndex['indexsize']['scale'] = '--logarithmic -l 1 --units=si' |
| 87 |
typeIndex['indexsize']['category'] = 'MongoDB' |
| 88 |
|
| 89 |
|
| 90 |
def getCollstats(graphtype): |
| 91 |
if settings_mongodb_uri: |
| 92 |
con = pymongo.MongoClient(settings_mongodb_uri) |
| 93 |
else: |
| 94 |
con = pymongo.MongoClient(settings_host, int(settings_port)) |
| 95 |
|
| 96 |
if settings_user: |
| 97 |
db = con['admin'] |
| 98 |
db.authenticate(settings_user, settings_password) |
| 99 |
|
| 100 |
stats_tmp = {}
|
| 101 |
for dbname in con.database_names(): |
| 102 |
if dbname in settings_ignoredb: |
| 103 |
continue |
| 104 |
db = con[dbname] |
| 105 |
for coll in db.collection_names(): |
| 106 |
if coll.startswith('system.'):
|
| 107 |
continue |
| 108 |
stats = db.command("collstats", coll)
|
| 109 |
collname = dbname + "_" + coll.replace('.', '_')
|
| 110 |
if not stats_tmp.has_key(collname): |
| 111 |
stats_tmp[collname] = {}
|
| 112 |
stats_tmp[collname]['value'] = 0 |
| 113 |
stats_tmp[collname]['dbname'] = dbname |
| 114 |
if typeIndex[graphtype]['index'] in stats: |
| 115 |
stats_tmp[collname]['value'] += long(stats[typeIndex[graphtype]['index']]) |
| 116 |
|
| 117 |
|
| 118 |
con.close() |
| 119 |
|
| 120 |
for collname, item in sorted(stats_tmp.items()): |
| 121 |
yield ("%s" % collname, item['value'], item['dbname'])
|
| 122 |
|
| 123 |
|
| 124 |
def doData(base,graphtype): |
| 125 |
lastdb = "" |
| 126 |
for coll, stats, db in sorted(getCollstats(graphtype), key=itemgetter(2)): |
| 127 |
if lastdb != db: |
| 128 |
print "multigraph " + base + "_" + graphtype + "_" + db |
| 129 |
lastdb = db |
| 130 |
print "%s_%s.value %s" % (graphtype, coll, stats) |
| 131 |
|
| 132 |
|
| 133 |
def doConfig(base,graphtype): |
| 134 |
|
| 135 |
lastdb = "" |
| 136 |
for k,v,d in sorted(getCollstats(graphtype), key=itemgetter(2)): |
| 137 |
if lastdb != d: |
| 138 |
print "multigraph " + base + "_" + graphtype + "_" + d |
| 139 |
lastdb = d |
| 140 |
# print "graph_total total" |
| 141 |
print "graph_title MongoDB " + typeIndex[graphtype]['title'] + " for database " + d |
| 142 |
print "graph_args --base " + typeIndex[graphtype]['base'] + " " + typeIndex[graphtype]['scale'] |
| 143 |
print "graph_vlabel " + typeIndex[graphtype]['yaxis'] |
| 144 |
print "graph_category MongoDB" |
| 145 |
print "%s_%s.label %s" % (graphtype, k, k) |
| 146 |
print "%s_%s.min 0" % (graphtype, k) |
| 147 |
print "%s_%s.draw LINE1" % (graphtype, k) |
| 148 |
|
| 149 |
def doSuggest(): |
| 150 |
print "keys" |
| 151 |
for k in typeIndex.keys(): |
| 152 |
print k |
| 153 |
|
| 154 |
|
| 155 |
if __name__ == "__main__": |
| 156 |
from sys import argv,exit |
| 157 |
from os import environ,path |
| 158 |
import re |
| 159 |
|
| 160 |
# Could be done by a for loop |
| 161 |
# but i think if's are faster |
| 162 |
if 'HOST' in environ: |
| 163 |
settings_host = environ['HOST'] |
| 164 |
if 'PORT' in environ: |
| 165 |
settings_port = environ['PORT'] |
| 166 |
if 'DB' in environ: |
| 167 |
settings_db = environ['DB'] |
| 168 |
if 'MONGO_USER' in environ: |
| 169 |
settings_user = environ['MONGO_USER'] |
| 170 |
if 'PASSWORD' in environ: |
| 171 |
settings_password = environ['PASSWORD'] |
| 172 |
if 'IGNOREDB' in environ: |
| 173 |
settings_ignoredb = environ['IGNOREDB'].split(',')
|
| 174 |
m = re.search('^(.*)_([a-zA-Z0-9]*)$', path.basename(argv[0]))
|
| 175 |
if len(argv) < 2: |
| 176 |
doData(m.group(1),m.group(2)) |
| 177 |
elif argv[1] == "config": |
| 178 |
doConfig(m.group(1),m.group(2)) |
| 179 |
elif argv[1] == "autoconf": |
| 180 |
print "yes" |
| 181 |
elif argv[1] == "suggest": |
| 182 |
doSuggest() |
| 183 |
else: |
| 184 |
print "invalid argument" |
| 185 |
exit(1) |
