-
Notifications
You must be signed in to change notification settings - Fork 25k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ML] Add custom rule parameters to force time shift (#110974)
This PR extends the schema of the detection rule API by adding a new parametrizable action `force_time_shift` and a new property `params` to hold the parameter `total_shift_amount` as signed long in seconds to control the behavior of the time shift. A valid schema looks like this: ```http POST _ml/anomaly_detectors/my_job/_update { "detectors": { "detector_index": 0, "custom_rules": [ // update the detector with a custom rule that forces a time shift of 1 hour back starting now { "actions": [ "force_time_shift" ], "params": { "force_time_shift": { "time_shift_amount": 3600} } }, "conditions": [{ "applies_to": "time", "operator": "gt", "value": "now" }, { "applies_to": "time", "operator": "lt", "value": "now+bucket_span" }, ] }, ... ``` Execution of the detection rule action `force_time_shift` will shift the time inside the anomaly detector by a specified amount. This is useful, e.g. to quickly adapt to the daylight saving time events that are known beforehand. This PR is accompanied by changes in Kibana elastic/kibana#188710 and the native ml-cpp code elastic/ml-cpp#2690. The integration tests between Java and C++ parts of the force-time shift action will be implemented in a separate PR.
- Loading branch information
Showing
9 changed files
with
277 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 110974 | ||
summary: Add custom rule parameters to force time shift | ||
area: Machine Learning | ||
type: enhancement | ||
issues: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/config/RuleParams.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.core.ml.job.config; | ||
|
||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.common.io.stream.StreamOutput; | ||
import org.elasticsearch.common.io.stream.Writeable; | ||
import org.elasticsearch.xcontent.ConstructingObjectParser; | ||
import org.elasticsearch.xcontent.ParseField; | ||
import org.elasticsearch.xcontent.ToXContentObject; | ||
import org.elasticsearch.xcontent.XContentBuilder; | ||
|
||
import java.io.IOException; | ||
import java.util.Objects; | ||
|
||
public class RuleParams implements ToXContentObject, Writeable { | ||
|
||
public static final ParseField RULE_PARAMS_FIELD = new ParseField("params"); | ||
public static final ParseField FORCE_TIME_SHIFT_FIELD = new ParseField("force_time_shift"); | ||
|
||
// These parsers follow the pattern that metadata is parsed leniently (to allow for enhancements), whilst config is parsed strictly | ||
public static final ConstructingObjectParser<RuleParams, Void> LENIENT_PARSER = createParser(true); | ||
public static final ConstructingObjectParser<RuleParams, Void> STRICT_PARSER = createParser(false); | ||
|
||
public static ConstructingObjectParser<RuleParams, Void> createParser(boolean ignoreUnknownFields) { | ||
ConstructingObjectParser<RuleParams, Void> parser = new ConstructingObjectParser<>( | ||
RULE_PARAMS_FIELD.getPreferredName(), | ||
ignoreUnknownFields, | ||
a -> new RuleParams((RuleParamsForForceTimeShift) a[0]) | ||
); | ||
|
||
parser.declareObject( | ||
ConstructingObjectParser.optionalConstructorArg(), | ||
RuleParamsForForceTimeShift.LENIENT_PARSER, | ||
FORCE_TIME_SHIFT_FIELD | ||
); | ||
return parser; | ||
} | ||
|
||
private final RuleParamsForForceTimeShift forceTimeShift; | ||
|
||
public RuleParams() { | ||
this.forceTimeShift = null; | ||
} | ||
|
||
public RuleParams(RuleParamsForForceTimeShift forceTimeShift) { | ||
this.forceTimeShift = forceTimeShift; | ||
} | ||
|
||
public RuleParams(StreamInput in) throws IOException { | ||
// initialize optional forceTimeShift from in | ||
forceTimeShift = in.readOptionalWriteable(RuleParamsForForceTimeShift::new); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
// write optional forceTimeShift to out | ||
out.writeOptionalWriteable(forceTimeShift); | ||
} | ||
|
||
boolean isEmpty() { | ||
return forceTimeShift == null; | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
builder.startObject(); | ||
if (forceTimeShift != null) { | ||
builder.field(FORCE_TIME_SHIFT_FIELD.getPreferredName(), forceTimeShift); | ||
} | ||
builder.endObject(); | ||
return builder; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
|
||
if (obj instanceof RuleParams == false) { | ||
return false; | ||
} | ||
|
||
RuleParams other = (RuleParams) obj; | ||
return Objects.equals(forceTimeShift, other.forceTimeShift); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(forceTimeShift); | ||
} | ||
|
||
public RuleParamsForForceTimeShift getForceTimeShift() { | ||
return forceTimeShift; | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
...src/main/java/org/elasticsearch/xpack/core/ml/job/config/RuleParamsForForceTimeShift.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.core.ml.job.config; | ||
|
||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.common.io.stream.StreamOutput; | ||
import org.elasticsearch.common.io.stream.Writeable; | ||
import org.elasticsearch.xcontent.ConstructingObjectParser; | ||
import org.elasticsearch.xcontent.ParseField; | ||
import org.elasticsearch.xcontent.ToXContentObject; | ||
import org.elasticsearch.xcontent.XContentBuilder; | ||
|
||
import java.io.IOException; | ||
|
||
public class RuleParamsForForceTimeShift implements ToXContentObject, Writeable { | ||
public static final ParseField TYPE_FIELD = new ParseField("force_time_shift_params"); | ||
public static final ParseField TIME_SHIFT_AMOUNT_FIELD = new ParseField("time_shift_amount"); | ||
|
||
public static final ConstructingObjectParser<RuleParamsForForceTimeShift, Void> LENIENT_PARSER = createParser(true); | ||
public static final ConstructingObjectParser<RuleParamsForForceTimeShift, Void> STRICT_PARSER = createParser(false); | ||
|
||
private static ConstructingObjectParser<RuleParamsForForceTimeShift, Void> createParser(boolean ignoreUnknownFields) { | ||
ConstructingObjectParser<RuleParamsForForceTimeShift, Void> parser = new ConstructingObjectParser<>( | ||
TYPE_FIELD.getPreferredName(), | ||
ignoreUnknownFields, | ||
a -> new RuleParamsForForceTimeShift((Long) a[0]) | ||
); | ||
parser.declareLong(ConstructingObjectParser.constructorArg(), TIME_SHIFT_AMOUNT_FIELD); | ||
return parser; | ||
} | ||
|
||
private final long timeShiftAmount; | ||
|
||
public RuleParamsForForceTimeShift(long timeShiftAmount) { | ||
this.timeShiftAmount = timeShiftAmount; | ||
} | ||
|
||
public RuleParamsForForceTimeShift(StreamInput in) throws IOException { | ||
timeShiftAmount = in.readLong(); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
out.writeLong(timeShiftAmount); | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
builder.startObject(); | ||
builder.field(TIME_SHIFT_AMOUNT_FIELD.getPreferredName(), timeShiftAmount); | ||
builder.endObject(); | ||
return builder; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
|
||
if (obj instanceof RuleParamsForForceTimeShift == false) { | ||
return false; | ||
} | ||
|
||
RuleParamsForForceTimeShift other = (RuleParamsForForceTimeShift) obj; | ||
return timeShiftAmount == other.timeShiftAmount; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Long.hashCode(timeShiftAmount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.