[ML] Restore missing job stats (elastic/x-pack-elasticsearch#667)
* [ML] Pretty print dates in ModelSizeStats * [ML] Add last_data_time field to DataCounts * [ML] Add uptime to job stats * [ML] Pretty print time fields in ModelSnapshot * [ML] Rename uptime -> open_time Original commit: elastic/x-pack-elasticsearch@4ce5258a77
This commit is contained in:
parent
948a8594bb
commit
14a0167781
|
@ -28,6 +28,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.util.concurrent.AtomicArray;
|
import org.elasticsearch.common.util.concurrent.AtomicArray;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
|
@ -47,6 +48,7 @@ import org.elasticsearch.xpack.ml.utils.ExceptionsHelper;
|
||||||
import org.elasticsearch.xpack.persistent.PersistentTasks;
|
import org.elasticsearch.xpack.persistent.PersistentTasks;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -157,20 +159,24 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
private DataCounts dataCounts;
|
private DataCounts dataCounts;
|
||||||
@Nullable
|
@Nullable
|
||||||
private ModelSizeStats modelSizeStats;
|
private ModelSizeStats modelSizeStats;
|
||||||
|
@Nullable
|
||||||
|
private TimeValue openTime;
|
||||||
private JobState state;
|
private JobState state;
|
||||||
@Nullable
|
@Nullable
|
||||||
private DiscoveryNode node;
|
private DiscoveryNode node;
|
||||||
@Nullable
|
@Nullable
|
||||||
private String assignmentExplanation;
|
private String assignmentExplanation;
|
||||||
|
|
||||||
|
|
||||||
JobStats(String jobId, DataCounts dataCounts, @Nullable ModelSizeStats modelSizeStats, JobState state,
|
JobStats(String jobId, DataCounts dataCounts, @Nullable ModelSizeStats modelSizeStats, JobState state,
|
||||||
@Nullable DiscoveryNode node, @Nullable String assignmentExplanation) {
|
@Nullable DiscoveryNode node, @Nullable String assignmentExplanation, @Nullable TimeValue opentime) {
|
||||||
this.jobId = Objects.requireNonNull(jobId);
|
this.jobId = Objects.requireNonNull(jobId);
|
||||||
this.dataCounts = Objects.requireNonNull(dataCounts);
|
this.dataCounts = Objects.requireNonNull(dataCounts);
|
||||||
this.modelSizeStats = modelSizeStats;
|
this.modelSizeStats = modelSizeStats;
|
||||||
this.state = Objects.requireNonNull(state);
|
this.state = Objects.requireNonNull(state);
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.assignmentExplanation = assignmentExplanation;
|
this.assignmentExplanation = assignmentExplanation;
|
||||||
|
this.openTime = opentime;
|
||||||
}
|
}
|
||||||
|
|
||||||
JobStats(StreamInput in) throws IOException {
|
JobStats(StreamInput in) throws IOException {
|
||||||
|
@ -180,6 +186,7 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
state = JobState.fromStream(in);
|
state = JobState.fromStream(in);
|
||||||
node = in.readOptionalWriteable(DiscoveryNode::new);
|
node = in.readOptionalWriteable(DiscoveryNode::new);
|
||||||
assignmentExplanation = in.readOptionalString();
|
assignmentExplanation = in.readOptionalString();
|
||||||
|
openTime = in.readOptionalWriteable(TimeValue::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJobId() {
|
public String getJobId() {
|
||||||
|
@ -206,6 +213,10 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
return assignmentExplanation;
|
return assignmentExplanation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TimeValue getOpenTime() {
|
||||||
|
return openTime;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
@ -232,6 +243,9 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
if (assignmentExplanation != null) {
|
if (assignmentExplanation != null) {
|
||||||
builder.field("assigment_explanation", assignmentExplanation);
|
builder.field("assigment_explanation", assignmentExplanation);
|
||||||
}
|
}
|
||||||
|
if (openTime != null) {
|
||||||
|
builder.timeValueField("open_time", "open_time_string", openTime);
|
||||||
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -244,11 +258,12 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
state.writeTo(out);
|
state.writeTo(out);
|
||||||
out.writeOptionalWriteable(node);
|
out.writeOptionalWriteable(node);
|
||||||
out.writeOptionalString(assignmentExplanation);
|
out.writeOptionalString(assignmentExplanation);
|
||||||
|
out.writeOptionalWriteable(openTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(jobId, dataCounts, modelSizeStats, state, node, assignmentExplanation);
|
return Objects.hash(jobId, dataCounts, modelSizeStats, state, node, assignmentExplanation, openTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -265,7 +280,8 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
&& Objects.equals(this.modelSizeStats, other.modelSizeStats)
|
&& Objects.equals(this.modelSizeStats, other.modelSizeStats)
|
||||||
&& Objects.equals(this.state, other.state)
|
&& Objects.equals(this.state, other.state)
|
||||||
&& Objects.equals(this.node, other.node)
|
&& Objects.equals(this.node, other.node)
|
||||||
&& Objects.equals(this.assignmentExplanation, other.assignmentExplanation);
|
&& Objects.equals(this.assignmentExplanation, other.assignmentExplanation)
|
||||||
|
&& Objects.equals(this.openTime, other.openTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,8 +417,9 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
DiscoveryNode node = state.nodes().get(pTask.getExecutorNode());
|
DiscoveryNode node = state.nodes().get(pTask.getExecutorNode());
|
||||||
JobState jobState = MlMetadata.getJobState(jobId, tasks);
|
JobState jobState = MlMetadata.getJobState(jobId, tasks);
|
||||||
String assignmentExplanation = pTask.getAssignment().getExplanation();
|
String assignmentExplanation = pTask.getAssignment().getExplanation();
|
||||||
|
TimeValue openTime = durationToTimeValue(processManager.jobOpenTime(jobId));
|
||||||
Response.JobStats jobStats = new Response.JobStats(jobId, stats.get().v1(), stats.get().v2(), jobState,
|
Response.JobStats jobStats = new Response.JobStats(jobId, stats.get().v1(), stats.get().v2(), jobState,
|
||||||
node, assignmentExplanation);
|
node, assignmentExplanation, openTime);
|
||||||
listener.onResponse(new QueryPage<>(Collections.singletonList(jobStats), 1, Job.RESULTS_FIELD));
|
listener.onResponse(new QueryPage<>(Collections.singletonList(jobStats), 1, Job.RESULTS_FIELD));
|
||||||
} else {
|
} else {
|
||||||
listener.onResponse(new QueryPage<>(Collections.emptyList(), 0, Job.RESULTS_FIELD));
|
listener.onResponse(new QueryPage<>(Collections.emptyList(), 0, Job.RESULTS_FIELD));
|
||||||
|
@ -432,7 +449,7 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
assignmentExplanation = pTask.getAssignment().getExplanation();
|
assignmentExplanation = pTask.getAssignment().getExplanation();
|
||||||
}
|
}
|
||||||
jobStats.set(slot, new Response.JobStats(jobId, dataCounts, modelSizeStats, jobState, null,
|
jobStats.set(slot, new Response.JobStats(jobId, dataCounts, modelSizeStats, jobState, null,
|
||||||
assignmentExplanation));
|
assignmentExplanation, null));
|
||||||
if (counter.decrementAndGet() == 0) {
|
if (counter.decrementAndGet() == 0) {
|
||||||
List<Response.JobStats> results = response.getResponse().results();
|
List<Response.JobStats> results = response.getResponse().results();
|
||||||
results.addAll(jobStats.asList().stream()
|
results.addAll(jobStats.asList().stream()
|
||||||
|
@ -454,6 +471,14 @@ public class GetJobsStatsAction extends Action<GetJobsStatsAction.Request, GetJo
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TimeValue durationToTimeValue(Optional<Duration> duration) {
|
||||||
|
if (duration.isPresent()) {
|
||||||
|
return TimeValue.timeValueSeconds(duration.get().getSeconds());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static List<String> determineJobIdsWithoutLiveStats(List<String> requestedJobIds, List<Response.JobStats> stats) {
|
static List<String> determineJobIdsWithoutLiveStats(List<String> requestedJobIds, List<Response.JobStats> stats) {
|
||||||
Set<String> excludeJobIds = stats.stream().map(Response.JobStats::getJobId).collect(Collectors.toSet());
|
Set<String> excludeJobIds = stats.stream().map(Response.JobStats::getJobId).collect(Collectors.toSet());
|
||||||
return requestedJobIds.stream().filter(jobId -> !excludeJobIds.contains(jobId)).collect(Collectors.toList());
|
return requestedJobIds.stream().filter(jobId -> !excludeJobIds.contains(jobId)).collect(Collectors.toList());
|
||||||
|
|
|
@ -460,6 +460,9 @@ public class ElasticsearchMappings {
|
||||||
.startObject(DataCounts.LATEST_RECORD_TIME.getPreferredName())
|
.startObject(DataCounts.LATEST_RECORD_TIME.getPreferredName())
|
||||||
.field(TYPE, DATE)
|
.field(TYPE, DATE)
|
||||||
.endObject()
|
.endObject()
|
||||||
|
.startObject(DataCounts.LAST_DATA_TIME.getPreferredName())
|
||||||
|
.field(TYPE, DATE)
|
||||||
|
.endObject()
|
||||||
.endObject()
|
.endObject()
|
||||||
.endObject()
|
.endObject()
|
||||||
.endObject();
|
.endObject();
|
||||||
|
|
|
@ -255,6 +255,9 @@ public class DataCountsReporter extends AbstractComponent implements Closeable {
|
||||||
* Report the counts now regardless of whether or not we are at a reporting boundary.
|
* Report the counts now regardless of whether or not we are at a reporting boundary.
|
||||||
*/
|
*/
|
||||||
public void finishReporting() {
|
public void finishReporting() {
|
||||||
|
Date now = new Date();
|
||||||
|
incrementalRecordStats.setLastDataTimeStamp(now);
|
||||||
|
totalRecordStats.setLastDataTimeStamp(now);
|
||||||
dataCountsPersister.persistDataCounts(jobId, runningTotalStats(), new LoggingActionListener());
|
dataCountsPersister.persistDataCounts(jobId, runningTotalStats(), new LoggingActionListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -300,12 +300,12 @@ public class AutodetectProcessManager extends AbstractComponent {
|
||||||
return autoDetectCommunicatorByJob.get(jobId) != null;
|
return autoDetectCommunicatorByJob.get(jobId) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Duration jobUpTime(String jobId) {
|
public Optional<Duration> jobOpenTime(String jobId) {
|
||||||
AutodetectCommunicator communicator = autoDetectCommunicatorByJob.get(jobId);
|
AutodetectCommunicator communicator = autoDetectCommunicatorByJob.get(jobId);
|
||||||
if (communicator == null) {
|
if (communicator == null) {
|
||||||
return Duration.ZERO;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return Duration.between(communicator.getProcessStartTime(), ZonedDateTime.now());
|
return Optional.of(Duration.between(communicator.getProcessStartTime(), ZonedDateTime.now()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setJobState(long taskId, String jobId, JobState state) {
|
private void setJobState(long taskId, String jobId, JobState state) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
public static final String OUT_OF_ORDER_TIME_COUNT_STR = "out_of_order_timestamp_count";
|
public static final String OUT_OF_ORDER_TIME_COUNT_STR = "out_of_order_timestamp_count";
|
||||||
public static final String EARLIEST_RECORD_TIME_STR = "earliest_record_timestamp";
|
public static final String EARLIEST_RECORD_TIME_STR = "earliest_record_timestamp";
|
||||||
public static final String LATEST_RECORD_TIME_STR = "latest_record_timestamp";
|
public static final String LATEST_RECORD_TIME_STR = "latest_record_timestamp";
|
||||||
|
public static final String LAST_DATA_TIME_STR = "last_data_time";
|
||||||
|
|
||||||
public static final ParseField PROCESSED_RECORD_COUNT = new ParseField(PROCESSED_RECORD_COUNT_STR);
|
public static final ParseField PROCESSED_RECORD_COUNT = new ParseField(PROCESSED_RECORD_COUNT_STR);
|
||||||
public static final ParseField PROCESSED_FIELD_COUNT = new ParseField(PROCESSED_FIELD_COUNT_STR);
|
public static final ParseField PROCESSED_FIELD_COUNT = new ParseField(PROCESSED_FIELD_COUNT_STR);
|
||||||
|
@ -58,12 +59,13 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
public static final ParseField OUT_OF_ORDER_TIME_COUNT = new ParseField(OUT_OF_ORDER_TIME_COUNT_STR);
|
public static final ParseField OUT_OF_ORDER_TIME_COUNT = new ParseField(OUT_OF_ORDER_TIME_COUNT_STR);
|
||||||
public static final ParseField EARLIEST_RECORD_TIME = new ParseField(EARLIEST_RECORD_TIME_STR);
|
public static final ParseField EARLIEST_RECORD_TIME = new ParseField(EARLIEST_RECORD_TIME_STR);
|
||||||
public static final ParseField LATEST_RECORD_TIME = new ParseField(LATEST_RECORD_TIME_STR);
|
public static final ParseField LATEST_RECORD_TIME = new ParseField(LATEST_RECORD_TIME_STR);
|
||||||
|
public static final ParseField LAST_DATA_TIME = new ParseField(LAST_DATA_TIME_STR);
|
||||||
|
|
||||||
public static final ParseField TYPE = new ParseField("data_counts");
|
public static final ParseField TYPE = new ParseField("data_counts");
|
||||||
|
|
||||||
public static final ConstructingObjectParser<DataCounts, Void> PARSER =
|
public static final ConstructingObjectParser<DataCounts, Void> PARSER =
|
||||||
new ConstructingObjectParser<>("data_counts", a -> new DataCounts((String) a[0], (long) a[1], (long) a[2], (long) a[3],
|
new ConstructingObjectParser<>("data_counts", a -> new DataCounts((String) a[0], (long) a[1], (long) a[2], (long) a[3],
|
||||||
(long) a[4], (long) a[5], (long) a[6], (long) a[7], (Date) a[8], (Date) a[9]));
|
(long) a[4], (long) a[5], (long) a[6], (long) a[7], (Date) a[8], (Date) a[9], (Date) a[10]));
|
||||||
|
|
||||||
static {
|
static {
|
||||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), Job.ID);
|
PARSER.declareString(ConstructingObjectParser.constructorArg(), Job.ID);
|
||||||
|
@ -92,6 +94,15 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"unexpected token [" + p.currentToken() + "] for [" + LATEST_RECORD_TIME.getPreferredName() + "]");
|
"unexpected token [" + p.currentToken() + "] for [" + LATEST_RECORD_TIME.getPreferredName() + "]");
|
||||||
}, LATEST_RECORD_TIME, ValueType.VALUE);
|
}, LATEST_RECORD_TIME, ValueType.VALUE);
|
||||||
|
PARSER.declareField(ConstructingObjectParser.optionalConstructorArg(), p -> {
|
||||||
|
if (p.currentToken() == Token.VALUE_NUMBER) {
|
||||||
|
return new Date(p.longValue());
|
||||||
|
} else if (p.currentToken() == Token.VALUE_STRING) {
|
||||||
|
return new Date(TimeUtils.dateStringToEpoch(p.text()));
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"unexpected token [" + p.currentToken() + "] for [" + LAST_DATA_TIME.getPreferredName() + "]");
|
||||||
|
}, LAST_DATA_TIME, ValueType.VALUE);
|
||||||
PARSER.declareLong((t, u) -> {;}, INPUT_RECORD_COUNT);
|
PARSER.declareLong((t, u) -> {;}, INPUT_RECORD_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,10 +121,11 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
// NORELEASE: Use Jodatime instead
|
// NORELEASE: Use Jodatime instead
|
||||||
private Date earliestRecordTimeStamp;
|
private Date earliestRecordTimeStamp;
|
||||||
private Date latestRecordTimeStamp;
|
private Date latestRecordTimeStamp;
|
||||||
|
private Date lastDataTimeStamp;
|
||||||
|
|
||||||
public DataCounts(String jobId, long processedRecordCount, long processedFieldCount, long inputBytes,
|
public DataCounts(String jobId, long processedRecordCount, long processedFieldCount, long inputBytes,
|
||||||
long inputFieldCount, long invalidDateCount, long missingFieldCount, long outOfOrderTimeStampCount,
|
long inputFieldCount, long invalidDateCount, long missingFieldCount, long outOfOrderTimeStampCount,
|
||||||
Date earliestRecordTimeStamp, Date latestRecordTimeStamp) {
|
Date earliestRecordTimeStamp, Date latestRecordTimeStamp, Date lastDataTimeStamp) {
|
||||||
this.jobId = jobId;
|
this.jobId = jobId;
|
||||||
this.processedRecordCount = processedRecordCount;
|
this.processedRecordCount = processedRecordCount;
|
||||||
this.processedFieldCount = processedFieldCount;
|
this.processedFieldCount = processedFieldCount;
|
||||||
|
@ -124,6 +136,7 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
this.outOfOrderTimeStampCount = outOfOrderTimeStampCount;
|
this.outOfOrderTimeStampCount = outOfOrderTimeStampCount;
|
||||||
this.latestRecordTimeStamp = latestRecordTimeStamp;
|
this.latestRecordTimeStamp = latestRecordTimeStamp;
|
||||||
this.earliestRecordTimeStamp = earliestRecordTimeStamp;
|
this.earliestRecordTimeStamp = earliestRecordTimeStamp;
|
||||||
|
this.lastDataTimeStamp = lastDataTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataCounts(String jobId) {
|
public DataCounts(String jobId) {
|
||||||
|
@ -141,6 +154,7 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
outOfOrderTimeStampCount = lhs.outOfOrderTimeStampCount;
|
outOfOrderTimeStampCount = lhs.outOfOrderTimeStampCount;
|
||||||
latestRecordTimeStamp = lhs.latestRecordTimeStamp;
|
latestRecordTimeStamp = lhs.latestRecordTimeStamp;
|
||||||
earliestRecordTimeStamp = lhs.earliestRecordTimeStamp;
|
earliestRecordTimeStamp = lhs.earliestRecordTimeStamp;
|
||||||
|
lastDataTimeStamp = lhs.lastDataTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataCounts(StreamInput in) throws IOException {
|
public DataCounts(StreamInput in) throws IOException {
|
||||||
|
@ -158,6 +172,9 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
earliestRecordTimeStamp = new Date(in.readVLong());
|
earliestRecordTimeStamp = new Date(in.readVLong());
|
||||||
}
|
}
|
||||||
|
if (in.readBoolean()) {
|
||||||
|
lastDataTimeStamp = new Date(in.readVLong());
|
||||||
|
}
|
||||||
in.readVLong(); // throw away inputRecordCount
|
in.readVLong(); // throw away inputRecordCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,6 +344,19 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
this.latestRecordTimeStamp = latestRecordTimeStamp;
|
this.latestRecordTimeStamp = latestRecordTimeStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The wall clock time the latest record was seen.
|
||||||
|
*
|
||||||
|
* @return Wall clock time of the lastest record
|
||||||
|
*/
|
||||||
|
public Date getLastDataTimeStamp() {
|
||||||
|
return lastDataTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastDataTimeStamp(Date lastDataTimeStamp) {
|
||||||
|
this.lastDataTimeStamp = lastDataTimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
out.writeString(jobId);
|
out.writeString(jobId);
|
||||||
|
@ -349,6 +379,12 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
} else {
|
} else {
|
||||||
out.writeBoolean(false);
|
out.writeBoolean(false);
|
||||||
}
|
}
|
||||||
|
if (lastDataTimeStamp != null) {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
out.writeVLong(lastDataTimeStamp.getTime());
|
||||||
|
} else {
|
||||||
|
out.writeBoolean(false);
|
||||||
|
}
|
||||||
out.writeVLong(getInputRecordCount());
|
out.writeVLong(getInputRecordCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,6 +413,10 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
builder.dateField(LATEST_RECORD_TIME.getPreferredName(), LATEST_RECORD_TIME.getPreferredName() + "_string",
|
builder.dateField(LATEST_RECORD_TIME.getPreferredName(), LATEST_RECORD_TIME.getPreferredName() + "_string",
|
||||||
latestRecordTimeStamp.getTime());
|
latestRecordTimeStamp.getTime());
|
||||||
}
|
}
|
||||||
|
if (lastDataTimeStamp != null) {
|
||||||
|
builder.dateField(LAST_DATA_TIME.getPreferredName(), LAST_DATA_TIME.getPreferredName() + "_string",
|
||||||
|
lastDataTimeStamp.getTime());
|
||||||
|
}
|
||||||
builder.field(INPUT_RECORD_COUNT.getPreferredName(), getInputRecordCount());
|
builder.field(INPUT_RECORD_COUNT.getPreferredName(), getInputRecordCount());
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -406,7 +446,8 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
this.missingFieldCount == that.missingFieldCount &&
|
this.missingFieldCount == that.missingFieldCount &&
|
||||||
this.outOfOrderTimeStampCount == that.outOfOrderTimeStampCount &&
|
this.outOfOrderTimeStampCount == that.outOfOrderTimeStampCount &&
|
||||||
Objects.equals(this.latestRecordTimeStamp, that.latestRecordTimeStamp) &&
|
Objects.equals(this.latestRecordTimeStamp, that.latestRecordTimeStamp) &&
|
||||||
Objects.equals(this.earliestRecordTimeStamp, that.earliestRecordTimeStamp);
|
Objects.equals(this.earliestRecordTimeStamp, that.earliestRecordTimeStamp) &&
|
||||||
|
Objects.equals(this.lastDataTimeStamp, that.lastDataTimeStamp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +455,6 @@ public class DataCounts extends ToXContentToBytes implements Writeable {
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(jobId, processedRecordCount, processedFieldCount,
|
return Objects.hash(jobId, processedRecordCount, processedFieldCount,
|
||||||
inputBytes, inputFieldCount, invalidDateCount, missingFieldCount,
|
inputBytes, inputFieldCount, invalidDateCount, missingFieldCount,
|
||||||
outOfOrderTimeStampCount, latestRecordTimeStamp, earliestRecordTimeStamp);
|
outOfOrderTimeStampCount, latestRecordTimeStamp, earliestRecordTimeStamp, lastDataTimeStamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,9 +184,9 @@ public class ModelSizeStats extends ToXContentToBytes implements Writeable {
|
||||||
builder.field(TOTAL_PARTITION_FIELD_COUNT_FIELD.getPreferredName(), totalPartitionFieldCount);
|
builder.field(TOTAL_PARTITION_FIELD_COUNT_FIELD.getPreferredName(), totalPartitionFieldCount);
|
||||||
builder.field(BUCKET_ALLOCATION_FAILURES_COUNT_FIELD.getPreferredName(), bucketAllocationFailuresCount);
|
builder.field(BUCKET_ALLOCATION_FAILURES_COUNT_FIELD.getPreferredName(), bucketAllocationFailuresCount);
|
||||||
builder.field(MEMORY_STATUS_FIELD.getPreferredName(), memoryStatus);
|
builder.field(MEMORY_STATUS_FIELD.getPreferredName(), memoryStatus);
|
||||||
builder.field(LOG_TIME_FIELD.getPreferredName(), logTime.getTime());
|
builder.dateField(LOG_TIME_FIELD.getPreferredName(), LOG_TIME_FIELD.getPreferredName() + "_string", logTime.getTime());
|
||||||
if (timestamp != null) {
|
if (timestamp != null) {
|
||||||
builder.field(TIMESTAMP_FIELD.getPreferredName(), timestamp.getTime());
|
builder.dateField(TIMESTAMP_FIELD.getPreferredName(), TIMESTAMP_FIELD.getPreferredName() + "_string", timestamp.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -220,10 +220,18 @@ public class ModelSizeStats extends ToXContentToBytes implements Writeable {
|
||||||
return memoryStatus;
|
return memoryStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The timestamp of the last processed record when this instance was created.
|
||||||
|
* @return The record time
|
||||||
|
*/
|
||||||
public Date getTimestamp() {
|
public Date getTimestamp() {
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The wall clock time at the point when this instance was created.
|
||||||
|
* @return The wall clock time
|
||||||
|
*/
|
||||||
public Date getLogTime() {
|
public Date getLogTime() {
|
||||||
return logTime;
|
return logTime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class ModelSnapshot extends ToXContentToBytes implements Writeable {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
builder.field(Job.ID.getPreferredName(), jobId);
|
builder.field(Job.ID.getPreferredName(), jobId);
|
||||||
if (timestamp != null) {
|
if (timestamp != null) {
|
||||||
builder.field(TIMESTAMP.getPreferredName(), timestamp.getTime());
|
builder.dateField(TIMESTAMP.getPreferredName(), TIMESTAMP.getPreferredName() + "_string", timestamp.getTime());
|
||||||
}
|
}
|
||||||
if (description != null) {
|
if (description != null) {
|
||||||
builder.field(DESCRIPTION.getPreferredName(), description);
|
builder.field(DESCRIPTION.getPreferredName(), description);
|
||||||
|
@ -176,10 +176,12 @@ public class ModelSnapshot extends ToXContentToBytes implements Writeable {
|
||||||
builder.field(ModelSizeStats.RESULT_TYPE_FIELD.getPreferredName(), modelSizeStats);
|
builder.field(ModelSizeStats.RESULT_TYPE_FIELD.getPreferredName(), modelSizeStats);
|
||||||
}
|
}
|
||||||
if (latestRecordTimeStamp != null) {
|
if (latestRecordTimeStamp != null) {
|
||||||
builder.field(LATEST_RECORD_TIME.getPreferredName(), latestRecordTimeStamp.getTime());
|
builder.dateField(LATEST_RECORD_TIME.getPreferredName(), LATEST_RECORD_TIME.getPreferredName() + "_string",
|
||||||
|
latestRecordTimeStamp.getTime());
|
||||||
}
|
}
|
||||||
if (latestResultTimeStamp != null) {
|
if (latestResultTimeStamp != null) {
|
||||||
builder.field(LATEST_RESULT_TIME.getPreferredName(), latestResultTimeStamp.getTime());
|
builder.dateField(LATEST_RESULT_TIME.getPreferredName(), LATEST_RESULT_TIME.getPreferredName() + "_string",
|
||||||
|
latestResultTimeStamp.getTime());
|
||||||
}
|
}
|
||||||
if (quantiles != null) {
|
if (quantiles != null) {
|
||||||
builder.field(Quantiles.TYPE.getPreferredName(), quantiles);
|
builder.field(Quantiles.TYPE.getPreferredName(), quantiles);
|
||||||
|
|
|
@ -108,6 +108,7 @@ public final class ReservedFieldNames {
|
||||||
DataCounts.OUT_OF_ORDER_TIME_COUNT.getPreferredName(),
|
DataCounts.OUT_OF_ORDER_TIME_COUNT.getPreferredName(),
|
||||||
DataCounts.LATEST_RECORD_TIME.getPreferredName(),
|
DataCounts.LATEST_RECORD_TIME.getPreferredName(),
|
||||||
DataCounts.EARLIEST_RECORD_TIME.getPreferredName(),
|
DataCounts.EARLIEST_RECORD_TIME.getPreferredName(),
|
||||||
|
DataCounts.LAST_DATA_TIME.getPreferredName(),
|
||||||
|
|
||||||
Influence.INFLUENCER_FIELD_NAME.getPreferredName(),
|
Influence.INFLUENCER_FIELD_NAME.getPreferredName(),
|
||||||
Influence.INFLUENCER_FIELD_VALUES.getPreferredName(),
|
Influence.INFLUENCER_FIELD_VALUES.getPreferredName(),
|
||||||
|
|
|
@ -8,20 +8,23 @@ package org.elasticsearch.xpack.ml.action;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||||
import org.elasticsearch.common.transport.TransportAddress;
|
import org.elasticsearch.common.transport.TransportAddress;
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.xpack.ml.action.GetJobsStatsAction.Response;
|
import org.elasticsearch.xpack.ml.action.GetJobsStatsAction.Response;
|
||||||
import org.elasticsearch.xpack.ml.action.util.QueryPage;
|
import org.elasticsearch.xpack.ml.action.util.QueryPage;
|
||||||
import org.elasticsearch.xpack.ml.job.config.Job;
|
import org.elasticsearch.xpack.ml.job.config.Job;
|
||||||
import org.elasticsearch.xpack.ml.job.config.JobState;
|
import org.elasticsearch.xpack.ml.job.config.JobState;
|
||||||
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCounts;
|
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCounts;
|
||||||
|
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCountsTests;
|
||||||
import org.elasticsearch.xpack.ml.job.process.autodetect.state.ModelSizeStats;
|
import org.elasticsearch.xpack.ml.job.process.autodetect.state.ModelSizeStats;
|
||||||
import org.elasticsearch.xpack.ml.support.AbstractStreamableTestCase;
|
import org.elasticsearch.xpack.ml.support.AbstractStreamableTestCase;
|
||||||
import org.joda.time.DateTime;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.unit.TimeValue.parseTimeValue;
|
||||||
|
|
||||||
public class GetJobStatsActionResponseTests extends AbstractStreamableTestCase<Response> {
|
public class GetJobStatsActionResponseTests extends AbstractStreamableTestCase<Response> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -33,11 +36,7 @@ public class GetJobStatsActionResponseTests extends AbstractStreamableTestCase<R
|
||||||
for (int j = 0; j < listSize; j++) {
|
for (int j = 0; j < listSize; j++) {
|
||||||
String jobId = randomAsciiOfLength(10);
|
String jobId = randomAsciiOfLength(10);
|
||||||
|
|
||||||
DataCounts dataCounts = new DataCounts(randomAsciiOfLength(10), randomIntBetween(1, 1_000_000),
|
DataCounts dataCounts = new DataCountsTests().createTestInstance();
|
||||||
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
|
||||||
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
|
||||||
new DateTime(randomDateTimeZone()).toDate(), new DateTime(randomDateTimeZone()).toDate());
|
|
||||||
|
|
||||||
ModelSizeStats sizeStats = null;
|
ModelSizeStats sizeStats = null;
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
sizeStats = new ModelSizeStats.Builder("foo").build();
|
sizeStats = new ModelSizeStats.Builder("foo").build();
|
||||||
|
@ -52,7 +51,11 @@ public class GetJobStatsActionResponseTests extends AbstractStreamableTestCase<R
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
explanation = randomAsciiOfLength(3);
|
explanation = randomAsciiOfLength(3);
|
||||||
}
|
}
|
||||||
Response.JobStats jobStats = new Response.JobStats(jobId, dataCounts, sizeStats, jobState, node, explanation);
|
TimeValue openTime = null;
|
||||||
|
if (randomBoolean()) {
|
||||||
|
openTime = parseTimeValue(randomPositiveTimeValue(), "open_time-Test");
|
||||||
|
}
|
||||||
|
Response.JobStats jobStats = new Response.JobStats(jobId, dataCounts, sizeStats, jobState, node, explanation, openTime);
|
||||||
jobStatsList.add(jobStats);
|
jobStatsList.add(jobStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,16 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.ml.action;
|
package org.elasticsearch.xpack.ml.action;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.ml.job.config.JobState;
|
import org.elasticsearch.xpack.ml.job.config.JobState;
|
||||||
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCounts;
|
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCounts;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.ml.action.GetJobsStatsAction.TransportAction.determineJobIdsWithoutLiveStats;
|
import static org.elasticsearch.xpack.ml.action.GetJobsStatsAction.TransportAction.determineJobIdsWithoutLiveStats;
|
||||||
|
|
||||||
|
@ -23,7 +26,7 @@ public class GetJobsStatsActionTests extends ESTestCase {
|
||||||
assertEquals("id1", result.get(0));
|
assertEquals("id1", result.get(0));
|
||||||
|
|
||||||
result = determineJobIdsWithoutLiveStats(Collections.singletonList("id1"), Collections.singletonList(
|
result = determineJobIdsWithoutLiveStats(Collections.singletonList("id1"), Collections.singletonList(
|
||||||
new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null, JobState.CLOSED, null, null)));
|
new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null, JobState.CLOSED, null, null, null)));
|
||||||
assertEquals(0, result.size());
|
assertEquals(0, result.size());
|
||||||
|
|
||||||
result = determineJobIdsWithoutLiveStats(
|
result = determineJobIdsWithoutLiveStats(
|
||||||
|
@ -36,24 +39,32 @@ public class GetJobsStatsActionTests extends ESTestCase {
|
||||||
result = determineJobIdsWithoutLiveStats(
|
result = determineJobIdsWithoutLiveStats(
|
||||||
Arrays.asList("id1", "id2", "id3"),
|
Arrays.asList("id1", "id2", "id3"),
|
||||||
Collections.singletonList(new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null,
|
Collections.singletonList(new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null,
|
||||||
JobState.CLOSED, null, null))
|
JobState.CLOSED, null, null, null))
|
||||||
);
|
);
|
||||||
assertEquals(2, result.size());
|
assertEquals(2, result.size());
|
||||||
assertEquals("id2", result.get(0));
|
assertEquals("id2", result.get(0));
|
||||||
assertEquals("id3", result.get(1));
|
assertEquals("id3", result.get(1));
|
||||||
|
|
||||||
result = determineJobIdsWithoutLiveStats(Arrays.asList("id1", "id2", "id3"), Arrays.asList(
|
result = determineJobIdsWithoutLiveStats(Arrays.asList("id1", "id2", "id3"), Arrays.asList(
|
||||||
new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null, JobState.CLOSED, null, null),
|
new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null, JobState.CLOSED, null, null, null),
|
||||||
new GetJobsStatsAction.Response.JobStats("id3", new DataCounts("id3"), null, JobState.CLOSED, null, null)
|
new GetJobsStatsAction.Response.JobStats("id3", new DataCounts("id3"), null, JobState.CLOSED, null, null, null)
|
||||||
));
|
));
|
||||||
assertEquals(1, result.size());
|
assertEquals(1, result.size());
|
||||||
assertEquals("id2", result.get(0));
|
assertEquals("id2", result.get(0));
|
||||||
|
|
||||||
result = determineJobIdsWithoutLiveStats(Arrays.asList("id1", "id2", "id3"),
|
result = determineJobIdsWithoutLiveStats(Arrays.asList("id1", "id2", "id3"),
|
||||||
Arrays.asList(new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null, JobState.CLOSED, null, null),
|
Arrays.asList(
|
||||||
new GetJobsStatsAction.Response.JobStats("id2", new DataCounts("id2"), null, JobState.CLOSED, null, null),
|
new GetJobsStatsAction.Response.JobStats("id1", new DataCounts("id1"), null, JobState.CLOSED, null, null, null),
|
||||||
new GetJobsStatsAction.Response.JobStats("id3", new DataCounts("id3"), null, JobState.CLOSED, null, null)));
|
new GetJobsStatsAction.Response.JobStats("id2", new DataCounts("id2"), null, JobState.CLOSED, null, null, null),
|
||||||
|
new GetJobsStatsAction.Response.JobStats("id3", new DataCounts("id3"), null, JobState.CLOSED, null, null, null)));
|
||||||
assertEquals(0, result.size());
|
assertEquals(0, result.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDurationToTimeValue() {
|
||||||
|
assertNull(GetJobsStatsAction.TransportAction.durationToTimeValue(Optional.empty()));
|
||||||
|
|
||||||
|
Duration duration = Duration.ofSeconds(10L);
|
||||||
|
TimeValue timeValue = GetJobsStatsAction.TransportAction.durationToTimeValue(Optional.of(duration));
|
||||||
|
assertEquals(10L, timeValue.getSeconds());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
package org.elasticsearch.xpack.ml.action;
|
package org.elasticsearch.xpack.ml.action;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCounts;
|
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCounts;
|
||||||
|
import org.elasticsearch.xpack.ml.job.process.autodetect.state.DataCountsTests;
|
||||||
import org.elasticsearch.xpack.ml.support.AbstractStreamableTestCase;
|
import org.elasticsearch.xpack.ml.support.AbstractStreamableTestCase;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
@ -13,10 +14,7 @@ public class PostDataActionResponseTests extends AbstractStreamableTestCase<Post
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PostDataAction.Response createTestInstance() {
|
protected PostDataAction.Response createTestInstance() {
|
||||||
DataCounts counts = new DataCounts(randomAsciiOfLength(10), randomIntBetween(1, 1_000_000),
|
DataCounts counts = new DataCountsTests().createTestInstance();
|
||||||
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
|
||||||
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
|
||||||
new DateTime(randomDateTimeZone()).toDate(), new DateTime(randomDateTimeZone()).toDate());
|
|
||||||
|
|
||||||
return new PostDataAction.Response(counts);
|
return new PostDataAction.Response(counts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ public class DatafeedJobRunnerTests extends ESTestCase {
|
||||||
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
||||||
InputStream in = new ByteArrayInputStream("".getBytes(Charset.forName("utf-8")));
|
InputStream in = new ByteArrayInputStream("".getBytes(Charset.forName("utf-8")));
|
||||||
when(dataExtractor.next()).thenReturn(Optional.of(in));
|
when(dataExtractor.next()).thenReturn(Optional.of(in));
|
||||||
DataCounts dataCounts = new DataCounts("job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0));
|
DataCounts dataCounts = new DataCounts("job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0), new Date(0));
|
||||||
when(jobDataFuture.actionGet()).thenReturn(new PostDataAction.Response(dataCounts));
|
when(jobDataFuture.actionGet()).thenReturn(new PostDataAction.Response(dataCounts));
|
||||||
Consumer<Exception> handler = mockConsumer();
|
Consumer<Exception> handler = mockConsumer();
|
||||||
StartDatafeedAction.DatafeedTask task = createDatafeedTask("datafeed_id", 0L, 60000L);
|
StartDatafeedAction.DatafeedTask task = createDatafeedTask("datafeed_id", 0L, 60000L);
|
||||||
|
@ -209,7 +209,7 @@ public class DatafeedJobRunnerTests extends ESTestCase {
|
||||||
when(dataExtractorFactory.newExtractor(0L, 60000L)).thenReturn(dataExtractor);
|
when(dataExtractorFactory.newExtractor(0L, 60000L)).thenReturn(dataExtractor);
|
||||||
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
||||||
when(dataExtractor.next()).thenThrow(new RuntimeException("dummy"));
|
when(dataExtractor.next()).thenThrow(new RuntimeException("dummy"));
|
||||||
DataCounts dataCounts = new DataCounts("job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0));
|
DataCounts dataCounts = new DataCounts("job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0), new Date(0));
|
||||||
when(jobDataFuture.actionGet()).thenReturn(new PostDataAction.Response(dataCounts));
|
when(jobDataFuture.actionGet()).thenReturn(new PostDataAction.Response(dataCounts));
|
||||||
Consumer<Exception> handler = mockConsumer();
|
Consumer<Exception> handler = mockConsumer();
|
||||||
StartDatafeedAction.DatafeedTask task = createDatafeedTask("datafeed_id", 0L, 60000L);
|
StartDatafeedAction.DatafeedTask task = createDatafeedTask("datafeed_id", 0L, 60000L);
|
||||||
|
@ -263,7 +263,7 @@ public class DatafeedJobRunnerTests extends ESTestCase {
|
||||||
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
||||||
InputStream in = new ByteArrayInputStream("".getBytes(Charset.forName("utf-8")));
|
InputStream in = new ByteArrayInputStream("".getBytes(Charset.forName("utf-8")));
|
||||||
when(dataExtractor.next()).thenReturn(Optional.of(in));
|
when(dataExtractor.next()).thenReturn(Optional.of(in));
|
||||||
DataCounts dataCounts = new DataCounts("job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0));
|
DataCounts dataCounts = new DataCounts("job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0), new Date(0));
|
||||||
when(jobDataFuture.actionGet()).thenReturn(new PostDataAction.Response(dataCounts));
|
when(jobDataFuture.actionGet()).thenReturn(new PostDataAction.Response(dataCounts));
|
||||||
Consumer<Exception> handler = mockConsumer();
|
Consumer<Exception> handler = mockConsumer();
|
||||||
boolean cancelled = randomBoolean();
|
boolean cancelled = randomBoolean();
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class DatafeedJobTests extends ESTestCase {
|
||||||
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
when(dataExtractor.hasNext()).thenReturn(true).thenReturn(false);
|
||||||
InputStream inputStream = new ByteArrayInputStream("content".getBytes(StandardCharsets.UTF_8));
|
InputStream inputStream = new ByteArrayInputStream("content".getBytes(StandardCharsets.UTF_8));
|
||||||
when(dataExtractor.next()).thenReturn(Optional.of(inputStream));
|
when(dataExtractor.next()).thenReturn(Optional.of(inputStream));
|
||||||
DataCounts dataCounts = new DataCounts("_job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0));
|
DataCounts dataCounts = new DataCounts("_job_id", 1, 0, 0, 0, 0, 0, 0, new Date(0), new Date(0), new Date(0));
|
||||||
|
|
||||||
PostDataAction.Request expectedRequest = new PostDataAction.Request("_job_id");
|
PostDataAction.Request expectedRequest = new PostDataAction.Request("_job_id");
|
||||||
expectedRequest.setDataDescription(dataDescription.build());
|
expectedRequest.setDataDescription(dataDescription.build());
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class DataCountsReporterTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testComplexConstructor() throws Exception {
|
public void testComplexConstructor() throws Exception {
|
||||||
DataCounts counts = new DataCounts("foo", 1L, 1L, 2L, 0L, 3L, 4L, 5L, new Date(), new Date());
|
DataCounts counts = new DataCounts("foo", 1L, 1L, 2L, 0L, 3L, 4L, 5L, new Date(), new Date(), new Date());
|
||||||
|
|
||||||
try (DataCountsReporter dataCountsReporter =
|
try (DataCountsReporter dataCountsReporter =
|
||||||
new DataCountsReporter(threadPool, settings, JOB_ID, counts, jobDataCountsPersister)) {
|
new DataCountsReporter(threadPool, settings, JOB_ID, counts, jobDataCountsPersister)) {
|
||||||
|
@ -249,13 +249,21 @@ public class DataCountsReporterTests extends ESTestCase {
|
||||||
|
|
||||||
dataCountsReporter.setAnalysedFieldsPerRecord(3);
|
dataCountsReporter.setAnalysedFieldsPerRecord(3);
|
||||||
|
|
||||||
DataCounts dc = new DataCounts(JOB_ID, 2L, 5L, 0L, 10L, 0L, 1L, 0L, new Date(2000), new Date(3000));
|
Date now = new Date();
|
||||||
|
DataCounts dc = new DataCounts(JOB_ID, 2L, 5L, 0L, 10L, 0L, 1L, 0L, new Date(2000), new Date(3000), now);
|
||||||
dataCountsReporter.reportRecordWritten(5, 2000);
|
dataCountsReporter.reportRecordWritten(5, 2000);
|
||||||
dataCountsReporter.reportRecordWritten(5, 3000);
|
dataCountsReporter.reportRecordWritten(5, 3000);
|
||||||
dataCountsReporter.reportMissingField();
|
dataCountsReporter.reportMissingField();
|
||||||
dataCountsReporter.finishReporting();
|
dataCountsReporter.finishReporting();
|
||||||
|
|
||||||
|
long lastReportedTimeMs = dataCountsReporter.incrementalStats().getLastDataTimeStamp().getTime();
|
||||||
|
// check last data time is equal to now give or take a second
|
||||||
|
assertTrue(lastReportedTimeMs >= now.getTime() && lastReportedTimeMs <= now.getTime() +1);
|
||||||
|
assertEquals(dataCountsReporter.incrementalStats().getLastDataTimeStamp(),
|
||||||
|
dataCountsReporter.runningTotalStats().getLastDataTimeStamp());
|
||||||
|
|
||||||
Mockito.verify(jobDataCountsPersister, Mockito.times(1)).persistDataCounts(eq("SR"), eq(dc), any());
|
Mockito.verify(jobDataCountsPersister, Mockito.times(1)).persistDataCounts(eq("SR"), eq(dc), any());
|
||||||
|
dc.setLastDataTimeStamp(dataCountsReporter.incrementalStats().getLastDataTimeStamp());
|
||||||
assertEquals(dc, dataCountsReporter.incrementalStats());
|
assertEquals(dc, dataCountsReporter.incrementalStats());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,12 @@ import static org.hamcrest.Matchers.greaterThan;
|
||||||
public class DataCountsTests extends AbstractSerializingTestCase<DataCounts> {
|
public class DataCountsTests extends AbstractSerializingTestCase<DataCounts> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DataCounts createTestInstance() {
|
public DataCounts createTestInstance() {
|
||||||
return new DataCounts(randomAsciiOfLength(10), randomIntBetween(1, 1_000_000),
|
return new DataCounts(randomAsciiOfLength(10), randomIntBetween(1, 1_000_000),
|
||||||
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
||||||
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000), randomIntBetween(1, 1_000_000),
|
||||||
new DateTime(randomDateTimeZone()).toDate(), new DateTime(randomDateTimeZone()).toDate());
|
new DateTime(randomDateTimeZone()).toDate(), new DateTime(randomDateTimeZone()).toDate(),
|
||||||
|
new DateTime(randomDateTimeZone()).toDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,22 +36,22 @@ public class DataCountsTests extends AbstractSerializingTestCase<DataCounts> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCountsEquals_GivenEqualCounts() {
|
public void testCountsEquals_GivenEqualCounts() {
|
||||||
DataCounts counts1 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
DataCounts counts1 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
DataCounts counts2 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
DataCounts counts2 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
|
|
||||||
assertTrue(counts1.equals(counts2));
|
assertTrue(counts1.equals(counts2));
|
||||||
assertTrue(counts2.equals(counts1));
|
assertTrue(counts2.equals(counts1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCountsHashCode_GivenEqualCounts() {
|
public void testCountsHashCode_GivenEqualCounts() {
|
||||||
DataCounts counts1 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
DataCounts counts1 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
DataCounts counts2 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
DataCounts counts2 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
|
|
||||||
assertEquals(counts1.hashCode(), counts2.hashCode());
|
assertEquals(counts1.hashCode(), counts2.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCountsCopyConstructor() {
|
public void testCountsCopyConstructor() {
|
||||||
DataCounts counts1 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9);
|
DataCounts counts1 = createCounts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||||
DataCounts counts2 = new DataCounts(counts1);
|
DataCounts counts2 = new DataCounts(counts1);
|
||||||
|
|
||||||
assertEquals(counts1.hashCode(), counts2.hashCode());
|
assertEquals(counts1.hashCode(), counts2.hashCode());
|
||||||
|
@ -62,7 +63,7 @@ public class DataCountsTests extends AbstractSerializingTestCase<DataCounts> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCountCopyCreatedFieldsNotZero() throws Exception {
|
public void testCountCopyCreatedFieldsNotZero() throws Exception {
|
||||||
DataCounts counts1 = createCounts(1, 200, 400, 3, 4, 5, 6, 1479211200000L, 1479384000000L);
|
DataCounts counts1 = createCounts(1, 200, 400, 3, 4, 5, 6, 1479211200000L, 1479384000000L, 1488282343000L);
|
||||||
assertAllFieldsGreaterThanZero(counts1);
|
assertAllFieldsGreaterThanZero(counts1);
|
||||||
|
|
||||||
DataCounts counts2 = new DataCounts(counts1);
|
DataCounts counts2 = new DataCounts(counts1);
|
||||||
|
@ -101,19 +102,19 @@ public class DataCountsTests extends AbstractSerializingTestCase<DataCounts> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCalcProcessedFieldCount() {
|
public void testCalcProcessedFieldCount() {
|
||||||
DataCounts counts = new DataCounts(randomAsciiOfLength(16), 10L, 0L, 0L, 0L, 0L, 0L, 0L, new Date(), new Date());
|
DataCounts counts = new DataCounts(randomAsciiOfLength(16), 10L, 0L, 0L, 0L, 0L, 0L, 0L, new Date(), new Date(), new Date());
|
||||||
counts.calcProcessedFieldCount(3);
|
counts.calcProcessedFieldCount(3);
|
||||||
|
|
||||||
assertEquals(30, counts.getProcessedFieldCount());
|
assertEquals(30, counts.getProcessedFieldCount());
|
||||||
|
|
||||||
counts = new DataCounts(randomAsciiOfLength(16), 10L, 0L, 0L, 0L, 0L, 5L, 0L, new Date(), new Date());
|
counts = new DataCounts(randomAsciiOfLength(16), 10L, 0L, 0L, 0L, 0L, 5L, 0L, new Date(), new Date(), new Date());
|
||||||
counts.calcProcessedFieldCount(3);
|
counts.calcProcessedFieldCount(3);
|
||||||
assertEquals(25, counts.getProcessedFieldCount());
|
assertEquals(25, counts.getProcessedFieldCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEquals() {
|
public void testEquals() {
|
||||||
DataCounts counts1 = new DataCounts(
|
DataCounts counts1 = new DataCounts(
|
||||||
randomAsciiOfLength(16), 10L, 5000L, 2000L, 300L, 6L, 15L, 0L, new Date(), new Date(1435000000L));
|
randomAsciiOfLength(16), 10L, 5000L, 2000L, 300L, 6L, 15L, 0L, new Date(), new Date(1435000000L), new Date(10L));
|
||||||
DataCounts counts2 = new DataCounts(counts1);
|
DataCounts counts2 = new DataCounts(counts1);
|
||||||
|
|
||||||
assertEquals(counts1, counts2);
|
assertEquals(counts1, counts2);
|
||||||
|
@ -155,11 +156,12 @@ public class DataCountsTests extends AbstractSerializingTestCase<DataCounts> {
|
||||||
|
|
||||||
private static DataCounts createCounts(
|
private static DataCounts createCounts(
|
||||||
long processedRecordCount, long processedFieldCount, long inputBytes, long inputFieldCount,
|
long processedRecordCount, long processedFieldCount, long inputBytes, long inputFieldCount,
|
||||||
long invalidDateCount, long missingFieldCount, long outOfOrderTimeStampCount, long earliestRecordTime, long latestRecordTime) {
|
long invalidDateCount, long missingFieldCount, long outOfOrderTimeStampCount, long earliestRecordTime, long latestRecordTime,
|
||||||
|
long lastDataTime) {
|
||||||
|
|
||||||
DataCounts counts = new DataCounts("foo", processedRecordCount, processedFieldCount, inputBytes,
|
DataCounts counts = new DataCounts("foo", processedRecordCount, processedFieldCount, inputBytes,
|
||||||
inputFieldCount, invalidDateCount, missingFieldCount, outOfOrderTimeStampCount,
|
inputFieldCount, invalidDateCount, missingFieldCount, outOfOrderTimeStampCount,
|
||||||
new Date(earliestRecordTime), new Date(latestRecordTime));
|
new Date(earliestRecordTime), new Date(latestRecordTime), new Date(lastDataTime));
|
||||||
|
|
||||||
return counts;
|
return counts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ setup:
|
||||||
- is_true: jobs.0.node.name
|
- is_true: jobs.0.node.name
|
||||||
- is_true: jobs.0.node.transport_address
|
- is_true: jobs.0.node.transport_address
|
||||||
- match: { jobs.0.node.attributes.max_running_jobs: "10"}
|
- match: { jobs.0.node.attributes.max_running_jobs: "10"}
|
||||||
|
- gte: { jobs.0.open_time: 0}
|
||||||
|
|
||||||
---
|
---
|
||||||
"Test get job stats for closed job":
|
"Test get job stats for closed job":
|
||||||
|
@ -121,9 +122,10 @@ setup:
|
||||||
- gt: { jobs.0.model_size_stats.model_bytes: 0 }
|
- gt: { jobs.0.model_size_stats.model_bytes: 0 }
|
||||||
- match: { jobs.0.state: closed }
|
- match: { jobs.0.state: closed }
|
||||||
- is_false: jobs.0.node
|
- is_false: jobs.0.node
|
||||||
|
- is_false: jobs.0.open_time
|
||||||
|
|
||||||
---
|
---
|
||||||
"Test get job stats of datafeed job that has not received and data":
|
"Test get job stats of datafeed job that has not received any data":
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
xpack.ml.get_job_stats:
|
xpack.ml.get_job_stats:
|
||||||
|
@ -132,6 +134,7 @@ setup:
|
||||||
- match: { jobs.0.data_counts.processed_record_count: 0 }
|
- match: { jobs.0.data_counts.processed_record_count: 0 }
|
||||||
- match: { jobs.0.model_size_stats.model_bytes : 0 }
|
- match: { jobs.0.model_size_stats.model_bytes : 0 }
|
||||||
- match: { jobs.0.state: opened }
|
- match: { jobs.0.state: opened }
|
||||||
|
- gte: { jobs.0.open_time: 0}
|
||||||
|
|
||||||
---
|
---
|
||||||
"Test get all job stats explicitly":
|
"Test get all job stats explicitly":
|
||||||
|
|
Loading…
Reference in New Issue