Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

changes in mongodb-ganglia #1

Open
wants to merge 11 commits into from

1 participant

Benedikt Waldvogel
Benedikt Waldvogel

Hi Wil,

I've made a few little changes in your mongodb plugin for ganglia. They might be interesting for you…

Cheers,
Benedikt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 27, 2010
  1. removed trailing whitespaces

    Benedikt Waldvogel authored
  2. submit isMaster metric as integer (0 or 1)

    Benedikt Waldvogel authored
  3. added backgroundFlushes statistic

    Benedikt Waldvogel authored
  4. added lock queue metric for readers and writers

    Benedikt Waldvogel authored
Commits on Nov 12, 2010
  1. avoid negative op/s values

    Benedikt Waldvogel authored
Commits on Feb 23, 2012
  1. use pymongo (if available) to fetch and report database stats

    Benedikt Waldvogel authored
  2. gitignore

    Benedikt Waldvogel authored
  3. make use of 'with' statement

    Benedikt Waldvogel authored
  4. use file change date to determine the exact interval

    Benedikt Waldvogel authored
  5. add total stats without local db

    Benedikt Waldvogel authored
Commits on Feb 24, 2012
  1. use the right totalsNoLocals dict

    Benedikt Waldvogel authored
This page is out of date. Refresh to see the latest.
Showing with 107 additions and 27 deletions.
  1. +3 −0  .gitignore
  2. +104 −27 gmetric-mongodb.py
