示例#1
0
  def _createMetric(self, conn, metricName):
    """ Create scalar HTM metric if it doesn't exist

    :param conn: SQLAlchemy;
    :type conn: sqlalchemy.engine.Connection

    :param metricName: name of the HTM metric
    :type metricName: string

    :rtype: unique HTM metric identifier

    :raises htmengine.exceptions.MetricAlreadyExists: if a metric with same
      name already exists
    """
    resource = self._makeDefaultResourceName(metricName)

    # First, try to get it without locking (faster in typical case)
    try:
      with self.connectionFactory() as conn:
        metricObj = repository.getCustomMetricByName(
          conn,
          metricName,
          fields=[schema.metric.c.uid])
    except app_exceptions.ObjectNotFoundError:
      pass
    else:
      raise app_exceptions.MetricAlreadyExists(
        "Custom metric with matching name already exists: "
        "metric=%s, name=%s" % (metricObj.uid, metricName,),
        uid=metricObj.uid)

    with self.connectionFactory() as conn:
      with conn.begin():
        repository.lockOperationExclusive(conn,
                                          repository.OperationLock.METRICS)

        try:
          # Check again under lock, to avoid race condition with another process
          metricObj = repository.getCustomMetricByName(
            conn,
            metricName,
            fields=[schema.metric.c.uid])
        except app_exceptions.ObjectNotFoundError:
          pass
        else:
          return metricObj.uid

        metricDict = repository.addMetric(
          conn,
          name=metricName,
          description="Custom metric %s" % (metricName,),
          server=resource,
          location="",
          poll_interval=self._DEFAULT_METRIC_PERIOD,
          status=MetricStatus.UNMONITORED,
          datasource=self._DATASOURCE)

        return metricDict["uid"]
示例#2
0
    def _createMetric(self, conn, metricName):
        """ Create scalar HTM metric if it doesn't exist

    :param conn: SQLAlchemy;
    :type conn: sqlalchemy.engine.Connection

    :param metricName: name of the HTM metric
    :type metricName: string

    :rtype: unique HTM metric identifier

    :raises htmengine.exceptions.MetricAlreadyExists: if a metric with same
      name already exists
    """
        resource = self._makeDefaultResourceName(metricName)

        # First, try to get it without locking (faster in typical case)
        try:
            with self.connectionFactory() as conn:
                metricObj = repository.getCustomMetricByName(
                    conn, metricName, fields=[schema.metric.c.uid])
        except app_exceptions.ObjectNotFoundError:
            pass
        else:
            raise app_exceptions.MetricAlreadyExists(
                "Custom metric with matching name already exists: "
                "metric=%s, name=%s" % (
                    metricObj.uid,
                    metricName,
                ),
                uid=metricObj.uid)

        with self.connectionFactory() as conn:
            with conn.begin():
                repository.lockOperationExclusive(
                    conn, repository.OperationLock.METRICS)

                try:
                    # Check again under lock, to avoid race condition with another process
                    metricObj = repository.getCustomMetricByName(
                        conn, metricName, fields=[schema.metric.c.uid])
                except app_exceptions.ObjectNotFoundError:
                    pass
                else:
                    return metricObj.uid

                metricDict = repository.addMetric(
                    conn,
                    name=metricName,
                    description="Custom metric %s" % (metricName, ),
                    server=resource,
                    location="",
                    poll_interval=self._DEFAULT_METRIC_PERIOD,
                    status=MetricStatus.UNMONITORED,
                    datasource=self._DATASOURCE)

                return metricDict["uid"]
示例#3
0
    def checkStats(self, metricName, mn, mx):
        """Check that stats are computed correctly from the database"""
        engine = repository.engineFactory(config=self.__config)
        with engine.begin() as conn:
            metricObj = (repository.getCustomMetricByName(
                conn,
                metricName,
                fields=[schema.metric.c.uid, schema.metric.c.parameters]))
            stats = repository.getMetricStats(conn, metricObj.uid)

        self.assertSetEqual(set(stats.keys()), set(("min", "max")))
        self.assertAlmostEqual(stats["min"], mn)
        self.assertAlmostEqual(stats["max"], mx)
示例#4
0
  def checkStats(self, metricName, mn, mx):
    """Check that stats are computed correctly from the database"""
    engine = repository.engineFactory(config=self.__config)
    with engine.begin() as conn:
      metricObj = (
        repository.getCustomMetricByName(conn,
                                         metricName,
                                         fields=[schema.metric.c.uid,
                                                 schema.metric.c.parameters]))
      stats = repository.getMetricStats(conn, metricObj.uid)

    self.assertSetEqual(set(stats.keys()), set(("min", "max")))
    self.assertAlmostEqual(stats["min"], mn)
    self.assertAlmostEqual(stats["max"], mx)
