def get_arima_forecast(series, p, d, q, forecast, trend): series_adapted = adapt_time_series(series)[1] forecast_result = [] try: model = ARIMA(series_adapted, order=(p, d, q)) model_fit = model.fit(disp=0, trend=trend) forecast_result = model_fit.forecast(steps=forecast)[0] except Exception as e: # pass # print(e) # print(forecast_result) try: print("trying basic arima") model = ARIMA(series_adapted, order=(1, 1, 1)) model_fit = model.fit(disp=0, trend=trend) forecast_result = model_fit.forecast(steps=forecast)[0] except Exception as e: pass finally: if len(forecast_result) == 0: length = len(series_adapted) - 1 forecast_result = [series_adapted[length]] * forecast forecast_result = clean_arima(forecast_result) return forecast_result
def generate_data_multichart(array_data, array_names, time): data = "&chd=a:" index = 0 for array in array_data: if 'forecast' in array_names[index]: data += list_to_str(range(time, time + time)) else: data += list_to_str(range(0, time)) data += "|" if isinstance(array[0], list): data_parsed = adapt_time_series(array) array = data_parsed[1] length = len(array) - 1 start = length - time if start < 0: start = 0 array = array[start:length] data += list_to_str(array) data += "|" index += 1 data = data[:-1] return data
def generate_timeseries_chart(timeseries, name): data_parsed = adapt_time_series(timeseries) values = data_parsed[1] time = data_parsed[0] values_str = list_to_str(values) min_y = str(min(values)) max_y = str(max(values)) url = generate_url_chart(data=values_str, name=name, max_y=max_y, min_y=min_y) return url
def double_forecast_check(metric, forecasts, config_file, mode): alarm_paused = get_alarm_pause_status(config_file, "double_forecast") if not alarm_paused: forecast_percentage = get_monitoring_forecast_percentage(config_file) forecast_time = get_forecast_time(config_file) server = get_server(config_file) query = get_query_actual_search(metric=metric, config=config_file) actual_values = adapt_time_series( get_values(server, query, forecast_time)) max_actual = max(actual_values[1]) min_actual = min(actual_values[1]) difference_actual = calculate_percentage(max_actual, min_actual) min_diff = get_alarm_minimum_difference_forecast(config_file) max_diff = get_alarm_maximum_difference_forecast(config_file) if difference_actual > forecast_percentage: forecast_anomaly = True for forecast in forecasts: if mode == 'any': max_forecast = max(forecast[1]) min_forecast = min(forecast[1]) if check_alarm_percentage( actual_value=max_forecast, calculated_value=min_forecast, percentage_change=forecast_percentage, min_diff=min_diff, max_diff=max_diff): alarm = alarm or True else: alarm = alarm or False elif (forecast[0] == mode) or (mode == 'both'): min_forecast = min(forecast[1]) max_forecast = max(forecast[1]) difference_forecast = calculate_percentage( max_forecast, min_forecast) if difference_forecast >= difference_actual: forecast_anomaly = forecast_anomaly and True else: forecast_anomaly = forecast_anomaly and False if forecast_anomaly: return True else: return False
def test_double_forecast(file, minutes_alarm_forecast, config_file): time_series = prepare_timeseries(file, "ITCT") forecast_percentage = get_monitoring_forecast_percentage(config_file) anomaly_minutes = [] for minutes in minutes_alarm_forecast: start = int((minutes / 60) - 60 + 1) finish = int(minutes / 60 + 1) time_series_reduced = time_series[start:finish] time_series_reduced_adapted = adapt_time_series(time_series_reduced) max_actual = max(time_series_reduced_adapted[1]) min_actual = min(time_series_reduced_adapted[1]) difference_actual = calculate_percentage(max_actual, min_actual) if difference_actual > forecast_percentage: anomaly_minutes.append(finish) anomaly_minutes = anomaly_minutes and minutes_alarm_forecast return anomaly_minutes
def generate_url_multichart(array_data, array_names, name, time): base_url = "https://image-charts.com/chart" type_chart = "?cht=lxy" size = "&chs=700x200" data = generate_data_multichart(array_data=array_data, array_names=array_names, time=time) max_y = None min_y = None # for each metric in the array_data we parse the information and we get its max and min values to adapt the chart for array in array_data: if isinstance(array[0], list): data_parsed = adapt_time_series(array) array = data_parsed[1] local_max_y = max(array) local_min_y = min(array) if max_y is None or local_max_y > max_y: max_y = local_max_y if min_y is None or local_min_y < min_y: min_y = local_min_y # We adapt that information for the image-charts.com format axis = "&chxt=x,y&chxs=0,s|1,s" range_chart = "&chxr=1," + str(min_y) + "," + str(max_y) title_chart = "&chtt=" + name legend = "&chdl=" for legend_name in array_names: legend += legend_name + "|" legend = legend[:-1] chart_extras = axis + range_chart + title_chart + legend url = base_url + type_chart + size + chart_extras + data return url
def get_regression_array(server, case, variable_to_predict, app, datacenter, kubernetes_namespace, time): prediction = [0] * time # For each model for model in case[variable_to_predict]["metrics"]: # We check all the metrics of the model and we calculate the prediction for metric in model: query = get_query_regression( app=app, datacenter=datacenter, case=case, variable_to_predict=variable_to_predict, metric=metric, model=model, kubernetes_namespace=kubernetes_namespace) values = adapt_time_series(get_values(server, query, time))[1] # We multiply the values according to the model exp = float(model[metric]["exp"]) powered = [n**exp for n in values] mult = float(model[metric]["value"]) actual_prediction = [i * mult for i in powered] # if the prediction is smaller than requested, we extend it taking the last value if len(actual_prediction) < time: last_value = actual_prediction[len(actual_prediction) - 1] actual_prediction += [last_value ] * (time - len(actual_prediction)) # we add this metric to the previous ones prediction = [