# Copyright 2014 Budapest University of Technology and Economics (BME IK) # # This file is part of CIRCLE Cloud. # # CIRCLE is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) # any later version. # # CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along # with CIRCLE. If not, see <http://www.gnu.org/licenses/>. import requests import os class GraphiteHandler: def __init__(self): if os.getenv("GRAPHITE_HOST") in ['', None]: raise RuntimeError self.__server_name = os.getenv("GRAPHITE_HOST") if os.getenv("GRAPHITE_PORT") in ['', None]: raise RuntimeError self.__server_port = os.getenv("GRAPHITE_PORT") self.__queries = [] self.__responses = [] def put(self, query): self.__queries.append(query) def clean_up_queries(self): self.__queries = [] def clean_up_responses(self): self.__responses = [] def is_empty(self): return len(self.__queries) is 0 def generate_all(self): """ Regenerate the queries before sending. """ for query in self.__queries: query.generate() def send(self): """ Generates the corrent query for the Graphite webAPI and flush all the queries in the fifo. Important: After sending queries to the server the fifo will lost its content. """ url_base = "http://%s:%s/render?" % (self.__server_name, self.__server_port) for query in self.__queries: response = requests.get(url_base + query.get_generated()) if query.get_format() == "json": self.__responses.append(response.json()) # DICT else: self.__responses.append(response) self.clean_up_queries() def pop(self): """ Pop the first query has got from the server. """ try: return self.__responses.pop(0) # Transform to dictionary except: raise RuntimeError class Query: def __init__(self): """ Query initializaion: default format is json dictionary keys: ("target <string>","datapoints <list>") """ self.__target = "" self.__metric = "" self.__start = "" self.__end = "" self.__function = "" self.__response_format = "json" self.__generated = "" def set_target(self, target): """ Hostname of the target we should get the information from. After the hostname you should use the domain the target is in. Example: "foo.foodomain.domain.com.DOMAIN" where DOMAIN is the root of the graphite server. """ self.__target = '.'.join(target.split('.')[::-1]) def get_target(self): return self.__target def set_metric(self, metric): self.__metric = metric def get_metric(self): return self.__metric def set_absolute_start(self, year, month, day, hour, minute): """ Function for setting the time you want to get the reports from. """ if (len(year) > 4 or len(year) < 2): raise self.__start = hour + ":" + minute + "_" + year + month + day def set_relative_start(self, value, scale): """ Function for setting the time you want to get the reports from. """ if (scale not in ["years", "months", "days", "hours", "minutes", "seconds"]): raise self.__start = "-" + str(value) + scale def get_start(self): return self.__start def set_absolute_end(self, year, month, day, hour, minute): """ Function for setting the time until you want to get the reports from. """ if (len(year) > 4 or len(year) < 2): raise self.__end = hour + ":" + minute + "_" + year + month + day def set_relative_end(self, value, scale): """ Function for setting the time until you want to get the reports from. """ if (scale not in ["years", "months", "days", "hours", "minutes", "seconds"]): raise self.__end = "-" + str(value) + scale def get_end(self): return self.__end def set_format(self, fmat): """ Function for setting the format of the response from the server. Valid values: ["csv", "raw", "json"] """ valid_formats = ["csv", "raw", "json"] if fmat not in valid_formats: raise self.__response_format = fmat def get_format(self): return self.__response_format def generate(self): """ You must always call this function before sending the metric to the server for it generates the valid format that the graphite API can parse. """ tmp = "target=" + self.__target + "." + self.__metric if len(self.__start) is not 0: tmp = tmp + "&from=" + self.__start if len(self.__end) is not 0: tmp = tmp + "&until=" + self.__end tmp = tmp + "&format=" + self.__response_format self.__generated = tmp return self.__generated def get_generated(self): """ Returns the generated query string. Throws exception if it haven't been done yet. """ if len(self.__generated) is 0: raise return self.__generated