def _get_metrics(self): self.metrics = [] for key,values in couchbasemetrics.get_metrics().items(): for metric in values['metrics']: obj = { 'type': key, 'label': metric['id'], 'suffix': metric['suffix'] } self.metrics.append(obj) if 'bucket_stats' in values: for metric in values['bucket_stats']: obj = { 'type': 'bucket_stats', 'label': metric['id'], 'suffix': metric['suffix'] } self.metrics.append(obj)
class CouchbaseCollector(object): METRIC_PREFIX = 'couchbase_' metrics = couchbase_metrics.get_metrics() gauges = {} def __init__(self, target): self.BASE_URL = target.rstrip("/") """ Split dots in metric name and search for it in obj dict """ def _dot_get(self, metric, obj): try: return reduce(getitem, metric.split('.'), obj) except Exception as e: return False """ Request data via CURL with or without authentication. Auth username and password can be defined as environment variables :rtype JSON """ def _request_data(self, url): try: if set(["COUCHBASE_USERNAME", "COUCHBASE_PASSWORD"]).issubset(os.environ): response = requests.get(url, auth=HTTPBasicAuth(os.environ["COUCHBASE_USERNAME"], os.environ["COUCHBASE_PASSWORD"])) else: response = requests.get(url) except Exception as e: print('Failed to establish a new connection. Is {0} correct?'.format(self.BASE_URL)) sys.exit(1) if response.status_code != requests.codes.ok: print('Response Status ({0}): {1}'.format(response.status_code, response.text)) response.raise_for_status() result = response.json() return result """ Add metrics in GaugeMetricFamily format """ def _add_metrics(self, metrics, metric_name, metric_gauges, data): metric_id = re.sub('(\.)', '_', metrics['id']).lower() metric_value = self._dot_get(metrics['id'], data) gauges = [metric_id] for gauge in metric_gauges: gauges.append(gauge) if metric_value is not False: if isinstance(metric_value, list): metric_value = sum(metric_value) / float(len(metric_value)) if metric_id not in self.gauges: self.gauges[metric_id] = GaugeMetricFamily('%s_%s' % (metric_name, metric_id), '%s' % metric_id, value=None, labels=metrics['labels']) self.gauges[metric_id].add_metric(gauges, value=metric_value) """ Collect cluster, nodes, bucket and bucket details metrics """ def _collect_metrics(self, key, values, couchbase_data): if key == 'cluster': for metrics in values['metrics']: self._add_metrics(metrics, self.METRIC_PREFIX + 'cluster', [], couchbase_data) elif key == 'nodes': for node in couchbase_data['nodes']: for metrics in values['metrics']: self._add_metrics(metrics, self.METRIC_PREFIX + 'node', [node['hostname']], node) elif key == 'buckets': for bucket in couchbase_data: for metrics in values['metrics']: self._add_metrics(metrics, self.METRIC_PREFIX + 'bucket', [bucket['name']], bucket) # Get detailed stats for each bucket bucket_stats = self._request_data(self.BASE_URL + bucket['stats']['uri']) for bucket_metrics in values['bucket_stats']: self._add_metrics(bucket_metrics, self.METRIC_PREFIX + 'bucket_stats', [bucket['name']], bucket_stats["op"]["samples"]) def _clear_gauges(self): self.gauges = {} """ Collect each metric defined in external module statsmetrics """ def collect(self): self._clear_gauges() for api_key, api_values in self.metrics.items(): # Request data for each url couchbase_data = self._request_data(self.BASE_URL + api_values['url']) self._collect_metrics(api_key, api_values, couchbase_data) for gauge_name, gauge in self.gauges.items(): yield gauge
from statsmetrics import couchbase as couchbasemetrics metrics = couchbasemetrics.get_metrics() print(metrics)