예제 #1
0
def run():
    api = dbApi.dbApi()
    while True:
        print("Calculating complex measurements, time: ", datetime.now())
        complexEntries = api.getCpxDefinitions()
        measDefs = [MeasurementDef.fromDict(v) for v in complexEntries]
        for measDef in measDefs:
            cpxCalculator = CpxCalculator(measDef)
            sessionIds = api.getSessionIds(measDef.getFilter())
            nowTime = datetime.now()
            for sessionId in sessionIds:
                simpleMeasurements = api.getMeasurements(
                    sessionId,
                    measDef.parent_id,
                    measDef.lastCalcTime,
                    nowTime,
                )
                cpxValues = cpxCalculator.calculate(simpleMeasurements,
                                                    nowTime)
                print(sessionId, measDef.metric_id, cpxValues)
                if len(cpxValues) > 0:
                    api.insertMeasurements(sessionId, measDef.metric_id,
                                           cpxValues)
            measDef.lastCalcTime = nowTime
            api.updateMeasDefinition(measDef.hostname, measDef.metric_id,
                                     measDef.parent_id, measDef.movingWindow,
                                     measDef.interval, measDef.description,
                                     measDef.lastCalcTime, measDef.owner)
        time.sleep(60)
예제 #2
0
def delete_metric(metric_id, hostname):  # noqa: E501
    """Delete complex metric

     # noqa: E501

    :param metric_id: Metric identyfier. It has the same form as `metric_id` field of `Metric` model
    :type metric_id: str
    :param hostname: Target host (domain name)
    :type hostname: str

    :rtype: object
    """
    api = dbApi.dbApi()

    ids = api.getSessionIds({
        api.HOSTNAME_KEY: hostname,
        api.METRIC_PATH: metric_id
    })
    if len(ids) <= 0:
        return "Uknown metric or hostname", 404

    cpxDef = api.getCpxDefinitions({api.METRIC_ID_KEY: metric_id})
    if cpxDef:
        if cpxDef[api.OWNER_KEY] == get_jwt_identity():
            api.deleteComplexMetric(hostname, metric_id)
            api.deleteMetric(hostname, metric_id)
        else:
            return "You aren't creator of complex metric", 403
    else:
        return "Uknown metric, hostname or internal problem", 404

    return "Success", 200
예제 #3
0
def post_metric(hostname, payload):  # noqa: E501
    """Add complex metric

     # noqa: E501

    :param hostname: Target host (domain name)
    :type hostname: str
    :param payload: Complex mertic payload
    :type payload: dict | bytes

    :rtype: InlineResponse201
    """
    api = dbApi.dbApi()
    if connexion.request.is_json:
        payload = Payload.from_dict(connexion.request.get_json())  # noqa: E501

    parent_id = payload.parent_id
    moving_window = payload.moving_window_duration
    interval = payload.interval

    if interval <= 0:
        return "Interval has to be greather than 0", 400

    if moving_window <= 0:
        return "Moving window has to be greater than 0", 400

    description = payload.description
    metric_id = ("cpx_" + str(parent_id) + "_" + str(moving_window) + "_" +
                 str(interval))

    metrics = api.getAllMetrics({dbApi.dbApi.HOSTNAME_KEY: hostname})
    if metric_id in metrics:
        return "Metric id already exists", 409

    print(metrics)
    if parent_id not in metrics:
        return "Unknown parent_id", 404

    hostnames = api.getHosts(None)
    if hostname not in hostnames:
        return "Unknown hostname", 404

    unit = api.updateMetricInMetadata(hostname, metric_id, parent_id,
                                      description)
    if unit == "":
        unit = "Unknown Unit"

    api.insertMeasDefinition(
        hostname,
        metric_id,
        parent_id,
        moving_window,
        interval,
        description,
        get_jwt_identity(),
    )
    response = InlineResponse201(metric_id, unit)
    return response.to_dict(), 201
def get_metrics():  # noqa: E501
    """List of metrics

     # noqa: E501


    :rtype: List[Metric]
    """

    api = dbApi.dbApi()
    metrics = api.getAllMetrics()
    response = []

    for metric in metrics.keys():
        interval = None
        moving_window = None
        parent_id = None
        hosts = api.getHostnameByMetric(metric)

        print("getCpxDefinitions, metric: ", metric)

        cpxDef = api.getCpxDefinitions({api.METRIC_ID_KEY: metric})

        if cpxDef:
            print("cpxDef not none")
            hosts.append(cpxDef[api.HOSTNAME_KEY])
            interval = cpxDef[api.INTERVAL_KEY]
            moving_window = cpxDef[api.MOVING_WINDOW_KEY]
            parent_id = cpxDef[api.PARENT_ID_KEY]
            print(parent_id)

        metric_object = Metric(
            id=metric,
            interval=interval,
            moving_window_duration=moving_window,
            description=metrics[metric][0],
            unit=metrics[metric][1],
            hosts=hosts,
            parent_id=parent_id,
        )
        response.append(metric_object.to_dict())

    return response
