def serie_operatorset(manager, period, perfdatas, timewindow, usenan=True): """ Generate set of operators. :param manager: Serie manager :type manager: canopsis.serie.manager.Serie :param period: Period used for timeserie :type period: canopsis.timeserie.timewindow.Period :param perfdatas: Perfdata classified by metric id :type perfdatas: dict :param timewindow: Time window used for consolidation :type timewindow: canopsis.timeserie.timewindow.TimeWindow :param usenan: include nan point values :type usenan: bool :returns: operators classified by name as dict """ operators = { key: new_operator(key, manager, period, perfdatas, timewindow, usenan) for key in get_aggregations() } return operators
def _aggregation_value(self, values_to_aggregate, func=None): """Get the aggregated value related to input values_to_aggregate, a specific function and a timestamp. """ if func is None: func = get_aggregations()[self.aggregation] if len(values_to_aggregate) > 0: result = round(func(values_to_aggregate), 2) else: result = 0 if self.fill else None return result
def calculate(self, points, timewindow, meta=None, usenan=True): """Do an operation on all points with input timewindow. :param bool usenan: if False (True by default) remove nan point values. :return: points such as follow: Let func self aggregation function and input points of the form: [(T0, V0), ..., (Tn, Vn)] then the result is [(T0, func(V0, V1)), (T2, func(V2, V3), ...]. """ result = [] nan = float('nan') # start to exclude points not in timewindow # in taking care about round time if self.round_time: period = self._get_period(timewindow) round_starttimestamp = period.round_timestamp( timestamp=timewindow.start() ) timewindow = timewindow.reduce( start=round_starttimestamp, stop=timewindow.stop() ) # start to exclude points which are not in timewindow points = [ point for point in points if point[0] in timewindow and (usenan or not isnan(point[1])) ] if not meta: meta = {} transform_method = meta.get('value', {}).get('type', None) points = apply_transform(points, method=transform_method) points_len = len(points) func = None # if no period and max_points > len(points) if ( (not points) or self.period is None and self.max_points > points_len ): result = points # result is points else: # else calculate points with the right aggregation function func = get_aggregations()[self.aggregation] # get timesteps timesteps = self.timesteps(timewindow)[:-1] # initialize variables for loop i = 0 values_to_aggregate = [] last_point = None len_timesteps = len(timesteps) # iterate on timesteps to get points in [prev_ts, timestamp[ for index, timestamp in enumerate(timesteps): # initialize values_to_aggregate values_to_aggregate = [] # set timestamp and previous_timestamp if index < (len_timesteps - 1): # calculate the upper bound next_timestamp = timesteps[index + 1] else: next_timestamp = None # fill the values_to_aggregate array for i in range(i, points_len): # while points to process pt_ts, pt_val = points[i] # leave the loop if _timestamp is for a future aggregation if next_timestamp is not None and pt_ts >= next_timestamp: break else: # add value to list of values to aggregate values_to_aggregate.append(pt_val) else: # leave the loop whatever timesteps i += 1 # TODO: understand what it means :D if self.aggregation == "DELTA" and last_point: values_to_aggregate.insert(0, last_point) if values_to_aggregate: # get the aggregated value related to values_to_aggregate aggregation_value = self._aggregation_value( values_to_aggregate, func ) # new point to add to result if usenan or not isnan(aggregation_value): aggregation_point = timestamp, aggregation_value result.append(aggregation_point) # save last_point for future DELTA checking last_point = aggregation_point[-1] elif usenan: result.append((timestamp, nan)) return result
def calculate(self, points, timewindow, meta=None): """ Do an operation on all points with input timewindow. Return points su as follow: Let fn self aggregation function and input points of the form: [(T0, V0), ..., (Tn, Vn)] then the result is [(T0, fn(V0, V1)), (T2, fn(V2, V3), ...]. """ result = [] # start to exclude points not in timewindow # in taking care about round time if self.round_time: period = self._get_period(timewindow) round_starttimestamp = period.round_timestamp( timestamp=timewindow.start(), normalize=True ) timewindow = timewindow.reduce( start=round_starttimestamp, stop=timewindow.stop() ) # start to exclude points which are not in timewindow points = [point for point in points if point[0] in timewindow] if not meta: meta = {} transform_method = meta.get('value', {}).get('type', None) points = self.apply_transform(points, method=transform_method) points_len = len(points) fn = None # if no period and max_points > len(points) if (not points) or self.period is None\ and self.max_points > points_len: result = points # result is points else: # else get the right aggregation function fn = get_aggregations()[self.aggregation] # if an aggregation is required if fn is not None: # get timesteps timesteps = self.timesteps(timewindow) # initialize variables for loop i = 0 values_to_aggregate = [] last_point = None # iterate on all timesteps in order to get points in [prev_ts, ts[ for index in range(1, len(timesteps)): # initialize values_to_aggregate values_to_aggregate = [] # set timestamp and previous_timestamp previous_timestamp = timesteps[index - 1] timestamp = timesteps[index] # if no point to process in [previous_timestamp, timestamp] if points[i][0] > timestamp: continue # go to the next iteration # fill the values_to_aggregate array while i < points_len: # while there are points to process _timestamp, value = points[i] i += 1 # leave the loop if _timestamp is for a future aggregation if _timestamp > timestamp: break # if _timestamp is in timewindow and value is not None # add value to list of values to aggregate if value is not None: values_to_aggregate.append(value) # TODO: understand what it means :D if self.aggregation == "DELTA" and last_point: values_to_aggregate.insert(0, last_point) # get the aggregated value related to values_to_aggregate _aggregation_value = self._aggregation_value( values_to_aggregate, fn) # new point to add to result aggregation_point = previous_timestamp, _aggregation_value result.append(aggregation_point) # save last_point for future DELTA checking if len(values_to_aggregate) > 0: last_point = values_to_aggregate[-1] if i >= points_len: break else: result = points return result