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"]
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"]
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)
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)
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"