diff --git a/plugins/keystone/keystone_stats b/plugins/keystone/keystone_stats new file mode 100755 index 00000000..9c52afbc --- /dev/null +++ b/plugins/keystone/keystone_stats @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# +# Plugin to monitor status of Keystone +# +# Needs following minimal configuration in plugin-conf.d/keystone: +# [keystone_*] +# user keystone +# +# Magic markers +#%# capabilities=autoconf +#%# family=keystone + +import sys + +from keystone.common import utils +from keystone import config +from keystone import exception +from keystone import identity + +CONF = config.CONF + +stats = ['users', 'tenants'] + + +def print_config(): + global states + print 'graph_title Keystone Stats' + print 'graph_vlabel count' + print 'graph_args --base 1000 --lower-limit 0' + print 'graph_category keystone' + print 'graph_scale no' + print 'graph_info This graph shows stats about keystone: ' + (', ').join(stats) + for field in stats: + print '%s_enabled.label enabled %s' % (field, field) + print '%s_enabled.draw LINE2' % field + print '%s_enabled.info %s enabled' % (field, field) + print '%s_total.label total %s' % (field, field) + print '%s_total.draw LINE2' % field + print '%s_total.info %s total' % (field, field) + + +def get_status(): + enabled = {} + total = {} + for k in stats: + enabled[k] = 0 + total[k] = 0 + + identity_api = identity.Manager() + + for user in identity_api.list_users(None): + total['users'] += 1 + if user['enabled']: + enabled['users'] += 1 + + # Ldap and pam driver don't support get_all_tenants() + # kvs and sql implement get_tenants() instead of get_all_tenants() + # Whoo: None of backend implements the correct function + tenants = [] + for api_func in [ 'get_all_tenants', 'get_tenants']: + try: + tenants = getattr(identity_api, api_func)(None) + except exception.NotImplemented, NotImplementedError: + pass + + + for tenant in tenants: + total['tenants'] += 1 + if tenant['enabled']: + enabled['tenants'] += 1 + + return {'enabled': enabled, 'total': total} + + +def print_values(): + stats = get_status() + for state in stats.keys(): + for (field, value) in stats[state].iteritems(): + print "%s_%s.value %s" % (field, state, value) + + +if __name__ == '__main__': + if len(sys.argv) > 1: + if sys.argv[1] == "config": + print_config() + elif sys.argv[1] == "autoconf": + print "yes" + else: + CONF(config_files=[utils.find_config('keystone.conf')]) + print_values() + diff --git a/plugins/nova/nova_floating_ips b/plugins/nova/nova_floating_ips new file mode 100755 index 00000000..392bfc57 --- /dev/null +++ b/plugins/nova/nova_floating_ips @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# +# Plugin to monitor status of Floating IPs in Nova +# +# To monitor a floating ips, link floating_ips to this file. +# E.g. +# ln -s /usr/share/munin/plugins/nova_floating_ips /etc/munin/plugins/ +# +# Needs following minimal configuration in plugin-conf.d/nova: +# [nova_*] +# user nova +# +# Magic markers +#%# capabilities=autoconf +#%# family=nova + +from nova import context +from nova import db +from nova import flags +from nova import utils +import sys + +states = ['total', 'allocated', 'associated'] + + +def print_config(): + global states + print 'graph_title Nova Floating IPs' + print 'graph_vlabel %' + print 'graph_args --base 1000 --lower-limit 0' + print 'graph_category nova' + print 'graph_scale no' + print 'graph_info This graph shows the number of Floating IPs in Nova and their status' + for state in states: + print '%s.label %s' % (state, state) + print '%s.draw LINE2' % state + print '%s.info %s IPs' % (state, state) + + +def get_status(): + status = {} + for k in states: + status[k] = 0 + + ctxt = context.get_admin_context() + floating_ips = db.floating_ip_get_all(ctxt) + for floating_ip in floating_ips: + status['total'] += 1 + if floating_ip['fixed_ip_id']: + status['associated'] += 1 + if floating_ip['project_id']: + status['allocated'] += 1 + + return status + + +def print_values(): + status = get_status() + for (state, value) in status.iteritems(): + print "%s.value %s" % (state, value) + + +if __name__ == '__main__': + if len(sys.argv) > 1: + if sys.argv[1] == "config": + print_config() + elif sys.argv[1] == "autoconf": + print "yes" + else: + utils.default_flagfile() + flags.FLAGS(sys.argv) + print_values() diff --git a/plugins/nova/nova_instance_ b/plugins/nova/nova_instance_ new file mode 100755 index 00000000..d990ebd0 --- /dev/null +++ b/plugins/nova/nova_instance_ @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# +# Plugin to monitor status of Floating IPs in Nova +# +# To monitor instance states, link instance_states to this file. +# E.g. +# ln -s /usr/share/munin/plugins/nova_instance_states /etc/munin/plugins/ +# +# Needs following minimal configuration in plugin-conf.d/nova: +# [nova_*] +# user nova +# +# Magic markers +#%# capabilities=autoconf +#%# family=nova + +from nova import context +from nova import db +from nova import flags +from nova import utils +import sys + + +class InstanceState(object): + instance_counts = None + states = None + + @classmethod + def init(cls, metric): + if cls.states and cls.instance_counts: + return + ctxt = context.get_admin_context() + instances = db.instance_get_all(ctxt) + cls.instance_counts = {} + instance_types = {} + for it in db.instance_type_get_all(ctxt, True).values(): + instance_types[it['id']] = it['name'] + + if metric == 'state': + metric = 'state_description' + + for instance in instances: + i = dict(instance) + i['instance_type'] = i['type'] = instance_types.get( + instance.instance_type_id, + '(unknown') + val = cls.instance_counts.get(i[metric], 0) + cls.instance_counts[i[metric]] = val + 1 + cls.states = cls.instance_counts.keys() + + @classmethod + def get_states(cls, metric): + InstanceState.init(metric) + return cls.states + + @classmethod + def get_instance_counts(cls, metric): + InstanceState.init(metric) + return cls.instance_counts + + +def print_config(metric): + states = InstanceState.get_states(metric) + print 'graph_title Nova Instance States' + print 'graph_vlabel instances' + print 'graph_args --base 1000 --lower-limit 0' + print 'graph_category nova' + print 'graph_scale no' + print 'graph_info This graph shows the number of instances by state' + for state in states: + print '%s.label %s' % (state, state) + print '%s.draw LINE2' % state + print '%s.info %s IPs' % (state, state) + + +def print_values(metric): + status = InstanceState.get_instance_counts(metric) + for (state, value) in status.iteritems(): + print '%s.value %s' % (state, value) + + +if __name__ == '__main__': + argv = sys.argv[:] + utils.default_flagfile() + flags.FLAGS(sys.argv) + metric = argv[0].split('nova_instance_').pop() or 'state' + + if len(argv) > 1: + if argv[1] == 'config': + print_config(metric) + elif argv[1] == 'autoconf': + print 'yes' + else: + print_values(metric) diff --git a/plugins/nova/nova_instance_launched b/plugins/nova/nova_instance_launched new file mode 100755 index 00000000..943b46d6 --- /dev/null +++ b/plugins/nova/nova_instance_launched @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# +# Plugin to monitor instances launched from beginning of time +# +# To monitor a floating ips, link floating_ips to this file. +# E.g. +# ln -s /usr/share/munin/plugins/nova_instance_launched /etc/munin/plugins/ +# +# Needs following minimal configuration in plugin-conf.d/nova: +# [nova_*] +# user nova +# +# Magic markers +#%# capabilities=autoconf +#%# family=nova + +from nova import context +from nova import db +from nova import flags +from nova import utils +from nova.db.sqlalchemy.session import get_session +import sys + +def print_config(): + global states + print 'graph_title Nova Instances Launched' + print 'graph_vlabel qty' + print 'graph_args --base 1000 --lower-limit 0' + print 'graph_category nova' + print 'graph_scale no' + print 'graph_info This graph shows the number of instances launched since the beginning of time' + print 'instances.label instances' + print 'instances.draw LINE2' + +def get_status(): + connection = get_session().connection() + row = connection.execute("select count(*) from instances").fetchall()[0] + return row[0] + +def print_values(): + qty = get_status() + print "instances.value %s" % qty + +if __name__ == '__main__': + if len(sys.argv) > 1: + if sys.argv[1] == "config": + print_config() + elif sys.argv[1]=="autoconf" : + print "yes" + else: + utils.default_flagfile() + flags.FLAGS(sys.argv) + print_values() diff --git a/plugins/nova/nova_instance_timing b/plugins/nova/nova_instance_timing new file mode 100755 index 00000000..3794e2f9 --- /dev/null +++ b/plugins/nova/nova_instance_timing @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# +# Plugin to monitor trending of launch/schedule times for last 5 successful instances +# +# To monitor a floating ips, link floating_ips to this file. +# E.g. +# ln -s /usr/share/munin/plugins/nova_instance_timing /etc/munin/plugins/ +# +# Needs following minimal configuration in plugin-conf.d/nova: +# [nova_*] +# user nova +# +# Magic markers +#%# capabilities=autoconf +#%# family=nova + +from nova import context +from nova import db +from nova import flags +from nova import utils +from nova.db.sqlalchemy.session import get_session +import sys + + +def print_config(): + global states + print 'graph_title Nova Launch Times' + print 'graph_vlabel seconds' + print 'graph_args --base 1000 --lower-limit 0' + print 'graph_category nova' + print 'graph_scale no' + print 'graph_info This the average time for the last 5 schedulings/launchings' + print 'schedule.label schedule time' + print 'schedule.draw LINE2' + print 'schedule.info average time for last 5 instance to be scheduled' + print 'launch.label launch time' + print 'launch.draw LINE2' + print 'launch.info average time for last 5 instance to be launched after scheduling' + + +def get_status(): + connection = get_session().connection() + row = connection.execute("select AVG(TIME_TO_SEC(TIMEDIFF(scheduled_at, created_at))) from instances where scheduled_at is not null order by scheduled_at desc limit 5;").fetchall()[0] + schedule = row[0] + row = connection.execute("select AVG(TIME_TO_SEC(TIMEDIFF(launched_at, scheduled_at))) from instances where launched_at is not null order by launched_at desc limit 5;").fetchall()[0] + launch = row[0] + return (schedule, launch) + + +def print_values(): + schedule, launch = get_status() + print "schedule.value %s" % schedule + print "launch.value %s" % launch + + +if __name__ == '__main__': + if len(sys.argv) > 1: + if sys.argv[1] == "config": + print_config() + elif sys.argv[1] == "autoconf": + print "yes" + else: + utils.default_flagfile() + flags.FLAGS(sys.argv) + print_values() diff --git a/plugins/nova/nova_services b/plugins/nova/nova_services new file mode 100755 index 00000000..7bbbfbaf --- /dev/null +++ b/plugins/nova/nova_services @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# +# Plugin to report service status +# +# Needs following minimal configuration in plugin-conf.d/nova: +# [nova_*] +# user nova +# +# Magic markers +#%# capabilities=autoconf +#%# family=nova + +from nova import context +from nova import db +from nova import flags +from nova import utils +import sys + +services = ['nova-compute', 'nova-volume', 'nova-scheduler', 'nova-vncproxy', 'nova-network', 'nova-cert', 'nova-console', 'nova-consoleauth'] + + +def print_config(): + global services + print 'graph_title Nova Services' + print 'graph_vlabel qty' + print 'graph_args --base 1000 --lower-limit 0' + print 'graph_category nova' + print 'graph_scale no' + print 'graph_info Nova services - alive and active' + for service in services: + print '%s_alive.label %s alive' % (service, service) + print '%s_alive.draw LINE2' % service + print '%s_alive.info seen in last 30 seconds' % service + print '%s_active.label %s active' % (service, service) + print '%s_active.draw LINE2' % service + print '%s_active.info alive and enabled' % service + + +def get_status(): + global services + alive = {} + active = {} + for k in services: + alive[k] = 0 + active[k] = 0 + + ctxt = context.get_admin_context() + now = utils.utcnow() + services = db.service_get_all(ctxt) + for svc in services: + delta = now - (svc['updated_at'] or svc['created_at']) + if (delta.seconds <= 30): + alive[svc['binary']] += 1 + if not svc['disabled']: + active[svc['binary']] += 1 + + return {'alive': alive, 'active': active} + + +def print_values(): + status = get_status() + for (state, value) in status['alive'].iteritems(): + print "%s_alive.value %s" % (state, value) + for (state, value) in status['active'].iteritems(): + print "%s_active.value %s" % (state, value) + + +if __name__ == '__main__': + if len(sys.argv) > 1: + if sys.argv[1] == "config": + print_config() + elif sys.argv[1] == "autoconf": + print "yes" + else: + utils.default_flagfile() + flags.FLAGS(sys.argv) + print_values()