diff --git a/src/main/java/com/microsoft/dhalion/Utils.java b/src/main/java/com/microsoft/dhalion/Utils.java index 857ef2a..b4eb5d1 100644 --- a/src/main/java/com/microsoft/dhalion/Utils.java +++ b/src/main/java/com/microsoft/dhalion/Utils.java @@ -1,20 +1,15 @@ -package com.microsoft.dhalion; - -import java.util.ArrayList; +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ -import static java.awt.SystemColor.text; +package com.microsoft.dhalion; public class Utils { public static String getCompositeName(String... names) { - if (names.length > 0) { - String text = names[0]; - for (int i = 1; i < names.length; i++) { - text = text + "_" + names[i]; - } - return text; - } - return ""; + return names.length > 0 ? String.join("_", names) : ""; } - } diff --git a/src/main/java/com/microsoft/dhalion/detectors/AboveThresholdDetector.java b/src/main/java/com/microsoft/dhalion/detectors/AboveThresholdDetector.java index 9868212..22f5b45 100644 --- a/src/main/java/com/microsoft/dhalion/detectors/AboveThresholdDetector.java +++ b/src/main/java/com/microsoft/dhalion/detectors/AboveThresholdDetector.java @@ -1,33 +1,39 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.detectors; -import com.microsoft.dhalion.Utils; import com.microsoft.dhalion.conf.PolicyConfig; import com.microsoft.dhalion.core.Measurement; import com.microsoft.dhalion.core.MeasurementsTable; import com.microsoft.dhalion.core.MeasurementsTable.SortKey; import com.microsoft.dhalion.core.Symptom; -import javax.inject.Inject; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.logging.Logger; /** * The AboveThreshold Detector evaluates whether the values of a certain metric are above a user-defined * threshold during a time window and in this case returns a symptom. The detector takes as input the metric name, * the threshold and the time window specified as the number of latest checkpoints. It generates a - * SYMPTOM_HIGH_metricName symptom that is parameterized by the metric name. - * + * {@link AboveThresholdDetector}_metricName symptom that is parameterized by the metric name. + *

* For example, if the threshold is set to 90, the number of latest checkpoints is set to 2 and the metric is set to - * CPU_UTILIZATION, then the detector will return a symptom SYMPTOM_HIGH_CPU_UTILIZATION only when the CPU_UTILIZATION - * is above 90 consistently during the last 2 invocations of the policy. By default the number of checkpoints is set - * to 1 which means that the detector considers only the current value when determining whether to return a symptom. + * CPU_UTILIZATION, then the detector will return a symptom AboveThresholdDetector_CPU_UTILIZATION only when the + * CPU_UTILIZATION is above 90 consistently during the last 2 invocations of the policy. By default the number of + * checkpoints is set to 1 which means that the detector considers only the current value when determining whether to + * return a symptom. */ public class AboveThresholdDetector extends Detector { - public static String SYMPTOM_HIGH = AboveThresholdDetector.class.getSimpleName(); - - public static final String HIGH_THRESHOLD_CONF = "AboveThresholdDetector.threshold"; - public static final String ABOVE_THRESHOLD_NO_CHECKPOINTS = "AboveThresholdDetector.noCheckpoints"; + public static final String SYMPTOM_HIGH = AboveThresholdDetector.class.getSimpleName(); + static final String HIGH_THRESHOLD_CONF = "AboveThresholdDetector.threshold"; + static final String ABOVE_THRESHOLD_NO_CHECKPOINTS = "AboveThresholdDetector.noCheckpoints"; private final double highThreshold; private String metricName; @@ -35,38 +41,38 @@ public class AboveThresholdDetector extends Detector { private static final Logger LOG = Logger.getLogger(AboveThresholdDetector.class.getSimpleName()); - - @Inject public AboveThresholdDetector(PolicyConfig policyConfig, String metricName) { - this.highThreshold = (Double) policyConfig.getConfig(Utils.getCompositeName(HIGH_THRESHOLD_CONF, metricName)); - this.noCheckpoints = (Double) policyConfig.getConfig(Utils.getCompositeName(ABOVE_THRESHOLD_NO_CHECKPOINTS, - metricName), 1); + this.highThreshold = (Double) policyConfig.getConfig(String.join("_", HIGH_THRESHOLD_CONF, metricName)); + this.noCheckpoints + = (Double) policyConfig.getConfig(String.join("_", ABOVE_THRESHOLD_NO_CHECKPOINTS, metricName), 1); this.metricName = metricName; } @Override public Collection detect(Collection measurements) { - ArrayList result = new ArrayList<>(); - if (measurements.size() > 0) { - MeasurementsTable measurementsTable = context.measurements().type(metricName).sort(false, SortKey.TIME_STAMP); - Collection aboveThresholdAssignments = new ArrayList(); - for (String component : measurementsTable.uniqueComponents()) { - MeasurementsTable componentData = measurementsTable.component(component); - for (String instance : componentData.uniqueInstances()) { - MeasurementsTable instanceData = measurementsTable.instance(instance).last((int) noCheckpoints); - if (instanceData.valueBetween(highThreshold, Double.MAX_VALUE).size() == noCheckpoints) { - LOG.fine(String.format("Instance %s has values above the limit for the last %s checkpoints", instance, - noCheckpoints)); - aboveThresholdAssignments.add(instance); - } + if (measurements.isEmpty()) { + return Collections.emptyList(); + } + + Collection assignments = new ArrayList<>(); + MeasurementsTable measurementsTable = context.measurements().type(metricName).sort(false, SortKey.TIME_STAMP); + for (String component : measurementsTable.uniqueComponents()) { + MeasurementsTable componentData = measurementsTable.component(component); + for (String instance : componentData.uniqueInstances()) { + MeasurementsTable instanceData = componentData.instance(instance).last((int) noCheckpoints); + if (instanceData.valueBetween(highThreshold, Double.MAX_VALUE).size() == noCheckpoints) { + LOG.fine(String.format("Instance %s has values above the limit (%s) for the last %s checkpoints", + instance, highThreshold, noCheckpoints)); + assignments.add(instance); } } - if (aboveThresholdAssignments.size() > 0) { - Symptom s = new Symptom(Utils.getCompositeName(SYMPTOM_HIGH, metricName), context.checkpoint(), - aboveThresholdAssignments); - result.add(s); - } } - return result; + + if (assignments.isEmpty()) { + return Collections.emptyList(); + } + + Symptom s = new Symptom(String.join("_", SYMPTOM_HIGH, metricName), context.checkpoint(), assignments); + return Collections.singletonList(s); } } diff --git a/src/main/java/com/microsoft/dhalion/detectors/BelowThresholdDetector.java b/src/main/java/com/microsoft/dhalion/detectors/BelowThresholdDetector.java index cd97b1f..e4e99da 100644 --- a/src/main/java/com/microsoft/dhalion/detectors/BelowThresholdDetector.java +++ b/src/main/java/com/microsoft/dhalion/detectors/BelowThresholdDetector.java @@ -1,33 +1,40 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.detectors; -import com.microsoft.dhalion.Utils; import com.microsoft.dhalion.conf.PolicyConfig; import com.microsoft.dhalion.core.Measurement; import com.microsoft.dhalion.core.MeasurementsTable; import com.microsoft.dhalion.core.MeasurementsTable.SortKey; import com.microsoft.dhalion.core.Symptom; -import javax.inject.Inject; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.logging.Logger; /** * The BelowThreshold Detector evaluates whether the values of a certain metric are below a user-defined * threshold during a time window and in this case returns a symptom. The detector takes as input the metric name, * the threshold and the time window specified as the number of latest checkpoints. It generates a - * SYMPTOM_LOW_metricName symptom that is parameterized by the metric name. + * {@link BelowThresholdDetector}_metricName symptom that is parameterized by the metric name. *

* For example, if the threshold is set to 10, the number of latest checkpoints is set to 2 and the metric is set to - * CPU_UTILIZATION, then the detector will return a symptom SYMPTOM_LOW_CPU_UTILIZATION only when the CPU_UTILIZATION - * is below 10 consistently during the last 2 invocations of the policy. By default the number of checkpoints is set - * to 1 which means that the detector considers only the current value when determining whether to return a symptom. + * CPU_UTILIZATION, then the detector will return a symptom {@link BelowThresholdDetector}_CPU_UTILIZATION only when + * the CPU_UTILIZATION is below 10 consistently during the last 2 invocations of the policy. By default the number of + * checkpoints is set to 1 which means that the detector considers only the current value when determining whether to + * return a symptom. */ public class BelowThresholdDetector extends Detector { - public static String SYMPTOM_LOW = BelowThresholdDetector.class.getSimpleName(); + public static final String SYMPTOM_LOW = BelowThresholdDetector.class.getSimpleName(); - public static final String LOW_THRESHOLD_CONF = "BelowThresholdDetector.threshold"; - public static final String BELOW_THRESHOLD_NO_CHECKPOINTS = "BelowThresholdDetector.noCheckpoints"; + static final String LOW_THRESHOLD_CONF = "BelowThresholdDetector.threshold"; + static final String BELOW_THRESHOLD_NO_CHECKPOINTS = "BelowThresholdDetector.noCheckpoints"; private final double lowThreshold; private String metricName; @@ -35,37 +42,38 @@ public class BelowThresholdDetector extends Detector { private static final Logger LOG = Logger.getLogger(BelowThresholdDetector.class.getSimpleName()); - @Inject public BelowThresholdDetector(PolicyConfig policyConfig, String metricName) { - this.lowThreshold = (Double) policyConfig.getConfig(Utils.getCompositeName(LOW_THRESHOLD_CONF, metricName)); - this.noCheckpoints = (Double) policyConfig.getConfig(Utils.getCompositeName(BELOW_THRESHOLD_NO_CHECKPOINTS, - metricName), 1); + this.lowThreshold = (Double) policyConfig.getConfig(String.join("_", LOW_THRESHOLD_CONF, metricName)); + this.noCheckpoints + = (Double) policyConfig.getConfig(String.join("_", BELOW_THRESHOLD_NO_CHECKPOINTS, metricName), 1); this.metricName = metricName; } @Override public Collection detect(Collection measurements) { - ArrayList result = new ArrayList<>(); - if (measurements.size() > 0) { - MeasurementsTable measurementsTable = context.measurements().type(metricName).sort(false, SortKey.TIME_STAMP); - Collection belowThresholdAssignments = new ArrayList(); - for (String component : measurementsTable.uniqueComponents()) { - MeasurementsTable componentData = measurementsTable.component(component); - for (String instance : componentData.uniqueInstances()) { - MeasurementsTable instanceData = measurementsTable.instance(instance).last((int) noCheckpoints); - if (instanceData.valueBetween(Double.MIN_VALUE, lowThreshold).size() == noCheckpoints) { - LOG.fine(String.format("Instance %s has values below the limit for the last %s checkpoints", instance, - noCheckpoints)); - belowThresholdAssignments.add(instance); - } + if (measurements.isEmpty()) { + return Collections.emptyList(); + } + + MeasurementsTable measurementsTable = context.measurements().type(metricName).sort(false, SortKey.TIME_STAMP); + Collection assignments = new ArrayList<>(); + for (String component : measurementsTable.uniqueComponents()) { + MeasurementsTable componentData = measurementsTable.component(component); + for (String instance : componentData.uniqueInstances()) { + MeasurementsTable instanceData = componentData.instance(instance).last((int) noCheckpoints); + if (instanceData.valueBetween(Double.MIN_VALUE, lowThreshold).size() == noCheckpoints) { + LOG.fine(String.format("Instance %s has values below the limit %s for the last %s checkpoints", + instance, lowThreshold, noCheckpoints)); + assignments.add(instance); } } - if (belowThresholdAssignments.size() > 0) { - Symptom s = new Symptom(Utils.getCompositeName(SYMPTOM_LOW, metricName), context.checkpoint(), - belowThresholdAssignments); - result.add(s); - } } - return result; + + if (assignments.isEmpty()) { + return Collections.emptyList(); + } + + Symptom s = new Symptom(String.join("_", SYMPTOM_LOW, metricName), context.checkpoint(), assignments); + return Collections.singletonList(s); } } diff --git a/src/main/java/com/microsoft/dhalion/detectors/Detector.java b/src/main/java/com/microsoft/dhalion/detectors/Detector.java index bbdd93c..52f4019 100644 --- a/src/main/java/com/microsoft/dhalion/detectors/Detector.java +++ b/src/main/java/com/microsoft/dhalion/detectors/Detector.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.detectors; import com.microsoft.dhalion.api.IDetector; @@ -11,5 +18,4 @@ public class Detector implements IDetector { public void initialize(ExecutionContext context) { this.context = context; } - } diff --git a/src/main/java/com/microsoft/dhalion/examples/AlertPolicy.java b/src/main/java/com/microsoft/dhalion/examples/AlertPolicy.java index 457cc73..5670285 100644 --- a/src/main/java/com/microsoft/dhalion/examples/AlertPolicy.java +++ b/src/main/java/com/microsoft/dhalion/examples/AlertPolicy.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.microsoft.dhalion.api.IHealthPolicy; diff --git a/src/main/java/com/microsoft/dhalion/examples/AlertResolver.java b/src/main/java/com/microsoft/dhalion/examples/AlertResolver.java index 029d008..7b4e7d7 100644 --- a/src/main/java/com/microsoft/dhalion/examples/AlertResolver.java +++ b/src/main/java/com/microsoft/dhalion/examples/AlertResolver.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.microsoft.dhalion.api.IResolver; diff --git a/src/main/java/com/microsoft/dhalion/examples/CSVMetricsProvider.java b/src/main/java/com/microsoft/dhalion/examples/CSVMetricsProvider.java index bc61b34..f893970 100644 --- a/src/main/java/com/microsoft/dhalion/examples/CSVMetricsProvider.java +++ b/src/main/java/com/microsoft/dhalion/examples/CSVMetricsProvider.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.microsoft.dhalion.api.MetricsProvider; diff --git a/src/main/java/com/microsoft/dhalion/examples/MetricName.java b/src/main/java/com/microsoft/dhalion/examples/MetricName.java index a5a8ad8..1685561 100644 --- a/src/main/java/com/microsoft/dhalion/examples/MetricName.java +++ b/src/main/java/com/microsoft/dhalion/examples/MetricName.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; /** diff --git a/src/main/java/com/microsoft/dhalion/examples/NodeStat.java b/src/main/java/com/microsoft/dhalion/examples/NodeStat.java index d964df2..ce15810 100644 --- a/src/main/java/com/microsoft/dhalion/examples/NodeStat.java +++ b/src/main/java/com/microsoft/dhalion/examples/NodeStat.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.google.common.annotations.VisibleForTesting; diff --git a/src/main/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoser.java b/src/main/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoser.java index 611c7cd..2bf1e95 100644 --- a/src/main/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoser.java +++ b/src/main/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoser.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.microsoft.dhalion.Utils; diff --git a/src/main/java/com/microsoft/dhalion/sensors/BasicSensor.java b/src/main/java/com/microsoft/dhalion/sensors/BasicSensor.java index da6db49..0858697 100644 --- a/src/main/java/com/microsoft/dhalion/sensors/BasicSensor.java +++ b/src/main/java/com/microsoft/dhalion/sensors/BasicSensor.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.sensors; import com.microsoft.dhalion.api.ISensor; diff --git a/src/test/java/com/microsoft/dhalion/detectors/AboveThresholdDetectorTest.java b/src/test/java/com/microsoft/dhalion/detectors/AboveThresholdDetectorTest.java index 7c32d4b..04ea2ce 100644 --- a/src/test/java/com/microsoft/dhalion/detectors/AboveThresholdDetectorTest.java +++ b/src/test/java/com/microsoft/dhalion/detectors/AboveThresholdDetectorTest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.detectors; import com.microsoft.dhalion.Utils; diff --git a/src/test/java/com/microsoft/dhalion/detectors/BelowThresholdDetectorTest.java b/src/test/java/com/microsoft/dhalion/detectors/BelowThresholdDetectorTest.java index a497bf8..10d5c39 100644 --- a/src/test/java/com/microsoft/dhalion/detectors/BelowThresholdDetectorTest.java +++ b/src/test/java/com/microsoft/dhalion/detectors/BelowThresholdDetectorTest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.detectors; import com.microsoft.dhalion.Utils; diff --git a/src/test/java/com/microsoft/dhalion/examples/CSVMetricsProviderTest.java b/src/test/java/com/microsoft/dhalion/examples/CSVMetricsProviderTest.java index 436f60f..11ecf44 100644 --- a/src/test/java/com/microsoft/dhalion/examples/CSVMetricsProviderTest.java +++ b/src/test/java/com/microsoft/dhalion/examples/CSVMetricsProviderTest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.microsoft.dhalion.conf.Config; diff --git a/src/test/java/com/microsoft/dhalion/examples/NodeStatTest.java b/src/test/java/com/microsoft/dhalion/examples/NodeStatTest.java index 336ab35..76b23d9 100644 --- a/src/test/java/com/microsoft/dhalion/examples/NodeStatTest.java +++ b/src/test/java/com/microsoft/dhalion/examples/NodeStatTest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.microsoft.dhalion.core.Measurement; diff --git a/src/test/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoserTest.java b/src/test/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoserTest.java index 5aeeb6e..0d6c4cb 100644 --- a/src/test/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoserTest.java +++ b/src/test/java/com/microsoft/dhalion/examples/UncommonUtilizationDiagnoserTest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.examples; import com.microsoft.dhalion.Utils; diff --git a/src/test/java/com/microsoft/dhalion/sensors/BasicSensorTest.java b/src/test/java/com/microsoft/dhalion/sensors/BasicSensorTest.java index 9934c33..53974e3 100644 --- a/src/test/java/com/microsoft/dhalion/sensors/BasicSensorTest.java +++ b/src/test/java/com/microsoft/dhalion/sensors/BasicSensorTest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This program is made available under the terms of the MIT License. + * See the LICENSE file in the project root for more information. + */ + package com.microsoft.dhalion.sensors; import com.microsoft.dhalion.api.MetricsProvider;