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)
Beispiel #2
0
    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, 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))
Beispiel #4
0
 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)
Beispiel #5
0
    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))
Beispiel #6
0
    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))
Beispiel #7
0
    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 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))