3  .gitignore
View
@@ -0,0 +1,3 @@
+.*.swp
+.project
+.pydevproject
131 gmetric-mongodb.py
View
@@ -1,33 +1,94 @@
#!/usr/bin/python
+# vim: set ts=4 sw=4 et :
from subprocess import Popen
-import sys, os, urllib2
+import sys, os, urllib2, time
try:
import json
except ImportError:
import simplejson as json
-GMETRIC = "/usr/bin/gmetric --name=\"%s\" --value=\"%s\" --type=\"int32\" --units=\"%s\""
+hasPyMongo = None
+try:
+ import pymongo
+ hasPyMongo = True
+except ImportError:
+ hasPyMongo = False
+
+GMETRIC = "/usr/bin/gmetric --name=\"%s\" --value=\"%s\" --type=\"%s\" --units=\"%s\""
class ServerStatus:
- ops_tmp_file = os.path.join("/", "tmp", "mongo-prevops")
+ ops_tmp_file = os.path.join("/", "tmp", "mongo-prevops")
def __init__(self):
self.status = self.getServerStatus()
# call individual metrics
- for f in ["conns", "btree", "mem", "repl", "ops", "lock"]:
- getattr(self,f)()
+ for f in ["conns", "btree", "mem", "backgroundFlushing", "repl", "ops", "lock"]:
+ getattr(self, f)()
+
+ if (hasPyMongo):
+ self.stats = self.getStats()
+ self.writeStats()
def getServerStatus(self):
- raw = urllib2.urlopen( "http://127.0.0.1:28017/_status" ).read()
- return json.loads( raw )["serverStatus"]
-
+ raw = urllib2.urlopen("http://localhost:28017/_status").read()
+ return json.loads(raw)["serverStatus"]
+
+ def getStats(self):
+ c = pymongo.Connection("localhost:27017", slave_okay=True)
+ stats = []
+
+ for dbName in c.database_names():
+ db = c[dbName]
+ dbStats = db.command("dbstats")
+ if dbStats["objects"] == 0:
+ continue
+ stats.append(dbStats)
+
+ c.disconnect()
+ return stats
+
+ def writeStats(self):
+ keys = { "numExtents":"extents", "objects":"objects",
+ "fileSize": "bytes", "dataSize": "bytes", "indexSize": "bytes", "storageSize": "bytes" }
+
+ totals = {}
+ totalsNoLocals = {}
+ for k in keys.keys():
+ totalsNoLocals[k] = 0
+ totals[k] = 0
+
+ for status in self.stats:
+ dbName = status["db"]
+
+ for k, v in keys.iteritems():
+ value = status[k]
+ self.callGmetric({dbName + "_" + k: (value, v)})
+ totals[k] += value
+ if (dbName != "local"):
+ totalsNoLocals[k] += value
+
+ for k, v in keys.iteritems():
+ self.callGmetric({"total_" + k: (totals[k], v)})
+ self.callGmetric({"totalNoLocal_" + k: (totalsNoLocals[k], v)})
+
+ self.callGmetric({"total_dataAndIndexSize" : (totals["dataSize"]+totals["indexSize"], "bytes")})
+ self.callGmetric({"totalNoLocal_dataAndIndexSize" : (totalsNoLocals["dataSize"]+totalsNoLocals["indexSize"], "bytes")})
+
def callGmetric(self, d):
- for k,v in d.iteritems():
- cmd = GMETRIC % ("mongodb_" + k, v[0], v[1])
+ for k, v in d.iteritems():
+ unit = None
+ if (isinstance(v[0], int)):
+ unit = "int32"
+ elif (isinstance(v[0], float)):
+ unit = "double"
+ else:
+ raise RuntimeError(str(v[0].__class__) + " unknown (key: " + k + ")")
+
+ cmd = GMETRIC % ("mongodb_" + k, v[0], unit, v[1])
Popen(cmd, shell=True)
-
+
def conns(self):
ss = self.status
self.callGmetric({
@@ -43,7 +104,7 @@ def btree(self):
"btree_resets" : (b["resets"], "count"),
"btree_miss_ratio" : (b["missRatio"], "ratio"),
})
-
+
def mem(self):
m = self.status["mem"]
self.callGmetric({
@@ -52,41 +113,57 @@ def mem(self):
"mem_mapped" : (m["mapped"], "MB"),
})
+ def backgroundFlushing(self):
+ f = self.status["backgroundFlushing"]
+ self.callGmetric({
+ "flush_average" : (f["average_ms"], "ms"),
+ })
+
def ops(self):
out = {}
cur_ops = self.status["opcounters"]
+
+ lastChange = None
try:
- f = open(self.ops_tmp_file, "r")
- content = f.read()
- prev_ops = json.loads(content)
- f.close()
+ os.stat_float_times(True)
+ lastChange = os.stat(self.ops_tmp_file).st_ctime
+ with open(self.ops_tmp_file, "r") as f:
+ content = f.read()
+ prev_ops = json.loads(content)
except (ValueError, IOError):
prev_ops = {}
-
- for k,v in cur_ops.iteritems():
+
+ for k, v in cur_ops.iteritems():
if k in prev_ops:
name = k + "s_per_second"
if k == "query":
name = "queries_per_second"
- out[name] = ((float(v) - float(prev_ops[k]) ) / 60, "ops/s")
- f = open(self.ops_tmp_file, 'w')
- try:
+ interval = time.time() - lastChange
+ if (interval <= 0.0):
+ continue
+ out[name] = (max(0, float(v) - float(prev_ops[k])) / interval, "ops/s")
+
+ with open(self.ops_tmp_file, 'w') as f:
f.write(json.dumps(cur_ops))
- finally:
- f.close()
self.callGmetric(out)
-
+
def repl(self):
+ ismaster = 0;
+ if (self.status["repl"]["ismaster"]):
+ ismaster = 1
+
self.callGmetric({
- "is_master" : (self.status["repl"]["ismaster"], "boolean")
+ "is_master" : (ismaster, "boolean")
})
def lock(self):
self.callGmetric({
- "lock_ratio" : (self.status["globalLock"]["ratio"], "ratio")
+ "lock_ratio" : (self.status["globalLock"]["ratio"], "ratio"),
+ "lock_queue_readers" : (self.status["globalLock"]["currentQueue"]["readers"], "queue size"),
+ "lock_queue_writers" : (self.status["globalLock"]["currentQueue"]["writers"], "queue size"),
})
-
+
if __name__ == "__main__":
ServerStatus()
Something went wrong with that request. Please try again.