Filippo Giunchedi has uploaded a new change for review.
https://gerrit.wikimedia.org/r/299539
Change subject: puppetmaster: generate prometheus targets from ganglia
......................................................................
puppetmaster: generate prometheus targets from ganglia
Similarly to other 'exported resources generators', query MySQL for puppet data
and output prometheus configuration.
Bug: T126785
Change-Id: I91b97371d7054242373e91ec225cefad07756140
---
A modules/puppetmaster/files/prometheus-ganglia-gen
1 file changed, 145 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/operations/puppet
refs/changes/39/299539/1
diff --git a/modules/puppetmaster/files/prometheus-ganglia-gen
b/modules/puppetmaster/files/prometheus-ganglia-gen
new file mode 100755
index 0000000..b0a7ad8
--- /dev/null
+++ b/modules/puppetmaster/files/prometheus-ganglia-gen
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+# Generate prometheus targets to be polled, based on puppet's exported
+# resource Ganglia::Cluster.
+
+
+import argparse
+import logging
+import re
+import sys
+import yaml
+
+from collections import defaultdict
+from logging.handlers import SysLogHandler
+
+# python 3 compatibility
+try:
+ import ConfigParser as configparser
+except ImportError:
+ import configparser
+
+import sqlalchemy
+
+
+# placeholder object for attributes
+class Host(object):
+ pass
+
+
+class PrometheusClusterGen(object):
+ query = """
+SELECT resources.title as title,
+ GROUP_CONCAT(CONCAT(param_names.name, "\t", param_values.value)
+ SEPARATOR "\n") AS service_content
+FROM param_values
+ JOIN param_names ON param_names.id = param_values.param_name_id
+ JOIN resources ON param_values.resource_id = resources.id
+WHERE restype = 'Ganglia::Cluster'
+GROUP BY resources.id ORDER BY resources.title ASC"""
+
+ def load_config(self, configfile):
+ self.config = configparser.SafeConfigParser()
+ self.config.read(configfile)
+ self.dsn = "{}://{}:{}@{}:3306/puppet".format(
+ self.config.get('master', 'dbadapter'),
+ self.config.get('master', 'dbuser'),
+ self.config.get('master', 'dbpassword'),
+ self.config.get('master', 'dbserver')
+ )
+
+ def __init__(self, configfile, debug):
+ self.log = logging.getLogger('prometheus-ganglia-gen')
+ self.log.debug('Loading configfile %s', configfile)
+ self.load_config(configfile)
+ self.db_engine = sqlalchemy.create_engine(
+ self.dsn,
+ echo=debug
+ )
+
+ def _query(self):
+ connection = self.db_engine.connect()
+ connection.execute('set group_concat_max_len = @@max_allowed_packet')
+ res = connection.execute(self.query)
+ connection.close()
+ return res
+
+ def _hosts(self):
+ try:
+ for entity in self._query():
+ attrs = defaultdict(list)
+ for restuple in entity['service_content'].split("\n"):
+ (k, v) = restuple.split("\t")
+ attrs[k].append(v)
+
+ h = Host()
+ h.fqdn = entity['title']
+ h.name = h.fqdn.split('.')[0]
+ h.cluster = attrs['cluster'][0]
+ h.site = attrs['site'][0]
+ yield h
+ except Exception as e:
+ self.log.exception(
+ 'Could not generate output for resource Ganglia::Cluster')
+ sys.exit(30)
+
+ def site_targets(self, sites, filter_hostnames=None,
target_suffix=':9100'):
+ if filter_hostnames is None:
+ filter_hostnames = []
+
+ all_clusters = defaultdict(list)
+ for host in self._hosts():
+ if sites and host.site not in sites:
+ continue
+ if filter_hostnames:
+ if not any([re.match(x, host.name) for x in filter_hostnames]):
+ continue
+ cluster_id = (host.cluster, host.site)
+ all_clusters[cluster_id].append(host)
+
+ targets = []
+ for cluster_id, hosts in all_clusters.iteritems():
+ target = {}
+ cluster_name, cluster_site = cluster_id
+ target['labels'] = {'cluster': cluster_name}
+ if not sites:
+ target['labels'].update({'site': cluster_site})
+ target['targets'] = ["".join((x.name, target_suffix)) for x in
hosts]
+ targets.append(target)
+
+ return targets
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--configfile', '-c', dest='configfile',
+ default='/etc/puppet/puppet.conf')
+ parser.add_argument('--site', dest='sites', metavar='SITE', nargs='+')
+ parser.add_argument('--filter-hostname', dest='filter_hostnames',
+ metavar='REGEXP', nargs='+')
+ parser.add_argument('--debug', action='store_true', default=False)
+ args = parser.parse_args()
+
+ log_format='%(name)s: %(levelname)s - %(message)s'
+ log = logging.getLogger('prometheus-ganglia-gen')
+
+ logging.basicConfig(level=logging.DEBUG, format=log_format,
stream=sys.stderr)
+
+ if not args.debug:
+ log.setLevel(logging.INFO)
+ log.propagate = False
+ handler = SysLogHandler(
+ address='/dev/log',
+ facility=SysLogHandler.LOG_LOCAL3)
+ formatter = logging.Formatter(fmt=log_format)
+ handler.setFormatter(formatter)
+ log.addHandler(handler)
+
+ log.info('Generating prometheus cluster targets for sites %r' % args.sites)
+ clustergen = PrometheusClusterGen(args.configfile, args.debug)
+ print yaml.dump(clustergen.site_targets(args.sites, args.filter_hostnames),
+ default_flow_style=False)
+ log.info('Run completed')
+
+
+if __name__ == '__main__':
+ main()
--
To view, visit https://gerrit.wikimedia.org/r/299539
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I91b97371d7054242373e91ec225cefad07756140
Gerrit-PatchSet: 1
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Filippo Giunchedi <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits