root / plugins / mongodb / mongo_collection_ @ 4387edfa
Historique | Voir | Annoter | Télécharger (6,66 ko)
| 1 | 276169a6 | Alban | #!/usr/bin/env python3 |
|---|---|---|---|
| 2 | 22621b6a | Foxlik | # -*- 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 | 276169a6 | Alban | # #%# family=auto |
| 33 | # #%# capabilities=suggest autoconf |
||
| 34 | 22621b6a | Foxlik | |
| 35 | |||
| 36 | 887063d5 | Nico Casar Gonzalez | import pymongo |
| 37 | 22621b6a | Foxlik | from operator import itemgetter |
| 38 | |||
| 39 | settings_host = '127.0.0.1' |
||
| 40 | settings_port = 27017 |
||
| 41 | 9121b90e | Nico Casar Gonzalez | # mongodb_uri will override host and port |
| 42 | settings_mongodb_uri = '' |
||
| 43 | 276169a6 | Alban | settings_db = 'admin' |
| 44 | 22621b6a | Foxlik | 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 | 99542938 | dipohl | typeIndex['collcount']['category'] = 'db' |
| 56 | 22621b6a | Foxlik | |
| 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 | 99542938 | dipohl | typeIndex['collsize']['category'] = 'db' |
| 64 | 22621b6a | Foxlik | |
| 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 | 99542938 | dipohl | typeIndex['avgsize']['category'] = 'db' |
| 72 | 22621b6a | Foxlik | |
| 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 | 99542938 | dipohl | typeIndex['storage']['category'] = 'db' |
| 80 | 22621b6a | Foxlik | |
| 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 | 99542938 | dipohl | typeIndex['indexsize']['category'] = 'db' |
| 88 | 22621b6a | Foxlik | |
| 89 | |||
| 90 | def getCollstats(graphtype): |
||
| 91 | 276169a6 | Alban | 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[settings_db] |
||
| 98 | db.authenticate(settings_user, settings_password) |
||
| 99 | |||
| 100 | stats_tmp = {}
|
||
| 101 | for dbname in con.list_database_names(): |
||
| 102 | if dbname in settings_ignoredb: |
||
| 103 | continue |
||
| 104 | db = con[dbname] |
||
| 105 | for coll in db.list_collection_names(): |
||
| 106 | if coll.startswith('system.'):
|
||
| 107 | continue |
||
| 108 | stats = db.command("collstats", coll)
|
||
| 109 | collname = dbname + "_" + coll.replace('.', '_')
|
||
| 110 | if collname not in stats_tmp: |
||
| 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'] += int(stats[typeIndex[graphtype]['index']]) |
||
| 116 | |||
| 117 | con.close() |
||
| 118 | |||
| 119 | for collname, item in sorted(stats_tmp.items()): |
||
| 120 | yield ("%s" % collname, item['value'], item['dbname'])
|
||
| 121 | |||
| 122 | |||
| 123 | def doData(base, graphtype): |
||
| 124 | 22621b6a | Foxlik | lastdb = "" |
| 125 | for coll, stats, db in sorted(getCollstats(graphtype), key=itemgetter(2)): |
||
| 126 | if lastdb != db: |
||
| 127 | 276169a6 | Alban | print("multigraph " + base + "_" + graphtype + "_" + db)
|
| 128 | 22621b6a | Foxlik | lastdb = db |
| 129 | 276169a6 | Alban | print("%s_%s.value %s" % (graphtype, coll, stats))
|
| 130 | 22621b6a | Foxlik | |
| 131 | |||
| 132 | 276169a6 | Alban | def doConfig(base, graphtype): |
| 133 | 22621b6a | Foxlik | |
| 134 | lastdb = "" |
||
| 135 | 276169a6 | Alban | for k, v, d in sorted(getCollstats(graphtype), key=itemgetter(2)): |
| 136 | 22621b6a | Foxlik | if lastdb != d: |
| 137 | 276169a6 | Alban | print("multigraph " + base + "_" + graphtype + "_" + d)
|
| 138 | 22621b6a | Foxlik | lastdb = d |
| 139 | 276169a6 | Alban | print("graph_title MongoDB " + typeIndex[graphtype]['title'] + " for database " + d)
|
| 140 | print("graph_args --base " + typeIndex[graphtype]['base'] + " " + typeIndex[graphtype]['scale'])
|
||
| 141 | print("graph_vlabel " + typeIndex[graphtype]['yaxis'])
|
||
| 142 | print("graph_category db")
|
||
| 143 | print("%s_%s.label %s" % (graphtype, k, k))
|
||
| 144 | print("%s_%s.min 0" % (graphtype, k))
|
||
| 145 | print("%s_%s.draw LINE1" % (graphtype, k))
|
||
| 146 | |||
| 147 | 22621b6a | Foxlik | |
| 148 | def doSuggest(): |
||
| 149 | 276169a6 | Alban | print("keys")
|
| 150 | for k in typeIndex.keys(): |
||
| 151 | print(k) |
||
| 152 | 22621b6a | Foxlik | |
| 153 | |||
| 154 | if __name__ == "__main__": |
||
| 155 | 276169a6 | Alban | from sys import argv, exit |
| 156 | from os import environ, path |
||
| 157 | 22621b6a | Foxlik | import re |
| 158 | |||
| 159 | # Could be done by a for loop |
||
| 160 | # but i think if's are faster |
||
| 161 | 276169a6 | Alban | if 'host' in environ: |
| 162 | settings_host = environ['host'] |
||
| 163 | if 'port' in environ: |
||
| 164 | settings_port = environ['port'] |
||
| 165 | if 'db' in environ: |
||
| 166 | settings_db = environ['db'] |
||
| 167 | if 'username' in environ: |
||
| 168 | settings_user = environ['username'] |
||
| 169 | if 'password' in environ: |
||
| 170 | settings_password = environ['password'] |
||
| 171 | if 'ignoredb' in environ: |
||
| 172 | settings_ignoredb = environ['ignoredb'].split(',')
|
||
| 173 | 22621b6a | Foxlik | m = re.search('^(.*)_([a-zA-Z0-9]*)$', path.basename(argv[0]))
|
| 174 | if len(argv) < 2: |
||
| 175 | 276169a6 | Alban | doData(m.group(1), m.group(2)) |
| 176 | 22621b6a | Foxlik | elif argv[1] == "config": |
| 177 | 276169a6 | Alban | doConfig(m.group(1), m.group(2)) |
| 178 | 22621b6a | Foxlik | elif argv[1] == "autoconf": |
| 179 | 276169a6 | Alban | print("yes")
|
| 180 | 22621b6a | Foxlik | elif argv[1] == "suggest": |
| 181 | doSuggest() |
||
| 182 | else: |
||
| 183 | 276169a6 | Alban | print("invalid argument")
|
| 184 | 22621b6a | Foxlik | exit(1) |
