示例#1
0
 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
示例#3
0
from statsmetrics import couchbase as couchbasemetrics

metrics = couchbasemetrics.get_metrics()
print(metrics)