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