This is an automated email from the ASF dual-hosted git repository.
jihao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 8cadaec [TE] Anomaly detection for monthly data (#3949)
8cadaec is described below
commit 8cadaecfbc3407358c60d7e4d25106e4d3562c3a
Author: Jihao Zhang <[email protected]>
AuthorDate: Mon Mar 11 15:37:08 2019 -0700
[TE] Anomaly detection for monthly data (#3949)
---
.../pinot/thirdeye/detection/DetectionUtils.java | 23 ++++++++--
.../components/AbsoluteChangeRuleDetector.java | 18 +++++++-
.../components/PercentageChangeRuleDetector.java | 49 ++++++++++++++--------
.../components/ThresholdRuleDetector.java | 20 +++++++--
.../spec/AbsoluteChangeRuleDetectorSpec.java | 12 ++++++
.../spec/PercentageChangeRuleDetectorSpec.java | 12 ++++++
.../detection/spec/ThresholdRuleDetectorSpec.java | 10 +++++
.../PercentageChangeRuleDetectorTest.java | 21 ++++++++++
.../components/ThresholdRuleDetectorTest.java | 28 +++++++++++++
9 files changed, 166 insertions(+), 27 deletions(-)
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionUtils.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionUtils.java
index ddae32b..50e4a98 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionUtils.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionUtils.java
@@ -27,6 +27,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.pinot.thirdeye.common.dimension.DimensionMap;
+import org.apache.pinot.thirdeye.common.time.TimeGranularity;
import org.apache.pinot.thirdeye.dataframe.BooleanSeries;
import org.apache.pinot.thirdeye.dataframe.DataFrame;
import org.apache.pinot.thirdeye.dataframe.LongSeries;
@@ -42,6 +43,7 @@ import
org.apache.pinot.thirdeye.detection.spi.model.TimeSeries;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Period;
+import org.joda.time.PeriodType;
import static org.apache.pinot.thirdeye.dataframe.util.DataFrameUtils.*;
@@ -84,10 +86,11 @@ public class DetectionUtils {
* @param df time series with COL_TIME and at least one boolean value series
* @param seriesName name of the value series
* @param endTime end time of this detection window
+ * @param monitoringGranularityPeriod the monitoring granularity period
* @param dataset dataset config for the metric
* @return list of anomalies
*/
- public static List<MergedAnomalyResultDTO> makeAnomalies(MetricSlice slice,
DataFrame df, String seriesName, long endTime, DatasetConfigDTO dataset) {
+ public static List<MergedAnomalyResultDTO> makeAnomalies(MetricSlice slice,
DataFrame df, String seriesName, long endTime, Period
monitoringGranularityPeriod, DatasetConfigDTO dataset) {
if (df.isEmpty()) {
return Collections.emptyList();
}
@@ -128,12 +131,11 @@ public class DetectionUtils {
// guess-timate of next time series timestamp
if (dataset != null) {
- Period period = dataset.bucketTimeGranularity().toPeriod();
DateTimeZone timezone = DateTimeZone.forID(dataset.getTimezone());
long lastTimestamp = sTime.getLong(sTime.size() - 1);
- end = new DateTime(lastTimestamp, timezone).plus(period).getMillis();
+ end = new DateTime(lastTimestamp,
timezone).plus(monitoringGranularityPeriod).getMillis();
}
// truncate at analysis end time
@@ -202,4 +204,19 @@ public class DetectionUtils {
}
return
baselineProvider.computePredictedTimeSeries(MetricSlice.from(metricId, start,
end, filters));
}
+
+ /**
+ * Get the joda period for a monitoring granularity
+ * @param monitoringGranularity
+ */
+ public static Period getMonitoringGranularityPeriod(String
monitoringGranularity, DatasetConfigDTO datasetConfigDTO) {
+ if
(monitoringGranularity.equals(MetricSlice.NATIVE_GRANULARITY.toAggregationGranularityString()))
{
+ return datasetConfigDTO.bucketTimeGranularity().toPeriod();
+ }
+ if (monitoringGranularity.equals("1_MONTHS")) {
+ return new Period(0,1,0,0,0,0,0,0, PeriodType.months());
+ }
+ return TimeGranularity.fromString(monitoringGranularity).toPeriod();
+ }
+
}
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/AbsoluteChangeRuleDetector.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/AbsoluteChangeRuleDetector.java
index d2946f4..a5a2ab9 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/AbsoluteChangeRuleDetector.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/AbsoluteChangeRuleDetector.java
@@ -19,6 +19,7 @@
package org.apache.pinot.thirdeye.detection.components;
+import org.apache.pinot.thirdeye.common.time.TimeGranularity;
import org.apache.pinot.thirdeye.dashboard.resources.v2.BaselineParsingUtils;
import org.apache.pinot.thirdeye.dataframe.BooleanSeries;
import org.apache.pinot.thirdeye.dataframe.DataFrame;
@@ -42,6 +43,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.joda.time.Interval;
+import org.joda.time.Period;
import static org.apache.pinot.thirdeye.dataframe.util.DataFrameUtils.*;
@@ -62,6 +64,9 @@ public class AbsoluteChangeRuleDetector implements
AnomalyDetector<AbsoluteChang
private InputDataFetcher dataFetcher;
private Baseline baseline;
private Pattern pattern;
+ private String monitoringGranularity;
+ private TimeGranularity timeGranularity;
+
private static final String COL_CURR = "current";
private static final String COL_BASE = "baseline";
private static final String COL_ANOMALY = "anomaly";
@@ -72,7 +77,7 @@ public class AbsoluteChangeRuleDetector implements
AnomalyDetector<AbsoluteChang
@Override
public List<MergedAnomalyResultDTO> runDetection(Interval window, String
metricUrn) {
MetricEntity me = MetricEntity.fromURN(metricUrn);
- MetricSlice slice = MetricSlice.from(me.getId(), window.getStartMillis(),
window.getEndMillis(), me.getFilters());
+ MetricSlice slice = MetricSlice.from(me.getId(), window.getStartMillis(),
window.getEndMillis(), me.getFilters(), timeGranularity);
List<MetricSlice> slices = new ArrayList<>(this.baseline.scatter(slice));
slices.add(slice);
InputData data = this.dataFetcher.fetchData(new
InputDataSpec().withTimeseriesSlices(slices).withMetricIdsForDataset(
@@ -100,7 +105,8 @@ public class AbsoluteChangeRuleDetector implements
AnomalyDetector<AbsoluteChang
// make anomalies
DatasetConfigDTO datasetConfig =
data.getDatasetForMetricId().get(me.getId());
- return DetectionUtils.makeAnomalies(slice, df, COL_ANOMALY,
window.getEndMillis(), datasetConfig);
+ return DetectionUtils.makeAnomalies(slice, df, COL_ANOMALY,
window.getEndMillis(),
+ DetectionUtils.getMonitoringGranularityPeriod(monitoringGranularity,
datasetConfig), datasetConfig);
}
@Override
@@ -111,5 +117,13 @@ public class AbsoluteChangeRuleDetector implements
AnomalyDetector<AbsoluteChang
String offset = spec.getOffset();
this.baseline = BaselineParsingUtils.parseOffset(offset, timezone);
this.pattern = Pattern.valueOf(spec.getPattern().toUpperCase());
+
+ this.monitoringGranularity = spec.getMonitoringGranularity();
+ if (this.monitoringGranularity.equals("1_MONTHS")) {
+ this.timeGranularity = MetricSlice.NATIVE_GRANULARITY;
+ } else {
+ this.timeGranularity =
TimeGranularity.fromString(spec.getMonitoringGranularity());
+ }
+
}
}
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetector.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetector.java
index e84220b..5d717fb 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetector.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetector.java
@@ -19,6 +19,7 @@
package org.apache.pinot.thirdeye.detection.components;
+import org.apache.pinot.thirdeye.common.time.TimeGranularity;
import org.apache.pinot.thirdeye.dashboard.resources.v2.BaselineParsingUtils;
import org.apache.pinot.thirdeye.dataframe.BooleanSeries;
import org.apache.pinot.thirdeye.dataframe.DataFrame;
@@ -43,28 +44,28 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.joda.time.Interval;
+import org.joda.time.Period;
+import org.joda.time.PeriodType;
import static org.apache.pinot.thirdeye.dataframe.DoubleSeries.*;
import static org.apache.pinot.thirdeye.dataframe.util.DataFrameUtils.*;
-@Components(title = "Percentage change rule detection",
- type = "PERCENTAGE_RULE",
- tags = {DetectionTag.RULE_DETECTION},
- description = "Computes a multi-week aggregate baseline and compares the
current value "
- + "based on relative change.",
- presentation = {
- @PresentationOption(name = "percentage change", template = "comparing
${offset} is ${pattern} more than ${percentageChange}")
- },
- params = {
- @Param(name = "offset", defaultValue = "wo1w"),
- @Param(name = "percentageChange", placeholder = "value"),
- @Param(name = "pattern", allowableValues = {"up", "down"})
- })
+
+@Components(title = "Percentage change rule detection", type =
"PERCENTAGE_RULE", tags = {
+ DetectionTag.RULE_DETECTION}, description =
+ "Computes a multi-week aggregate baseline and compares the current value "
+ + "based on relative change.", presentation = {
+ @PresentationOption(name = "percentage change", template = "comparing
${offset} is ${pattern} more than ${percentageChange}")}, params = {
+ @Param(name = "offset", defaultValue = "wo1w"), @Param(name =
"percentageChange", placeholder = "value"),
+ @Param(name = "pattern", allowableValues = {"up", "down"})})
public class PercentageChangeRuleDetector implements
AnomalyDetector<PercentageChangeRuleDetectorSpec> {
private double percentageChange;
private InputDataFetcher dataFetcher;
private Baseline baseline;
private Pattern pattern;
+ private String monitoringGranularity;
+ private TimeGranularity timeGranularity;
+
private static final String COL_CURR = "current";
private static final String COL_BASE = "baseline";
private static final String COL_CHANGE = "change";
@@ -75,10 +76,13 @@ public class PercentageChangeRuleDetector implements
AnomalyDetector<PercentageC
@Override
public List<MergedAnomalyResultDTO> runDetection(Interval window, String
metricUrn) {
MetricEntity me = MetricEntity.fromURN(metricUrn);
- MetricSlice slice = MetricSlice.from(me.getId(), window.getStartMillis(),
window.getEndMillis(), me.getFilters());
+ MetricSlice slice =
+ MetricSlice.from(me.getId(), window.getStartMillis(),
window.getEndMillis(), me.getFilters(), timeGranularity);
List<MetricSlice> slices = new ArrayList<>(this.baseline.scatter(slice));
slices.add(slice);
- InputData data = this.dataFetcher.fetchData(new
InputDataSpec().withTimeseriesSlices(slices).withMetricIdsForDataset(Collections.singletonList(slice.getMetricId())));
+
+ InputData data = this.dataFetcher.fetchData(new
InputDataSpec().withTimeseriesSlices(slices)
+
.withMetricIdsForDataset(Collections.singletonList(slice.getMetricId())));
DataFrame dfCurr = data.getTimeseries().get(slice).renameSeries(COL_VALUE,
COL_CURR);
DataFrame dfBase = this.baseline.gather(slice,
data.getTimeseries()).renameSeries(COL_VALUE, COL_BASE);
@@ -98,10 +102,11 @@ public class PercentageChangeRuleDetector implements
AnomalyDetector<PercentageC
// relative change
if (!Double.isNaN(this.percentageChange)) {
// consistent with pattern
- if (pattern.equals(Pattern.UP_OR_DOWN) ) {
+ if (pattern.equals(Pattern.UP_OR_DOWN)) {
df.addSeries(COL_PATTERN, BooleanSeries.fillValues(df.size(), true));
} else {
- df.addSeries(COL_PATTERN, this.pattern.equals(Pattern.UP) ?
df.getDoubles(COL_CHANGE).gt(0) : df.getDoubles(COL_CHANGE).lt(0));
+ df.addSeries(COL_PATTERN,
+ this.pattern.equals(Pattern.UP) ? df.getDoubles(COL_CHANGE).gt(0)
: df.getDoubles(COL_CHANGE).lt(0));
}
df.addSeries(COL_CHANGE_VIOLATION,
df.getDoubles(COL_CHANGE).abs().gte(this.percentageChange));
df.mapInPlace(BooleanSeries.ALL_TRUE, COL_ANOMALY, COL_PATTERN,
COL_CHANGE_VIOLATION);
@@ -109,7 +114,8 @@ public class PercentageChangeRuleDetector implements
AnomalyDetector<PercentageC
// anomalies
DatasetConfigDTO datasetConfig =
data.getDatasetForMetricId().get(me.getId());
- return DetectionUtils.makeAnomalies(slice, df, COL_ANOMALY,
window.getEndMillis(), datasetConfig);
+ return DetectionUtils.makeAnomalies(slice, df, COL_ANOMALY,
window.getEndMillis(),
+ DetectionUtils.getMonitoringGranularityPeriod(monitoringGranularity,
datasetConfig), datasetConfig);
}
@Override
@@ -120,5 +126,12 @@ public class PercentageChangeRuleDetector implements
AnomalyDetector<PercentageC
String offset = spec.getOffset();
this.baseline = BaselineParsingUtils.parseOffset(offset, timezone);
this.pattern = Pattern.valueOf(spec.getPattern().toUpperCase());
+
+ this.monitoringGranularity = spec.getMonitoringGranularity();
+ if (this.monitoringGranularity.equals("1_MONTHS")) {
+ this.timeGranularity = MetricSlice.NATIVE_GRANULARITY;
+ } else {
+ this.timeGranularity =
TimeGranularity.fromString(spec.getMonitoringGranularity());
+ }
}
}
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetector.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetector.java
index 63a5604..236e457 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetector.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetector.java
@@ -19,6 +19,9 @@
package org.apache.pinot.thirdeye.detection.components;
+import java.util.Collections;
+import java.util.List;
+import org.apache.pinot.thirdeye.common.time.TimeGranularity;
import org.apache.pinot.thirdeye.dataframe.BooleanSeries;
import org.apache.pinot.thirdeye.dataframe.DataFrame;
import org.apache.pinot.thirdeye.dataframe.util.MetricSlice;
@@ -35,9 +38,8 @@ import
org.apache.pinot.thirdeye.detection.spi.components.AnomalyDetector;
import org.apache.pinot.thirdeye.detection.spi.model.InputData;
import org.apache.pinot.thirdeye.detection.spi.model.InputDataSpec;
import org.apache.pinot.thirdeye.rootcause.impl.MetricEntity;
-import java.util.Collections;
-import java.util.List;
import org.joda.time.Interval;
+import org.joda.time.Period;
import static org.apache.pinot.thirdeye.dataframe.util.DataFrameUtils.*;
@@ -54,12 +56,14 @@ public class ThresholdRuleDetector implements
AnomalyDetector<ThresholdRuleDetec
private double min;
private double max;
private InputDataFetcher dataFetcher;
+ private String monitoringGranularity;
+ private TimeGranularity timeGranularity;
@Override
public List<MergedAnomalyResultDTO> runDetection(Interval window, String
metricUrn) {
MetricEntity me = MetricEntity.fromURN(metricUrn);
Long endTime = window.getEndMillis();
- MetricSlice slice = MetricSlice.from(me.getId(), window.getStartMillis(),
endTime, me.getFilters());
+ MetricSlice slice = MetricSlice.from(me.getId(), window.getStartMillis(),
endTime, me.getFilters(), timeGranularity);
InputData data = this.dataFetcher.fetchData(
new
InputDataSpec().withTimeseriesSlices(Collections.singletonList(slice))
@@ -83,7 +87,8 @@ public class ThresholdRuleDetector implements
AnomalyDetector<ThresholdRuleDetec
df.mapInPlace(BooleanSeries.HAS_TRUE, COL_ANOMALY, COL_TOO_HIGH,
COL_TOO_LOW);
DatasetConfigDTO datasetConfig =
data.getDatasetForMetricId().get(me.getId());
- return DetectionUtils.makeAnomalies(slice, df, COL_ANOMALY, endTime,
datasetConfig);
+ return DetectionUtils.makeAnomalies(slice, df, COL_ANOMALY, endTime,
+ DetectionUtils.getMonitoringGranularityPeriod(monitoringGranularity,
datasetConfig), datasetConfig);
}
@Override
@@ -91,5 +96,12 @@ public class ThresholdRuleDetector implements
AnomalyDetector<ThresholdRuleDetec
this.min = spec.getMin();
this.max = spec.getMax();
this.dataFetcher = dataFetcher;
+ this.monitoringGranularity = spec.getMonitoringGranularity();
+ if (this.monitoringGranularity.equals("1_MONTHS")) {
+ this.timeGranularity = MetricSlice.NATIVE_GRANULARITY;
+ } else {
+ this.timeGranularity =
TimeGranularity.fromString(spec.getMonitoringGranularity());
+ }
+
}
}
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/AbsoluteChangeRuleDetectorSpec.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/AbsoluteChangeRuleDetectorSpec.java
index 3d02492..601d36d 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/AbsoluteChangeRuleDetectorSpec.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/AbsoluteChangeRuleDetectorSpec.java
@@ -19,11 +19,23 @@
package org.apache.pinot.thirdeye.detection.spec;
+import org.apache.pinot.thirdeye.dataframe.util.MetricSlice;
+
+
public class AbsoluteChangeRuleDetectorSpec extends AbstractSpec {
private double absoluteChange = Double.NaN;
private String offset = "wo1w";
private String timezone = "UTC";
private String pattern = "UP_OR_DOWN";
+ private String monitoringGranularity =
MetricSlice.NATIVE_GRANULARITY.toAggregationGranularityString(); // use native
granularity by default
+
+ public String getMonitoringGranularity() {
+ return monitoringGranularity;
+ }
+
+ public void setMonitoringGranularity(String monitoringGranularity) {
+ this.monitoringGranularity = monitoringGranularity;
+ }
public double getAbsoluteChange() {
return absoluteChange;
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/PercentageChangeRuleDetectorSpec.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/PercentageChangeRuleDetectorSpec.java
index 25a9079..694699d 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/PercentageChangeRuleDetectorSpec.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/PercentageChangeRuleDetectorSpec.java
@@ -19,11 +19,23 @@
package org.apache.pinot.thirdeye.detection.spec;
+import org.apache.pinot.thirdeye.dataframe.util.MetricSlice;
+
+
public class PercentageChangeRuleDetectorSpec extends AbstractSpec {
private double percentageChange = Double.NaN;
private String offset = "wo1w";
private String timezone = "UTC";
private String pattern = "UP_OR_DOWN";
+ private String monitoringGranularity =
MetricSlice.NATIVE_GRANULARITY.toAggregationGranularityString(); // use native
granularity by default
+
+ public String getMonitoringGranularity() {
+ return monitoringGranularity;
+ }
+
+ public void setMonitoringGranularity(String monitoringGranularity) {
+ this.monitoringGranularity = monitoringGranularity;
+ }
public String getPattern() {
return pattern;
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/ThresholdRuleDetectorSpec.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/ThresholdRuleDetectorSpec.java
index 11b4561..7e706aa 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/ThresholdRuleDetectorSpec.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/spec/ThresholdRuleDetectorSpec.java
@@ -20,12 +20,22 @@
package org.apache.pinot.thirdeye.detection.spec;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import org.apache.pinot.thirdeye.dataframe.util.MetricSlice;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ThresholdRuleDetectorSpec extends AbstractSpec {
private double min = Double.NaN;
private double max = Double.NaN;
+ private String monitoringGranularity =
MetricSlice.NATIVE_GRANULARITY.toAggregationGranularityString(); // use native
granularity by default
+
+ public String getMonitoringGranularity() {
+ return monitoringGranularity;
+ }
+
+ public void setMonitoringGranularity(String monitoringGranularity) {
+ this.monitoringGranularity = monitoringGranularity;
+ }
public double getMin() {
return min;
diff --git
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetectorTest.java
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetectorTest.java
index 7218d08..f52bd23 100644
---
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetectorTest.java
+++
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/PercentageChangeRuleDetectorTest.java
@@ -34,6 +34,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import org.apache.pinot.thirdeye.detection.spec.ThresholdRuleDetectorSpec;
+import org.apache.pinot.thirdeye.detection.spi.components.AnomalyDetector;
import org.joda.time.Interval;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
@@ -70,6 +72,11 @@ public class PercentageChangeRuleDetectorTest {
timeseries.put(MetricSlice.from(1L, 604800000L, 1209600000L), this.data);
timeseries.put(MetricSlice.from(1L, 1209600000L, 1814400000L), this.data);
timeseries.put(MetricSlice.from(1L, 1814400000L, 2419200000L), this.data);
+ timeseries.put(MetricSlice.from(1L, 1546214400000L, 1551312000000L),
+ new DataFrame().addSeries(COL_TIME, 1546214400000L,
1548892800000L).addSeries(COL_VALUE, 100, 200));
+ timeseries.put(MetricSlice.from(1L, 1543536000000L, 1548633600000L),
+ new DataFrame().addSeries(COL_TIME, 1543536000000L, 1546214400000L)
+ .addSeries(COL_VALUE, 100, 100));
this.provider = new MockDataProvider()
.setTimeseries(timeseries)
@@ -148,4 +155,18 @@ public class PercentageChangeRuleDetectorTest {
Assert.assertEquals(anomalies.get(4).getEndTime(), 2325600000L);
}
+ @Test
+ public void testMonthlyDetectionPercentage() {
+ AnomalyDetector percentageRule = new PercentageChangeRuleDetector();
+ PercentageChangeRuleDetectorSpec spec = new
PercentageChangeRuleDetectorSpec();
+ spec.setOffset("mo1m");
+ spec.setPercentageChange(0.4);
+ spec.setMonitoringGranularity("1_MONTHS");
+ percentageRule.init(spec, new DefaultInputDataFetcher(this.provider, -1));
+ List<MergedAnomalyResultDTO> anomalies = percentageRule.runDetection(new
Interval(1546214400000L, 1551312000000L), "thirdeye:metric:1");
+ Assert.assertEquals(anomalies.size(), 1);
+ Assert.assertEquals(anomalies.get(0).getStartTime(), 1548892800000L);
+ Assert.assertEquals(anomalies.get(0).getEndTime(), 1551312000000L);
+ }
+
}
\ No newline at end of file
diff --git
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetectorTest.java
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetectorTest.java
index 1b1a267..51c2ad6 100644
---
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetectorTest.java
+++
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/components/ThresholdRuleDetectorTest.java
@@ -48,6 +48,8 @@ public class ThresholdRuleDetectorTest {
Map<MetricSlice, DataFrame> timeSeries = new HashMap<>();
timeSeries.put(MetricSlice.from(123L, 0, 10),
new DataFrame().addSeries(COL_VALUE, 0, 100, 200, 500,
1000).addSeries(COL_TIME, 0, 2, 4, 6, 8));
+ timeSeries.put(MetricSlice.from(123L, 1546214400000L, 1551398400000L),
+ new DataFrame().addSeries(COL_TIME, 1546214400000L, 1548892800000L,
1551312000000L).addSeries(COL_VALUE, 100, 200, 300));
MetricConfigDTO metricConfigDTO = new MetricConfigDTO();
metricConfigDTO.setId(123L);
@@ -94,4 +96,30 @@ public class ThresholdRuleDetectorTest {
Assert.assertEquals(anomalies.get(1).getEndTime(), 10);
}
+ @Test
+ public void testMonthlyDetectionThreshold() {
+ AnomalyDetector thresholdRule = new ThresholdRuleDetector();
+ ThresholdRuleDetectorSpec spec = new ThresholdRuleDetectorSpec();
+ spec.setMin(200);
+ spec.setMonitoringGranularity("1_MONTHS");
+ thresholdRule.init(spec, new DefaultInputDataFetcher(testDataProvider,
-1));
+ List<MergedAnomalyResultDTO> anomalies = thresholdRule.runDetection(new
Interval(1546214400000L, 1551398400000L), "thirdeye:metric:123");
+ Assert.assertEquals(anomalies.size(), 1);
+ Assert.assertEquals(anomalies.get(0).getStartTime(), 1546214400000L);
+ Assert.assertEquals(anomalies.get(0).getEndTime(), 1548892800000L);
+ }
+
+ @Test
+ public void testMonthlyDetectionThresholdMax() {
+ AnomalyDetector thresholdRule = new ThresholdRuleDetector();
+ ThresholdRuleDetectorSpec spec = new ThresholdRuleDetectorSpec();
+ spec.setMax(200);
+ spec.setMonitoringGranularity("1_MONTHS");
+ thresholdRule.init(spec, new DefaultInputDataFetcher(testDataProvider,
-1));
+ List<MergedAnomalyResultDTO> anomalies = thresholdRule.runDetection(new
Interval(1546214400000L, 1551398400000L), "thirdeye:metric:123");
+ Assert.assertEquals(anomalies.size(), 1);
+ Assert.assertEquals(anomalies.get(0).getStartTime(), 1551312000000L);
+ Assert.assertEquals(anomalies.get(0).getEndTime(), 1551398400000L);
+ }
+
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]