/ cabot / cabotapp / graphite.py
graphite.py
  1  from django.conf import settings
  2  import requests
  3  import logging
  4  import time
  5  
  6  graphite_api = settings.GRAPHITE_API
  7  user = settings.GRAPHITE_USER
  8  password = settings.GRAPHITE_PASS
  9  graphite_from = settings.GRAPHITE_FROM
 10  auth = (user, password)
 11  
 12  
 13  def get_data(target_pattern, mins_to_check=None):
 14  
 15      if mins_to_check:
 16          _from = '-%dminute' % mins_to_check
 17      else:
 18          _from = graphite_from
 19  
 20      resp = requests.get(
 21          graphite_api + 'render', auth=auth,
 22          params={
 23              'target': target_pattern,
 24              'format': 'json',
 25              'from': _from,
 26          }
 27      )
 28      resp.raise_for_status()
 29      return resp.json()
 30  
 31  
 32  def get_matching_metrics(pattern):
 33      print 'Getting metrics matching %s' % pattern
 34      resp = requests.get(
 35          graphite_api + 'metrics/find/', auth=auth,
 36          params={
 37              'query': pattern,
 38              'format': 'completer'
 39          },
 40          headers={
 41              'accept': 'application/json'
 42          }
 43      )
 44      resp.raise_for_status()
 45      return resp.json()
 46  
 47  
 48  def get_all_metrics(limit=None):
 49      """Grabs all metrics by navigating find API recursively"""
 50      metrics = []
 51  
 52      def get_leafs_of_node(nodepath):
 53          for obj in get_matching_metrics(nodepath)['metrics']:
 54              if int(obj['is_leaf']) == 1:
 55                  metrics.append(obj['path'])
 56              else:
 57                  get_leafs_of_node(obj['path'])
 58      get_leafs_of_node('')
 59      return metrics
 60  
 61  
 62  def parse_metric(metric, mins_to_check=5, utcnow=None):
 63      if utcnow is None:
 64          utcnow = time.time()
 65      ret = {
 66          'num_series_with_data': 0,
 67          'num_series_no_data': 0,
 68          'error': None,
 69          'raw': '',
 70          'series': [],
 71      }
 72      try:
 73          data = get_data(metric, mins_to_check)
 74      except requests.exceptions.RequestException, e:
 75          ret['error'] = 'Error getting data from Graphite: %s' % e
 76          ret['raw'] = ret['error']
 77          logging.error('Error getting data from Graphite: %s' % e)
 78          return ret
 79      all_values = []
 80      for target in data:
 81          series = {'values': [
 82              float(t[0]) for t in target['datapoints'] if validate_datapoint(t, mins_to_check, utcnow)]}
 83          series["target"] = target["target"]
 84          all_values.extend(series['values'])
 85          if series['values']:
 86              ret['num_series_with_data'] += 1
 87              series['max'] = max(series['values'])
 88              series['min'] = min(series['values'])
 89              series['average_value'] = sum(series['values']) / len(series['values'])
 90              ret['series'].append(series)
 91          else:
 92              ret['num_series_no_data'] += 1
 93      if all_values:
 94          ret['average_value'] = sum(all_values) / len(all_values)
 95      ret['all_values'] = all_values
 96      ret['raw'] = data
 97      return ret
 98  
 99  def validate_datapoint(datapoint, mins_to_check, utcnow):
100      val, timestamp = datapoint
101      secs_to_check = 60 * mins_to_check
102      if val is None:
103          return False
104      if timestamp > (utcnow - secs_to_check):
105          return True
106      else:
107          return False
108  
109