Updated the slo_rules_topic and created a new metric_list_topic which will accept new SLO definitions and the list of upper and lower bounds per monitoring metric respectively.
Created two endpoints required to instantiate a new Detector Subcomponent, named new-application-slo and new-application-metric-list respectively which retrieve any new SLO to be considered by the SLOViD or the metric list containing the upper and lower bounds of the individual metrics to be monitored Simplification of DetectorSubcomponent and RealtimeMonitoringAttribute classes by removing unecessary code Introduction of lower and upper bounds in the RealtimeMonitoringAttribute class Miscellaneous code style improvements Change-Id: I114c94bb625023dfef7afac26d7581de6b7b3e00
This commit is contained in:
parent
f662d2711f
commit
8adcb5e070
@ -17,27 +17,20 @@ public class Constants {
|
||||
public static String EMPTY = "";
|
||||
public static String SPACE = " ";
|
||||
public static Double LOWER_LIMIT_DELTA = - 100.0;
|
||||
public static Double UPPER_LIMIT_DELTA = - 100.0;
|
||||
|
||||
|
||||
//Operational constants
|
||||
public static boolean USE_CONFIGURATION_FILE_FOR_METRIC_VALUES_INPUT = false;
|
||||
public static boolean USE_CONFIGURATION_FILE_FOR_METRIC_TOPICS_INPUT = false;
|
||||
public static int elements_considered_in_prediction = 10;
|
||||
public static String slo_violation_determination_method;
|
||||
public static int time_horizon_seconds;
|
||||
public static int maximum_acceptable_forward_predictions;
|
||||
|
||||
public static double confidence_interval;
|
||||
public static double prediction_certainty;
|
||||
|
||||
public static String [] logic_operators = {"and","or"};
|
||||
public static final String default_handled_application_name = "default_application";
|
||||
public static URI base_project_path;
|
||||
public static String configuration_file_location = "src/main/resources/config/input_data.properties";
|
||||
public static String amq_library_configuration_location = "src/main/resources/config/eu.melodic.event.brokerclient.properties";
|
||||
public static String topic_for_severity_announcement = "prediction.slo_severity_value";
|
||||
public static String topic_for_lost_device_announcement = "eu.nebulouscloud.device_lost";
|
||||
public static String slo_rules_topic = "metrics.metric_list";
|
||||
public static String slo_rules_topic = "eu.nebulouscloud.monitoring.slo.new";
|
||||
public static String metric_list_topic = "eu.nebulouscloud.monitoring.metric_list";
|
||||
public static double slo_violation_probability_threshold = 0.5; //The threshold over which the probability of a predicted slo violation should be to have a violation detection
|
||||
public static int kept_values_per_metric = 5; //Default to be overriden from the configuration file. This indicates how many metric values are kept to calculate the "previous" metric value during the rate of change calculation
|
||||
public static String roc_calculation_mode = "prototype";
|
||||
|
@ -5,19 +5,18 @@ import slo_violation_detector_engine.DetectorSubcomponent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static configuration.Constants.EMPTY;
|
||||
import static configuration.Constants.default_handled_application_name;
|
||||
import static runtime.Main.detectors;
|
||||
import static slo_violation_detector_engine.DetectorSubcomponent.detector_integer_id;
|
||||
import static utilities.DebugDataSubscription.debug_data_generation;
|
||||
import static utilities.DebugDataSubscription.debug_data_output_topic_name;
|
||||
import static utility_beans.CharacterizedThread.CharacterizedThreadRunMode.detached;
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class DetectorRequestMappings {
|
||||
|
||||
@RequestMapping("/add-new-detector")
|
||||
public static String start_new_detector_subcomponent() throws IOException {
|
||||
detectors.add(new DetectorSubcomponent(detached));
|
||||
public static String start_new_detector_subcomponent() {
|
||||
detectors.add(new DetectorSubcomponent(default_handled_application_name,detached));
|
||||
return ("Spawned new SLO Detector subcomponent instance! Currently, there have been "+detector_integer_id+" detectors spawned");
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,79 @@
|
||||
package runtime;
|
||||
|
||||
import configuration.Constants;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import slo_violation_detector_engine.DetectorSubcomponent;
|
||||
import utility_beans.CharacterizedThread;
|
||||
import utility_beans.RealtimeMonitoringAttribute;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static configuration.Constants.default_handled_application_name;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class DirectorRequestMappings {
|
||||
@PostMapping(value = "/new-application",
|
||||
@PostMapping(value = "/new-application-slo",
|
||||
consumes = APPLICATION_JSON_VALUE)
|
||||
public static String start_new_detector_subcomponent(@RequestBody String string_rule_representation){
|
||||
DetectorSubcomponent new_detector = new DetectorSubcomponent(CharacterizedThread.CharacterizedThreadRunMode.detached);
|
||||
JSONObject rule_representation_json;
|
||||
JSONParser json_parser = new JSONParser();
|
||||
String application_name;
|
||||
try {
|
||||
rule_representation_json = (JSONObject) json_parser.parse(string_rule_representation);
|
||||
} catch (ParseException e) {
|
||||
return "Error in parsing the input string, the exception message follows:\n"+e;
|
||||
}
|
||||
application_name = (String) rule_representation_json.get("name");
|
||||
DetectorSubcomponent new_detector = DetectorSubcomponent.detector_subcomponents.getOrDefault(application_name,new DetectorSubcomponent(default_handled_application_name,CharacterizedThread.CharacterizedThreadRunMode.detached));
|
||||
new_detector.slo_rule_topic_subscriber_function.apply(Constants.slo_rules_topic,string_rule_representation);
|
||||
return ("New application was spawned");
|
||||
}
|
||||
|
||||
@PostMapping(value = "/new-application-metric-list",
|
||||
consumes = APPLICATION_JSON_VALUE)
|
||||
public static String parse_metric_list(@RequestBody String metric_list){
|
||||
JSONObject metric_list_json;
|
||||
JSONArray metrics_json_array;
|
||||
JSONParser json_parser = new JSONParser();
|
||||
String application_name;
|
||||
try {
|
||||
metric_list_json = (JSONObject) json_parser.parse(metric_list);
|
||||
} catch (ParseException e) {
|
||||
return "Error in parsing the input string, the exception message follows:\n"+e;
|
||||
}
|
||||
application_name = (String) metric_list_json.get("name");
|
||||
DetectorSubcomponent new_detector = DetectorSubcomponent.detector_subcomponents.getOrDefault(application_name,new DetectorSubcomponent(application_name,CharacterizedThread.CharacterizedThreadRunMode.detached));
|
||||
|
||||
HashMap<String,RealtimeMonitoringAttribute> application_metrics = new_detector.getSubcomponent_state().getMonitoring_attributes();
|
||||
metrics_json_array = (JSONArray) metric_list_json.get("metric_list");
|
||||
for (Object metric : metrics_json_array){
|
||||
JSONObject metric_json = (JSONObject) metric;
|
||||
String metric_name = (String) metric_json.get("name");
|
||||
int upper_bound = 100,lower_bound = 0;
|
||||
if (((String) metric_json.get("upper_bound")).toLowerCase().contains("-inf")){
|
||||
upper_bound = -Integer.MAX_VALUE;
|
||||
}else if (((String) metric_json.get("upper_bound")).toLowerCase().contains("inf")){
|
||||
upper_bound = Integer.MAX_VALUE;
|
||||
}
|
||||
if (((String) metric_json.get("lower_bound")).toLowerCase().contains("-inf")){
|
||||
lower_bound = -Integer.MAX_VALUE;
|
||||
}
|
||||
else if (((String) metric_json.get("lower_bound")).toLowerCase().contains("inf")){
|
||||
lower_bound = Integer.MAX_VALUE;
|
||||
}
|
||||
application_metrics.put(metric_name,new RealtimeMonitoringAttribute(metric_name,lower_bound,upper_bound));
|
||||
}
|
||||
|
||||
RealtimeMonitoringAttribute.initialize_monitoring_attributes(new_detector,application_metrics);
|
||||
return ("New application was spawned - The monitoring metrics related to the application are the following: "+application_metrics);
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class Main {
|
||||
|
||||
try {
|
||||
{
|
||||
InputStream inputStream = null;
|
||||
InputStream inputStream;
|
||||
if (args.length == 0) {
|
||||
operational_mode = getSLOViolationDetectionOperationalMode("DIRECTOR");
|
||||
inputStream = getPreferencesFileInputStream(EMPTY);
|
||||
@ -70,9 +70,9 @@ public class Main {
|
||||
slo_violation_probability_threshold = Double.parseDouble(prop.getProperty("slo_violation_probability_threshold"));
|
||||
slo_violation_determination_method = prop.getProperty("slo_violation_determination_method");
|
||||
maximum_acceptable_forward_predictions = Integer.parseInt(prop.getProperty("maximum_acceptable_forward_predictions"));
|
||||
DetectorSubcomponent detector = new DetectorSubcomponent(detached);
|
||||
DetectorSubcomponent detector = new DetectorSubcomponent(default_handled_application_name,detached);
|
||||
detectors.add(detector);
|
||||
ArrayList<String> unbounded_metric_strings = new ArrayList<String>(Arrays.asList(prop.getProperty("metrics_bounds").split(",")));
|
||||
ArrayList<String> unbounded_metric_strings = new ArrayList<>(Arrays.asList(prop.getProperty("metrics_bounds").split(",")));
|
||||
for (String metric_string : unbounded_metric_strings) {
|
||||
detector.getSubcomponent_state().getMonitoring_attributes_bounds_representation().put(metric_string.split(";")[0], metric_string.split(";", 2)[1]);
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ import static utility_beans.CharacterizedThread.CharacterizedThreadRunMode.attac
|
||||
public class DetectorSubcomponent extends SLOViolationDetectorSubcomponent{
|
||||
public static final SynchronizedInteger detector_integer_id = new SynchronizedInteger();
|
||||
public static HashMap<String,DetectorSubcomponent> detector_subcomponents = new HashMap<>(); //A HashMap containing all detector subcomponents
|
||||
private DetectorSubcomponentUtilities utilities;
|
||||
|
||||
private DetectorSubcomponentState subcomponent_state;
|
||||
public final AtomicBoolean stop_signal = new AtomicBoolean(false);
|
||||
public final SynchronizedBoolean can_modify_slo_rules = new SynchronizedBoolean(false);
|
||||
@ -34,11 +32,10 @@ public class DetectorSubcomponent extends SLOViolationDetectorSubcomponent{
|
||||
public Long last_processed_adaptation_time = -1L;//initialization
|
||||
|
||||
|
||||
public DetectorSubcomponent(CharacterizedThread.CharacterizedThreadRunMode characterized_thread_run_mode) {
|
||||
public DetectorSubcomponent(String application_name, CharacterizedThread.CharacterizedThreadRunMode characterized_thread_run_mode) {
|
||||
super.thread_type = CharacterizedThread.CharacterizedThreadType.slo_bound_running_thread;
|
||||
subcomponent_state = new DetectorSubcomponentState();
|
||||
utilities = new DetectorSubcomponentUtilities();
|
||||
Integer current_detector_id = -1;//initialization
|
||||
Integer current_detector_id;
|
||||
synchronized (detector_integer_id){
|
||||
/*try {
|
||||
detector_integer_id.wait();
|
||||
@ -54,7 +51,7 @@ public class DetectorSubcomponent extends SLOViolationDetectorSubcomponent{
|
||||
}else/*detached mode*/{
|
||||
CharacterizedThread.create_new_thread(new Runnables.SLODetectionEngineRunnable(this), "detector_"+current_detector_id+"_master_thread", true,this);
|
||||
}
|
||||
detector_subcomponents.put(String.valueOf(current_detector_id),this);
|
||||
detector_subcomponents.put(application_name+"_"+current_detector_id,this);
|
||||
}
|
||||
|
||||
public BiFunction<String, String, String> slo_rule_topic_subscriber_function = (topic, message) -> {
|
||||
@ -84,15 +81,6 @@ public class DetectorSubcomponent extends SLOViolationDetectorSubcomponent{
|
||||
//TODO possibly necessary to remove the next adaptation time as it will probably not be possible to start an adaptation during it
|
||||
return topic + ":MSG:" + message;
|
||||
};
|
||||
|
||||
public DetectorSubcomponentUtilities getUtilities() {
|
||||
return utilities;
|
||||
}
|
||||
|
||||
public void setUtilities(DetectorSubcomponentUtilities utilities) {
|
||||
this.utilities = utilities;
|
||||
}
|
||||
|
||||
public static String get_detector_subcomponent_statistics() {
|
||||
return "Currently, the number of active detectors are "+detector_integer_id;
|
||||
}
|
||||
|
@ -22,21 +22,34 @@ import static utility_beans.PredictedMonitoringAttribute.*;
|
||||
public class RealtimeMonitoringAttribute {
|
||||
|
||||
protected String name;
|
||||
private Integer upper_bound;
|
||||
private Integer lower_bound;
|
||||
private CircularFifoQueue<Double> actual_metric_values = new CircularFifoQueue<>(kept_values_per_metric); //the previous actual values of the metric
|
||||
|
||||
private CircularFifoQueue<Double> actual_metric_values = new CircularFifoQueue<Double>(kept_values_per_metric); //the previous actual values of the metric
|
||||
|
||||
public RealtimeMonitoringAttribute(String name, Integer lower_bound, Integer upper_bound){
|
||||
this.name = name;
|
||||
this.lower_bound = lower_bound;
|
||||
this.upper_bound = upper_bound;
|
||||
}
|
||||
|
||||
public RealtimeMonitoringAttribute(String name, Collection<Double> values){
|
||||
this.name = name;
|
||||
values.stream().forEach(x -> actual_metric_values.add(x));
|
||||
this.lower_bound = 0;
|
||||
this.upper_bound = 100;
|
||||
//Equivalent to below: values.stream().forEach(x -> actual_metric_values.add(x));
|
||||
actual_metric_values.addAll(values);
|
||||
}
|
||||
public RealtimeMonitoringAttribute(String name, Double value){
|
||||
this.name = name;
|
||||
this.lower_bound = 0;
|
||||
this.upper_bound = 100;
|
||||
actual_metric_values.add(value);
|
||||
}
|
||||
|
||||
public RealtimeMonitoringAttribute(String name){
|
||||
this.name = name;
|
||||
this.lower_bound = 0;
|
||||
this.upper_bound = 100;
|
||||
}
|
||||
|
||||
public static Double get_metric_value(DetectorSubcomponent detector, String metric_name){
|
||||
@ -88,43 +101,16 @@ public class RealtimeMonitoringAttribute {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public static <T extends Iterable<String>> void initialize_monitoring_attribute_min_values(T metric_names){
|
||||
initialize_attribute_value_hashmap(monitoring_attributes_min_values,metric_names);
|
||||
}
|
||||
|
||||
public static <T extends Iterable<String>> void initialize_monitoring_attribute_max_values(T metric_names){
|
||||
initialize_attribute_value_hashmap(monitoring_attributes_max_values,metric_names);
|
||||
}
|
||||
*/
|
||||
private static <T extends Iterable<String>> void initialize_attribute_value_hashmap(HashMap<String,Double> hashmap ,T metric_names){
|
||||
for (String metric_name: metric_names){
|
||||
hashmap.put(metric_name,0.0);
|
||||
public static <T extends HashMap<String, RealtimeMonitoringAttribute>> void initialize_monitoring_attributes (DetectorSubcomponent detector, T metric_names_bounds){
|
||||
for (String metric_name : metric_names_bounds.keySet()) {
|
||||
detector.getSubcomponent_state().getMonitoring_attributes_statistics().put(metric_name, new
|
||||
MonitoringAttributeStatistics(metric_names_bounds.get(metric_name).lower_bound,metric_names_bounds.get(metric_name).upper_bound));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public static HashMap<String, Double> getMonitoring_attributes_min_values() {
|
||||
return monitoring_attributes_min_values;
|
||||
}
|
||||
|
||||
public static void setMonitoring_attributes_min_values(HashMap<String, Double> monitoring_attributes_min_values) {
|
||||
RealtimeMonitoringAttribute.monitoring_attributes_min_values = monitoring_attributes_min_values;
|
||||
}
|
||||
|
||||
public static HashMap<String, Double> getMonitoring_attributes_max_values() {
|
||||
return monitoring_attributes_max_values;
|
||||
}
|
||||
|
||||
public static void setMonitoring_attributes_max_values(HashMap<String, Double> monitoring_attributes_max_values) {
|
||||
RealtimeMonitoringAttribute.monitoring_attributes_max_values = monitoring_attributes_max_values;
|
||||
}
|
||||
*/
|
||||
public static void update_monitoring_attributes_values_map(DetectorSubcomponent detector, HashMap<String, Double> input_data) {
|
||||
for (HashMap.Entry<String,Double> entry: input_data.entrySet()){
|
||||
update_monitoring_attribute_value(detector, entry.getKey(),entry.getValue());
|
||||
private static <T extends Iterable<String>> void initialize_attribute_value_hashmap(HashMap<String,Double> hashmap ,T metric_names){
|
||||
for (String metric_name: metric_names){
|
||||
hashmap.put(metric_name,0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,5 +130,19 @@ public class RealtimeMonitoringAttribute {
|
||||
this.actual_metric_values = actual_metric_values;
|
||||
}
|
||||
|
||||
public Integer getUpper_bound() {
|
||||
return upper_bound;
|
||||
}
|
||||
|
||||
public void setUpper_bound(Integer upper_bound) {
|
||||
this.upper_bound = upper_bound;
|
||||
}
|
||||
|
||||
public Integer getLower_bound() {
|
||||
return lower_bound;
|
||||
}
|
||||
|
||||
public void setLower_bound(Integer lower_bound) {
|
||||
this.lower_bound = lower_bound;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ import utility_beans.RealtimeMonitoringAttribute;
|
||||
import utility_beans.PredictedMonitoringAttribute;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static configuration.Constants.default_handled_application_name;
|
||||
import static configuration.Constants.roc_limit;
|
||||
import static utility_beans.PredictedMonitoringAttribute.getAttributes_maximum_rate_of_change;
|
||||
import static utility_beans.PredictedMonitoringAttribute.getAttributes_minimum_rate_of_change;
|
||||
@ -23,13 +25,11 @@ import static utility_beans.RealtimeMonitoringAttribute.update_monitoring_attrib
|
||||
|
||||
public class DerivedMonitoringAttributeTests {
|
||||
|
||||
DetectorSubcomponent detector = new DetectorSubcomponent(CharacterizedThread.CharacterizedThreadRunMode.detached);
|
||||
DetectorSubcomponent detector = new DetectorSubcomponent(default_handled_application_name,CharacterizedThread.CharacterizedThreadRunMode.detached);
|
||||
@Test
|
||||
public void roc_calculation_test(){
|
||||
|
||||
RealtimeMonitoringAttribute realtimeMonitoringAttribute = new RealtimeMonitoringAttribute("cpu");
|
||||
|
||||
simple_initialize_0_100_bounded_attributes(detector,Arrays.asList(new String[]{"cpu"}));
|
||||
simple_initialize_0_100_bounded_attributes(detector, List.of("cpu"));
|
||||
update_monitoring_attribute_value(detector,"cpu",0.0);
|
||||
detector.getSubcomponent_state().getMonitoring_attributes_roc_statistics().put("cpu", new MonitoringAttributeStatistics()); //The rate of change of a metric, is a metric which itself should be monitored for its upper bound
|
||||
|
||||
|
@ -17,9 +17,11 @@ import utility_beans.PredictedMonitoringAttribute;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static configuration.Constants.default_handled_application_name;
|
||||
|
||||
|
||||
public class SeverityTests {
|
||||
DetectorSubcomponent detector = new DetectorSubcomponent(CharacterizedThread.CharacterizedThreadRunMode.detached);
|
||||
DetectorSubcomponent detector = new DetectorSubcomponent(default_handled_application_name, CharacterizedThread.CharacterizedThreadRunMode.detached);
|
||||
@Test
|
||||
public void all_metrics_Severity_test_1(){
|
||||
|
||||
|
@ -68,8 +68,8 @@ public class UnboundedMonitoringAttributeTests {
|
||||
*/
|
||||
|
||||
//private String metric_1_name = "custom_metric_1";
|
||||
private static Long targeted_prediction_time = 100000000000L;
|
||||
private DetectorSubcomponent detector = new DetectorSubcomponent(detached);
|
||||
private static final Long targeted_prediction_time = 100000000000L;
|
||||
private final DetectorSubcomponent detector = new DetectorSubcomponent(default_handled_application_name,detached);
|
||||
@Test
|
||||
public void unbounded_monitoring_attribute_test_1() throws IOException, ParseException {
|
||||
unbounded_monitoring_attribute_test_core("src/main/resources/test_v3_custom_metric_1_simple.json","custom_metric_1",new Double[]{20.0,35.0},new Double[]{110.0,130.0},0.0,50,100, 90,10,0.80);
|
||||
@ -105,7 +105,7 @@ public class UnboundedMonitoringAttributeTests {
|
||||
JSONObject rule_json = (JSONObject) new JSONParser().parse(String.join(EMPTY, Files.readAllLines(Paths.get(new File(json_file_name).getAbsolutePath()))));
|
||||
|
||||
ArrayList<SLORule> slo_rules = new ArrayList<>();
|
||||
SLORule slo_rule = new SLORule(rule_json.toJSONString(), new ArrayList<>(Arrays.asList(new String[]{metric_1_name})),detector);
|
||||
SLORule slo_rule = new SLORule(rule_json.toJSONString(), new ArrayList<>(Arrays.asList(metric_1_name)),detector);
|
||||
slo_rules.add(slo_rule);
|
||||
initialize_subrule_and_attribute_associations(slo_rules,new SynchronizedBoolean());
|
||||
|
||||
@ -238,9 +238,7 @@ public class UnboundedMonitoringAttributeTests {
|
||||
metrics.add(custom_metric_1);
|
||||
|
||||
for (MetricConfiguration metric: metrics) {
|
||||
Thread publishing_thread = new Thread(() -> {
|
||||
perpetual_metric_publisher(metric.name,metric.base_metric_value,metric.forecasted_metric_value,metric.confidence_interval,metric.probability, metric_max_value, publish_interval_in_milliseconds);
|
||||
});
|
||||
Thread publishing_thread = new Thread(() -> perpetual_metric_publisher(metric.name,metric.base_metric_value,metric.forecasted_metric_value,metric.confidence_interval,metric.probability, metric_max_value, publish_interval_in_milliseconds));
|
||||
publishing_thread.start();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user