#!/usr/bin/env python # -*- coding: utf-8 -*- # vim: set fileencoding=utf-8 # # Munin plugin to show Mysql COUNT(*) results for multiple values # # Copyright Igor Borodikhin # # License : GPLv3 # # parsed environment variables: # host: hostname or ip-address of Mysql server (default - localhost) # port: port number of Mysql server (default - 3306) # user: username to access Mysql server (default - empty) # password: password of Mysql user (default - empty) # database: Mysql database name (default - empty) # table: Mysql table name (no default, raises exception) # field: field name, used in GROUP BY statement (default - empty, no group by) # where: optional where condition (without "where", default - empty) # only: optional; "max" or "min" to indicate that only the largest or smallest value should be graphed # # This plugin shows graphs of Mysql COUNT(*) results. # # ## Requirements # This plugin requires pythons MySQLdb module which can be installed via easy_install. # # ## Installation # Copy file to directory /usr/share/munin/pligins/ and create symbolic links for each table you wish to monitor. # For example, if you wish to monitor how many users Mysql has per host create this symlink: # # ln -s /usr/share/munin/plugins/mysql_aggregate_ /etc/munin/plugins/mysql_aggregate_user # # And specify some options in munin-node.conf: # # [mysql_aggregate_*] # env.host 10.216.0.141 # env.port 3306 # env.user root # env.password vErYsEcReT # env.database mysql # env.table user # env.field Host # env.label Mysql users # env.vlabel users # #%# capabilities=autoconf #%# family=contrib import os, sys, MySQLdb, MySQLdb.cursors progName = sys.argv[0] # Parse environment variables # Mysql host if "host" in os.environ and os.environ["host"] != None: server = os.environ["host"] else: server = "localhost" # Mysql port if "port" in os.environ and os.environ["port"] != None: try: port = int(os.environ["port"]) except ValueError: port = 3306 else: port = 3306 # Mysql username if "user" in os.environ and os.environ["user"] != None: login = os.environ["user"] else: login = "" # Mysql password if "password" in os.environ and os.environ["password"] != None: passw = os.environ["password"] else: passw = "" # Mysql database if "database" in os.environ and os.environ["database"] != None: db = os.environ["database"] else: db = "" # Mysql table name if "table" in os.environ and os.environ["table"] != None: table = os.environ["table"] else: raise Exception("You should provide 'env.table' in configuration file") # Mysql group by field if "field" in os.environ and os.environ["field"] != None: groupBy = "GROUP BY %s" % os.environ["field"] field = "%s, " % os.environ["field"] else: groupBy = "" field = "" if "only" in os.environ and os.environ["only"] != None: if not field: raise Exception("You should provide 'env.field' in configuration file") only = os.environ["only"] if only == "max": dir = "DESC" elif only == "min": dir = "ASC" else: raise Exception("env.only should be 'max' or 'min'; found %s") % (only, ) order_by = "ORDER BY COUNT(*) %s LIMIT 1" % (dir, ) else: order_by = "" # Mysql where condition if "where" in os.environ and os.environ["where"] != None: where = "WHERE %s" % os.environ["where"] else: where = "" # Mysql connection handler conn = None # Query to get field values (used only when graphing several values) valuesQuery = "SELECT DISTINCT %s 1 FROM %s %s" % (field, table, where) # Query to get graph data aggregateQuery = "SELECT %sCOUNT(*) FROM %s %s %s %s" % (field, table, where, groupBy, order_by) # Connect to mysql try: conn = MySQLdb.connect(host=server, user=login, passwd=passw, db=db) cursor = conn.cursor() except MySQLdb.Error, e: print "Error %d: %s" % (e.args[0], e.args[1]) sys.exit(1) single_value = field == "" or order_by != "" # init values tuple if not single_value: values = {} cursor.execute(valuesQuery) results = cursor.fetchall() for result in results: values[result[0]] = 0 if len(sys.argv) == 2 and sys.argv[1] == "autoconf": print "yes" elif len(sys.argv) == 2 and sys.argv[1] == "config": if "label" in os.environ: label = os.environ["label"] else: label = "Aggregate - %s" % table if "vlabel" in os.environ: vlabel = os.environ["vlabel"] else: vlabel = "count(*)" if single_value: print "graph mysql_aggregate_%s" % table print "graph_title %s" % label print "graph_vlabel %s" % vlabel print "graph_category db" print "" if "only" in os.environ: print "values_count.label %s" % (os.environ["only"], ) else: print "values_count.label count" else: print "multigraph mysql_aggregate_%s" % table print "graph_title %s" % label print "graph_vlabel %s" % vlabel print "graph_category db" print "" for key in values.keys(): print "%s_count.label %s" % (key.replace(".", "_"), key.replace(".", "_")) for key in values.keys(): print "" print "multigraph mysql_aggregate_%s.%s" % (table, key.replace(".", "_")) print "graph_title %s, value %s" % (label, key.replace(".", "_")) print "graph_vlabel %s" % vlabel print "graph_category db" print "" print "%s_count.label %s" % (key.replace(".", "_"), key) print "" else: try: cursor.execute(aggregateQuery) if single_value: result = cursor.fetchone() count = 0 if field: ind = 1 else: ind = 0 if result[ind]: count = count + result[ind] print "values_count.value %s" % count else: results = cursor.fetchall() for result in results: values[result[0]] = result[1] print "multigraph mysql_aggregate_%s" % table for key in values.keys(): print "%s_count.value %s" % (key.replace(".", "_"), values[key]) for key in values.keys(): print "" print "multigraph mysql_aggregate_%s.%s" % (table, key.replace(".", "_")) print "%s_count.value %s" % (key.replace(".", "_"), values[key]) except MySQLdb.Error, e: print "Error %d: %s" % (e.args[0], e.args[1]) if conn: conn.close()