예제 #5
0
def get_hosts(q=None):  # noqa: E501
    """Get list of hosts

     # noqa: E501

    :param q: Filters out used metrics and hosts according to provided keys. String needs to match the following schema: &#x60;KEY1:VAL1,KEY2:VAL2;KEY3:VAL4...&#x60;. Comma is used to indicate &#x60;AND&#x60; operation while semicolon relates to &#x60;OR&#x60;. When &#x60;VAL&#x60; paramater is wrapped into slashes then regex mode is activated. For example when we query for &#x60;metric_id:cpu,os:/.*nix.*/;metric_id:cpu,os:/.*win.*/&#x60; we should receive cpu metric measurements for hosts containing either nix or win as substring in &#x60;os&#x60; metadata. Note that &#x60;AND&#x60; operation has higher priority than &#x60;OR&#x60;. Allowed keys: &#x60;metric_id&#x60;, &#x60;description&#x60;, &#x60;complex&#x60; (metric parameters) and all available host metadata fields. When not provided: No filtering performed - all available metrics and hosts are taken
    :type q: str

    :rtype: List[Host]
    """

    api = dbApi.dbApi()
    if q:
        hosts = []
        filters = QueryResolver.QueryResolver(q).getFilters()
        for f in filters:
            hosts.extend(api.getHosts(query=f))
    else:
        hosts = api.getHosts(query="")

    response = []
    for host in hosts:
        metrics = get_metrics()
        metric_objects = []
        for metric in metrics:
            cpxDef = api.getCpxDefinitions({api.METRIC_ID_KEY: metric["id"]})
            if cpxDef:
                currentUser = get_jwt_identity()
                isRemovableByCurrentUser = cpxDef[api.OWNER_KEY] == currentUser
                metric["removable"] = isRemovableByCurrentUser
            metric_objects.append(Metric.from_dict(metric))
        metrics = []
        metrics = [m for m in metric_objects if host in m.hosts]
        metadatas = [
            Metadata.from_dict(metadata)
            for metadata in api.getMetadataByHost(host)
        ]
        response.append((Host(hostname=host,
                              metrics=metrics,
                              metadata=metadatas)).to_dict())

    return response
예제 #6
0
def get_measurements(start=None,
                     end=None,
                     q=None,
                     limit=None,
                     last=None):  # noqa: E501
    """Selected measurements

     # noqa: E501

    :param start: ISO 8601 datetime format with 1s accuracy. Default value is current time subtracted by 1 day
    :type start: str
    :param end: ISO 8601 datetime format with 1s accuracy. Default value is current time.
    :type end: str
    :param q: Filters out used metrics and hosts according to provided keys. String needs to match the following schema: &#x60;KEY1:VAL1,KEY2:VAL2;KEY3:VAL4...&#x60;. Comma is used to indicate &#x60;AND&#x60; operation while semicolon relates to &#x60;OR&#x60;. When &#x60;VAL&#x60; paramater is wrapped into slashes then regex mode is activated. For example when we query for &#x60;metric_id:cpu,os:/.*nix.*/;metric_id:cpu,os:/.*win.*/&#x60; we should receive cpu metric measurements for hosts containing either nix or win as substring in &#x60;os&#x60; metadata. Note that &#x60;AND&#x60; operation has higher priority than &#x60;OR&#x60;. Allowed keys: &#x60;metric_id&#x60;, &#x60;description&#x60;, &#x60;complex&#x60; (metric parameters) and all available host metadata fields. When not provided: No filtering performed - all available metrics and hosts are taken
    :type q: str
    :param limit: Number of maximal amount of measurements given as a result of the query
    :type limit: 
    :param last: If it is set as &#x60;TRUE&#x60; then the only last measurement meeting the criteria from &#x60;q&#x60; parameter is returned
    :type last: bool

    :rtype: List[Measurement]
    """
    api = dbApi.dbApi()

    if not end:
        end = datetime.datetime.now()
    else:
        end = util.deserialize_datetime(end)

    if not start:
        start = datetime.datetime.now() - datetime.timedelta(days=1)
    else:
        start = util.deserialize_datetime(start)

    filters = []
    if not q:
        filters.append(None)
    else:
        resolver = QueryResolver.QueryResolver(q)
        if resolver.validateQuery() == 0:
            return "Bad request", 400
        else:
            filters = resolver.getFilters()

    print("start: " + str(start))
    print("end: " + str(end))
    print("q: " + str(q))

    measurements = []
    for metaFilter in filters:
        print("metaFilter: " + str(metaFilter))
        for sessionId in api.getSessionIds(metaFilter):
            print("sessionId: " + str(sessionId))
            metrics = list()

            if metaFilter and "metric_id" in metaFilter:
                metricFilter = metaFilter["metric_id"]
                print("Metrics filtering with filter: " + str(metricFilter))
                metrics = api.getMetrics(sessionId, metricFilter)
            else:
                print("No metrics filtering, take all metrics")
                metrics = api.getMetrics(sessionId)

            for metric in metrics:
                print(sessionId)
                print(metric)
                print(start)
                print(end)
                dataPoints = api.getMeasurements(sessionId, metric, start, end)
                points = [
                    Point(point[VALUE_IND], point[TIME_IND])
                    for point in dataPoints
                ]

                measurement = Measurement(metric, api.getHostname(sessionId),
                                          points)
                measurements.append(measurement.to_dict())

    return measurements