root / plugins / mongodb / mongo_collection_ @ dca09431
Historique | Voir | Annoter | Télécharger (6,95 ko)
| 1 |
#!/usr/bin/env python3 |
|---|---|
| 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 |
from os import getenv |
| 39 |
|
| 40 |
settings_host = '127.0.0.1' |
| 41 |
settings_port = 27017 |
| 42 |
# mongodb_uri will override host and port |
| 43 |
settings_mongodb_uri = '' |
| 44 |
settings_db = 'admin' |
| 45 |
settings_user = '' |
| 46 |
settings_password = '' |
| 47 |
settings_ignoredb = {}
|
| 48 |
settings_graph_category = getenv('graph_category', 'db')
|
| 49 |
|
| 50 |
typeIndex = {}
|
| 51 |
typeIndex['collcount'] = {}
|
| 52 |
typeIndex['collcount']['index'] = 'count' |
| 53 |
typeIndex['collcount']['title'] = 'per collection document count' |
| 54 |
typeIndex['collcount']['yaxis'] = 'documents' |
| 55 |
typeIndex['collcount']['base'] = '1000' |
| 56 |
typeIndex['collcount']['scale'] = '--logarithmic -l1' |
| 57 |
typeIndex['collcount']['category'] = settings_graph_category |
| 58 |
|
| 59 |
typeIndex['collsize'] = {}
|
| 60 |
typeIndex['collsize']['index'] = 'size' |
| 61 |
typeIndex['collsize']['title'] = 'per collection data size' |
| 62 |
typeIndex['collsize']['yaxis'] = 'Byte' |
| 63 |
typeIndex['collsize']['base'] = '1024' |
| 64 |
typeIndex['collsize']['scale'] = '--logarithmic -l1 --units=si' |
| 65 |
typeIndex['collsize']['category'] = settings_graph_category |
| 66 |
|
| 67 |
typeIndex['avgsize'] = {}
|
| 68 |
typeIndex['avgsize']['index'] = 'avgObjSize' |
| 69 |
typeIndex['avgsize']['title'] = 'average object size' |
| 70 |
typeIndex['avgsize']['yaxis'] = 'Byte' |
| 71 |
typeIndex['avgsize']['base'] = '1024' |
| 72 |
typeIndex['avgsize']['scale'] = '--logarithmic --units=si' |
| 73 |
typeIndex['avgsize']['category'] = settings_graph_category |
| 74 |
|
| 75 |
typeIndex['storage'] = {}
|
| 76 |
typeIndex['storage']['index'] = 'storageSize' |
| 77 |
typeIndex['storage']['title'] = 'per collection storage size' |
| 78 |
typeIndex['storage']['yaxis'] = 'Byte' |
| 79 |
typeIndex['storage']['base'] = '1024' |
| 80 |
typeIndex['storage']['scale'] = '--logarithmic -l1 --units=si' |
| 81 |
typeIndex['storage']['category'] = settings_graph_category |
| 82 |
|
| 83 |
typeIndex['indexsize'] = {}
|
| 84 |
typeIndex['indexsize']['index'] = 'totalIndexSize' |
| 85 |
typeIndex['indexsize']['title'] = 'per collection index size' |
| 86 |
typeIndex['indexsize']['yaxis'] = 'Byte' |
| 87 |
typeIndex['indexsize']['base'] = '1024' |
| 88 |
typeIndex['indexsize']['scale'] = '--logarithmic -l 1 --units=si' |
| 89 |
typeIndex['indexsize']['category'] = settings_graph_category |
| 90 |
|
| 91 |
|
| 92 |
def getCollstats(graphtype): |
| 93 |
if settings_mongodb_uri: |
| 94 |
con = pymongo.MongoClient(settings_mongodb_uri) |
| 95 |
else: |
| 96 |
con = pymongo.MongoClient(settings_host, int(settings_port)) |
| 97 |
|
| 98 |
if settings_user: |
| 99 |
db = con[settings_db] |
| 100 |
db.authenticate(settings_user, settings_password) |
| 101 |
|
| 102 |
stats_tmp = {}
|
| 103 |
for dbname in con.list_database_names(): |
| 104 |
if dbname in settings_ignoredb: |
| 105 |
continue |
| 106 |
db = con[dbname] |
| 107 |
for coll in db.list_collection_names(): |
| 108 |
if coll.startswith('system.'):
|
| 109 |
continue |
| 110 |
stats = db.command("collstats", coll)
|
| 111 |
collname = dbname + "_" + coll.replace('.', '_')
|
| 112 |
if collname not in stats_tmp: |
| 113 |
stats_tmp[collname] = {}
|
| 114 |
stats_tmp[collname]['value'] = 0 |
| 115 |
stats_tmp[collname]['dbname'] = dbname |
| 116 |
if typeIndex[graphtype]['index'] in stats: |
| 117 |
stats_tmp[collname]['value'] += int(stats[typeIndex[graphtype]['index']]) |
| 118 |
|
| 119 |
con.close() |
| 120 |
|
| 121 |
for collname, item in sorted(stats_tmp.items()): |
| 122 |
yield ("%s" % collname, item['value'], item['dbname'])
|
| 123 |
|
| 124 |
|
| 125 |
def doData(base, graphtype): |
| 126 |
lastdb = "" |
| 127 |
for coll, stats, db in sorted(getCollstats(graphtype), key=itemgetter(2)): |
| 128 |
if lastdb != db: |
| 129 |
print("multigraph " + base + "_" + graphtype + "_" + db)
|
| 130 |
lastdb = db |
| 131 |
print("%s_%s.value %s" % (graphtype, coll, stats))
|
| 132 |
|
| 133 |
|
| 134 |
def doConfig(base, graphtype): |
| 135 |
|
| 136 |
lastdb = "" |
| 137 |
for k, v, d in sorted(getCollstats(graphtype), key=itemgetter(2)): |
| 138 |
if lastdb != d: |
| 139 |
print("multigraph " + base + "_" + graphtype + "_" + d)
|
| 140 |
lastdb = d |
| 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 %s" % settings_graph_category)
|
| 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 |
|
| 150 |
def doSuggest(): |
| 151 |
print("keys")
|
| 152 |
for k in typeIndex.keys(): |
| 153 |
print(k) |
| 154 |
|
| 155 |
|
| 156 |
if __name__ == "__main__": |
| 157 |
from sys import argv, exit |
| 158 |
from os import environ, path |
| 159 |
import re |
| 160 |
|
| 161 |
# Could be done by a for loop |
| 162 |
# but i think if's are faster |
| 163 |
if 'host' in environ: |
| 164 |
settings_host = environ['host'] |
| 165 |
if 'port' in environ: |
| 166 |
settings_port = environ['port'] |
| 167 |
if 'db' in environ: |
| 168 |
settings_db = environ['db'] |
| 169 |
if 'username' in environ: |
| 170 |
settings_user = environ['username'] |
| 171 |
if 'password' in environ: |
| 172 |
settings_password = environ['password'] |
| 173 |
if 'ignoredb' in environ: |
| 174 |
settings_ignoredb = environ['ignoredb'].split(',')
|
| 175 |
if 'MONGO_DB_URI' in environ: |
| 176 |
settings_mongodb_uri = environ['MONGO_DB_URI'] |
| 177 |
m = re.search('^(.*)_([a-zA-Z0-9]*)$', path.basename(argv[0]))
|
| 178 |
if len(argv) < 2: |
| 179 |
doData(m.group(1), m.group(2)) |
| 180 |
elif argv[1] == "config": |
| 181 |
doConfig(m.group(1), m.group(2)) |
| 182 |
elif argv[1] == "autoconf": |
| 183 |
print("yes")
|
| 184 |
elif argv[1] == "suggest": |
| 185 |
doSuggest() |
| 186 |
else: |
| 187 |
print("invalid argument")
|
| 188 |
exit(1) |
