[ML] Configure autodetect with scheduled events (elastic/x-pack-elasticsearch#3521)

Original commit: elastic/x-pack-elasticsearch@e51b70ec69
This commit is contained in:
David Kyle 2018-01-10 12:02:14 +00:00 committed by GitHub
parent 66b187fe17
commit d3d965c8ee
2 changed files with 38 additions and 11 deletions

View File

@ -21,6 +21,7 @@ import org.elasticsearch.xpack.ml.utils.MlStrings;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@ -36,6 +37,9 @@ public class FieldConfigWriter {
private static final String CATEGORIZATION_FIELD_OPTION = " categorizationfield="; private static final String CATEGORIZATION_FIELD_OPTION = " categorizationfield=";
private static final String CATEGORIZATION_FILTER_PREFIX = "categorizationfilter."; private static final String CATEGORIZATION_FILTER_PREFIX = "categorizationfilter.";
private static final String FILTER_PREFIX = "filter."; private static final String FILTER_PREFIX = "filter.";
private static final String SCHEDULED_EVENT_PREFIX = "scheduledevent.";
private static final String SCHEDULED_EVENT_DESCRIPTION_SUFFIX = ".description";
// Note: for the Engine API summarycountfield is currently passed as a // Note: for the Engine API summarycountfield is currently passed as a
// command line option to autodetect rather than in the field config file // command line option to autodetect rather than in the field config file
@ -65,6 +69,7 @@ public class FieldConfigWriter {
writeDetectors(contents); writeDetectors(contents);
writeFilters(contents); writeFilters(contents);
writeScheduledEvents(contents);
writeAsEnumeratedSettings(CATEGORIZATION_FILTER_PREFIX, config.getCategorizationFilters(), writeAsEnumeratedSettings(CATEGORIZATION_FILTER_PREFIX, config.getCategorizationFilters(),
contents, true); contents, true);
@ -78,13 +83,10 @@ public class FieldConfigWriter {
private void writeDetectors(StringBuilder contents) throws IOException { private void writeDetectors(StringBuilder contents) throws IOException {
int counter = 0; int counter = 0;
List<DetectionRule> events = scheduledEvents.stream().map(e -> e.toDetectionRule(config.getBucketSpan()))
.collect(Collectors.toList());
for (Detector detector : config.getDetectors()) { for (Detector detector : config.getDetectors()) {
int detectorId = counter++; int detectorId = counter++;
writeDetectorClause(detectorId, detector, contents); writeDetectorClause(detectorId, detector, contents);
writeDetectorRules(detectorId, detector, events, contents); writeDetectorRules(detectorId, detector, contents);
} }
} }
@ -102,21 +104,23 @@ public class FieldConfigWriter {
contents.append(NEW_LINE); contents.append(NEW_LINE);
} }
private void writeDetectorRules(int detectorId, Detector detector, List<DetectionRule> scheduledEvents, private void writeDetectorRules(int detectorId, Detector detector, StringBuilder contents) throws IOException {
StringBuilder contents) throws IOException {
List<DetectionRule> rules = new ArrayList<>(); List<DetectionRule> rules = new ArrayList<>();
if (detector.getRules() != null) { if (detector.getRules() != null) {
rules.addAll(detector.getRules()); rules.addAll(detector.getRules());
} }
rules.addAll(scheduledEvents);
if (rules.isEmpty()) { if (rules.isEmpty()) {
return; return;
} }
contents.append(DETECTOR_PREFIX).append(detectorId).append(DETECTOR_RULES_SUFFIX).append(EQUALS); contents.append(DETECTOR_PREFIX).append(detectorId).append(DETECTOR_RULES_SUFFIX).append(EQUALS);
writeDetectionRulesJson(rules, contents);
contents.append(NEW_LINE);
}
private void writeDetectionRulesJson(List<DetectionRule> rules, StringBuilder contents) throws IOException {
contents.append('['); contents.append('[');
boolean first = true; boolean first = true;
for (DetectionRule rule : rules) { for (DetectionRule rule : rules) {
@ -130,7 +134,6 @@ public class FieldConfigWriter {
} }
} }
contents.append(']'); contents.append(']');
contents.append(NEW_LINE);
} }
private void writeFilters(StringBuilder buffer) throws IOException { private void writeFilters(StringBuilder buffer) throws IOException {
@ -155,6 +158,28 @@ public class FieldConfigWriter {
} }
} }
private void writeScheduledEvents(StringBuilder contents) throws IOException {
if (scheduledEvents.isEmpty()) {
return;
}
int eventIndex = 0;
for (ScheduledEvent event: scheduledEvents) {
contents.append(SCHEDULED_EVENT_PREFIX).append(eventIndex)
.append(SCHEDULED_EVENT_DESCRIPTION_SUFFIX).append(EQUALS)
.append(quoteField(event.getDescription()))
.append(NEW_LINE);
contents.append(SCHEDULED_EVENT_PREFIX).append(eventIndex)
.append(DETECTOR_RULES_SUFFIX).append(EQUALS);
writeDetectionRulesJson(Collections.singletonList(event.toDetectionRule(config.getBucketSpan())), contents);
contents.append(NEW_LINE);
++eventIndex;
}
}
private static void writeAsEnumeratedSettings(String settingName, List<String> values, StringBuilder buffer, boolean quote) { private static void writeAsEnumeratedSettings(String settingName, List<String> values, StringBuilder buffer, boolean quote) {
if (values == null) { if (values == null) {
return; return;

View File

@ -251,10 +251,12 @@ public class FieldConfigWriterTests extends ESTestCase {
createFieldConfigWriter().write(); createFieldConfigWriter().write();
verify(writer).write("detector.0.clause = count\n" + verify(writer).write("detector.0.clause = count\n" +
"detector.0.rules = [{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," + "scheduledevent.0.description = \"The Ashes\"\n" +
"scheduledevent.0.rules = [{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," +
"\"conditions\":[{\"type\":\"time\",\"condition\":{\"operator\":\"gte\",\"value\":\"1511395200\"}}," + "\"conditions\":[{\"type\":\"time\",\"condition\":{\"operator\":\"gte\",\"value\":\"1511395200\"}}," +
"{\"type\":\"time\",\"condition\":{\"operator\":\"lt\",\"value\":\"1515369600\"}}]}," + "{\"type\":\"time\",\"condition\":{\"operator\":\"lt\",\"value\":\"1515369600\"}}]}]\n" +
"{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," + "scheduledevent.1.description = elasticon\n" +
"scheduledevent.1.rules = [{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," +
"\"conditions\":[{\"type\":\"time\",\"condition\":{\"operator\":\"gte\",\"value\":\"1519603200\"}}," + "\"conditions\":[{\"type\":\"time\",\"condition\":{\"operator\":\"gte\",\"value\":\"1519603200\"}}," +
"{\"type\":\"time\",\"condition\":{\"operator\":\"lt\",\"value\":\"1519862400\"}}]}]" + "{\"type\":\"time\",\"condition\":{\"operator\":\"lt\",\"value\":\"1519862400\"}}]}]" +
"\n"); "\n");