def GET(self, autostackId, *args): # pylint: disable=C0103,W0613 """ Get Metrics associated with autostack :: GET /_autostacks/{autostackId}/metrics NOTE: args is ignored. Function signature for all method handlers must be compatible with the regexp pattern that matches. POST optionally takes a second argument, DELETE requires it. """ try: self.addStandardHeaders() engine = repository.engineFactory() metricRows = repository.getAutostackMetrics(engine, autostackId, getMetricDisplayFields(engine)) metricsList = [convertMetricRowToMetricDict(metricRow) for metricRow in metricRows] return utils.jsonEncode(metricsList) except ObjectNotFoundError: raise web.notfound("Autostack not found: Autostack ID: %s" % autostackId) except web.HTTPError as ex: if bool(re.match(r"([45][0-9][0-9])\s?", web.ctx.status)): # Log 400-599 status codes as errors, ignoring 200-399 log.error(str(ex) or repr(ex)) raise except Exception as ex: raise web.internalerror(str(ex) or repr(ex))
def GET(self): with web.ctx.connFactory() as conn: metrics = repository.getCustomMetrics(conn, getMetricDisplayFields(conn)) convertedMetrics = [convertMetricRowToMetricDict(metric) for metric in metrics] self.addStandardHeaders() return json.dumps(convertedMetrics)
def GET(self, period): """ Get metrics, sorted by anomalies over specified period (hours) :param period: Period (hours) over which to consider anomalies for sort order :type period: int :returns: List of metrics :rtype: list Example request:: GET /_anomalies/period/{period} Example response:: [ { "status": 1, "last_rowid": 4033, "display_name": "jenkins-master (us-west-2/AWS/EC2/i-12345678)", "description": "NetworkIn on EC2 instance i-12345678 in us-west-2", "name": "AWS/EC2/NetworkIn", "last_timestamp": "2014-04-14 20:29:00", "poll_interval": 300, "server": "us-west-2/AWS/EC2/i-12345678", "tag_name": "jenkins-master", "datasource": "cloudwatch", "location": "us-west-2", "message": null, "parameters": { "InstanceId": "i-12345678", "region": "us-west-2" }, "uid": "0b6b97022fdb4134936aae92aa67393b" }, ... ] """ try: self.addStandardHeaders() engine = repository.engineFactory() with engine.connect() as conn: modelIterator = repository.getAllMetrics(conn, fields=getMetricDisplayFields(conn)) displayValuesMap = repository.getMetricIdsSortedByDisplayValue(conn, period) # Keep track of the largest model display value for each server serverValues = defaultdict(float) modelsList = [] for model in modelIterator: val = displayValuesMap.get(model.uid) if val is not None: serverValues[model.server] = max(float(val), serverValues[model.server]) modelsList.append(convertMetricRowToMetricDict(model)) # Sort by the primary key. The order within each server is preserved # from previous sort. def getModelRankByServer(model): return (-serverValues[model["server"]], model["server"], model["name"]) modelsList = sorted(modelsList, key=getModelRankByServer) return utils.jsonEncode(modelsList) except (web.HTTPError) as ex: log.info(str(ex) or repr(ex)) raise ex except Exception as ex: log.exception("GET Failed") raise web.internalerror(str(ex) or repr(ex))
def GET(self): """ Get metrics, sorted by AWS name tag / instance ID :returns: List of metrics :rtype: list Example request:: GET /_anomalies/name Example response:: [ { "status": 1, "last_rowid": 4033, "display_name": "jenkins-master (us-west-2/AWS/EC2/i-12345678)", "description": "NetworkIn on EC2 instance i-12345678 in us-west-2", "name": "AWS/EC2/NetworkIn", "last_timestamp": "2014-04-14 20:29:00", "poll_interval": 300, "server": "us-west-2/AWS/EC2/i-12345678", "tag_name": "jenkins-master", "datasource": "cloudwatch", "location": "us-west-2", "message": null, "parameters": { "InstanceId": "i-12345678", "region": "us-west-2" }, "uid": "0b6b97022fdb4134936aae92aa67393b" }, ... ] """ try: self.addStandardHeaders() engine = repository.engineFactory() with engine.connect() as conn: modelIterator = repository.getAllMetrics(conn, fields=getMetricDisplayFields(conn)) modelsList = [convertMetricRowToMetricDict(model) for model in modelIterator] # Sort by tag_name, and then parameters=>InstanceID def cmpFn(model1, model2): name1 = model1["tag_name"] name2 = model2["tag_name"] id1 = model1["parameters"].get("InstanceID") id2 = model2["parameters"].get("InstanceID") if name1 and not name2: return -1 elif name2 and not name1: return 1 elif name1 != name2: return cmp(name1, name2) elif id1 and not id2: return -1 elif id2 and not id1: return 1 elif id1 != id2: return cmp(id1, id2) return 0 modelsList.sort(cmpFn) return utils.jsonEncode(modelsList) except (web.HTTPError) as ex: log.info(str(ex) or repr(ex)) raise ex except Exception as ex: log.exception("GET Failed") raise web.internalerror(str(ex) or repr(ex))
def POST(self, autostackId, data=None): # pylint: disable=C0103,R0201 """ Create one or more Autostack Metric(s) :: POST /_autostacks/{autostackId}/metrics [ { "namespace": "AWS/EC2", "metric": "CPUUtilization" }, ... ] Request body is a list of items, each of which are a subset of the standard cloudwatch native metric, specifying only: :param namespace: AWS Namespace :type namespace: str :param metric: AWS Metric name :type str: `datasource`, `region`, and `dimensions` normally required when creating models are not necessary. """ try: self.addStandardHeaders() with web.ctx.connFactory() as conn: autostackRow = repository.getAutostack(conn, autostackId) data = data or utils.jsonDecode(web.data()) for nativeMetric in data: try: if nativeMetric["namespace"] == "Autostacks": slaveDatasource = "autostack" else: slaveDatasource = "cloudwatch" # only support cloudwatch for now modelParams = {} if "min" and "max" in nativeMetric: modelParams["min"] = nativeMetric["min"] modelParams["max"] = nativeMetric["max"] modelSpec = { "datasource": "autostack", "metricSpec": { "autostackId": autostackRow.uid, "slaveDatasource": slaveDatasource, "slaveMetric": nativeMetric }, "modelParams": modelParams } metricId = (createAutostackDatasourceAdapter() .monitorMetric(modelSpec)) with web.ctx.connFactory() as conn: metricRow = repository.getMetric(conn, metricId) metricDict = convertMetricRowToMetricDict(metricRow) except KeyError: raise web.badrequest("Missing details in request") except ValueError: response = {"result": "failure"} raise web.badrequest(utils.jsonEncode(response)) response = {"result": "success", "metric": metricDict} raise web.created(utils.jsonEncode(response)) except ObjectNotFoundError: raise web.notfound("Autostack not found: Autostack ID: %s" % autostackId) except (web.HTTPError) as ex: if bool(re.match(r"([45][0-9][0-9])\s?", web.ctx.status)): # Log 400-599 status codes as errors, ignoring 200-399 log.error(str(ex) or repr(ex)) raise except Exception as ex: log.exception("POST Failed") raise web.internalerror(str(ex) or repr(ex))
def GET(self, period): """ Get metrics, sorted by anomalies over specified period (hours) :param period: Period (hours) over which to consider anomalies for sort order :type period: int :returns: List of metrics :rtype: list Example request:: GET /_anomalies/period/{period} Example response:: [ { "status": 1, "last_rowid": 4033, "display_name": "jenkins-master (us-west-2/AWS/EC2/i-12345678)", "description": "NetworkIn on EC2 instance i-12345678 in us-west-2", "name": "AWS/EC2/NetworkIn", "last_timestamp": "2014-04-14 20:29:00", "poll_interval": 300, "server": "us-west-2/AWS/EC2/i-12345678", "tag_name": "jenkins-master", "datasource": "cloudwatch", "location": "us-west-2", "message": null, "parameters": { "InstanceId": "i-12345678", "region": "us-west-2" }, "uid": "0b6b97022fdb4134936aae92aa67393b" }, ... ] """ try: self.addStandardHeaders() engine = repository.engineFactory() with engine.connect() as conn: modelIterator = repository.getAllMetrics( conn, fields=getMetricDisplayFields(conn)) displayValuesMap = repository.getMetricIdsSortedByDisplayValue( conn, period) # Keep track of the largest model display value for each server serverValues = defaultdict(float) modelsList = [] for model in modelIterator: val = displayValuesMap.get(model.uid) if val is not None: serverValues[model.server] = max( float(val), serverValues[model.server]) modelsList.append(convertMetricRowToMetricDict(model)) # Sort by the primary key. The order within each server is preserved # from previous sort. def getModelRankByServer(model): return (-serverValues[model["server"]], model["server"], model["name"]) modelsList = sorted(modelsList, key=getModelRankByServer) return utils.jsonEncode(modelsList) except (web.HTTPError) as ex: log.info(str(ex) or repr(ex)) raise ex except Exception as ex: log.exception("GET Failed") raise web.internalerror(str(ex) or repr(ex))
def GET(self): """ Get metrics, sorted by AWS name tag / instance ID :returns: List of metrics :rtype: list Example request:: GET /_anomalies/name Example response:: [ { "status": 1, "last_rowid": 4033, "display_name": "jenkins-master (us-west-2/AWS/EC2/i-12345678)", "description": "NetworkIn on EC2 instance i-12345678 in us-west-2", "name": "AWS/EC2/NetworkIn", "last_timestamp": "2014-04-14 20:29:00", "poll_interval": 300, "server": "us-west-2/AWS/EC2/i-12345678", "tag_name": "jenkins-master", "datasource": "cloudwatch", "location": "us-west-2", "message": null, "parameters": { "InstanceId": "i-12345678", "region": "us-west-2" }, "uid": "0b6b97022fdb4134936aae92aa67393b" }, ... ] """ try: self.addStandardHeaders() engine = repository.engineFactory() with engine.connect() as conn: modelIterator = repository.getAllMetrics( conn, fields=getMetricDisplayFields(conn)) modelsList = [ convertMetricRowToMetricDict(model) for model in modelIterator ] # Sort by tag_name, and then parameters=>InstanceID def cmpFn(model1, model2): name1 = model1["tag_name"] name2 = model2["tag_name"] id1 = model1["parameters"].get("InstanceID") id2 = model2["parameters"].get("InstanceID") if name1 and not name2: return -1 elif name2 and not name1: return 1 elif name1 != name2: return cmp(name1, name2) elif id1 and not id2: return -1 elif id2 and not id1: return 1 elif id1 != id2: return cmp(id1, id2) return 0 modelsList.sort(cmpFn) return utils.jsonEncode(modelsList) except (web.HTTPError) as ex: log.info(str(ex) or repr(ex)) raise ex except Exception as ex: log.exception("GET Failed") raise web.internalerror(str(ex) or repr(ex))