示例#5
0
def handler(environ, start_response):
    metricName = environ["PATH_INFO"]

    if environ["REQUEST_METHOD"] == "PUT":
        # Trigger model creation...

        modelSpec = {
            "datasource": "custom",
            "metricSpec": {
                "metric": metricName
            },
            "modelParams": {}
        }

        try:
            modelSpec["modelParams"].update(json.load(environ["wsgi.input"]))
        except Exception as e:
            start_response("400 Bad Request", [("Content-Type", "text/html")])
            yield "Unable to parse request"

        adapter = createDatasourceAdapter(modelSpec["datasource"])
        try:
            modelId = adapter.monitorMetric(modelSpec)
            start_response("201 Created", [("Content-Type", "text/html")])
            yield "Created %s\n" % modelId

        except MetricAlreadyMonitored:
            start_response("400 Bad Request", [("Content-Type", "text/html")])
            yield "Model already exists for %s" % metricName
    elif environ["REQUEST_METHOD"] == "POST":
        # Send data...

        start_response("200 OK", [("Content-Type", "text/html")])

        for sample in environ["wsgi.input"]:
            value, ts = sample.split(" ")
            sendSample(bus,
                       metricName=metricName,
                       value=float(value),
                       epochTimestamp=int(ts))

            yield "Saved %s %f @ %d\n" % (metricName, float(value), int(ts))
    elif environ["REQUEST_METHOD"] == "GET":
        with repository.engineFactory(appConfig).connect() as conn:
            fields = (schema.metric_data.c.metric_value,
                      schema.metric_data.c.timestamp,
                      schema.metric_data.c.rowid,
                      schema.metric_data.c.anomaly_score)
            sort = schema.metric_data.c.timestamp.asc()

            metricObj = repository.getCustomMetricByName(
                conn, metricName, fields=[schema.metric.c.uid])

            result = repository.getMetricData(conn,
                                              metricId=metricObj.uid,
                                              fields=fields,
                                              sort=sort)

            start_response("200 OK", [("Content-Type", "text/html")])

            for row in result:
                yield " ".join(
                    (metricName, str(row.metric_value),
                     str(calendar.timegm(row.timestamp.timetuple())),
                     str(row.anomaly_score))) + "\n"
def handler(environ, start_response):
    metricName = environ["PATH_INFO"]

    if environ["REQUEST_METHOD"] == "PUT":
        # Trigger model creation...

        modelSpec = {"datasource": "custom", "metricSpec": {"metric": metricName}, "modelParams": {}}

        try:
            modelSpec["modelParams"].update(json.load(environ["wsgi.input"]))
        except Exception as e:
            print e
            start_response("400 Bad Request", [("Content-Type", "text/html")])
            yield "Unable to parse request"

        adapter = createDatasourceAdapter(modelSpec["datasource"])
        try:
            modelId = adapter.monitorMetric(modelSpec)
            start_response("201 Created", [("Content-Type", "text/html")])
            yield "Created %s\n" % modelId

        except MetricAlreadyMonitored:
            start_response("400 Bad Request", [("Content-Type", "text/html")])
            yield "Model already exists for %s" % metricName
    elif environ["REQUEST_METHOD"] == "POST":
        # Send data...

        start_response("200 OK", [("Content-Type", "text/html")])

        for sample in environ["wsgi.input"]:
            value, ts = sample.split(" ")
            sendSample(bus, metricName=metricName, value=float(value), epochTimestamp=int(ts))

            yield "Saved %s %f @ %d\n" % (metricName, float(value), int(ts))
    elif environ["REQUEST_METHOD"] == "GET":
        # parameters = parse_qs(environ.get('QUERY_STRING', ''))
        # print parameters
        # if 'since' in parameters:
        #   since = parameters['since'][0]
        with repository.engineFactory(appConfig).connect() as conn:
            fields = (
                schema.metric_data.c.metric_value,
                schema.metric_data.c.timestamp,
                schema.metric_data.c.rowid,
                schema.metric_data.c.anomaly_score,
            )
            sort = schema.metric_data.c.timestamp.asc()

            metricObj = repository.getCustomMetricByName(conn, metricName, fields=[schema.metric.c.uid])

            result = repository.getMetricData(conn, metricId=metricObj.uid, fields=fields, sort=sort)

            start_response("200 OK", [("Content-Type", "text/html")])

            for row in result:
                yield " ".join(
                    (
                        metricName,
                        str(row.metric_value),
                        str(calendar.timegm(row.timestamp.timetuple())),
                        str(row.anomaly_score),
                    )
                ) + "\n"