Add start time and duration to tasks

Tasks now contain timestamps indicating when the tasks were created and current run time
This commit is contained in:
Igor Motov 2016-02-26 14:12:56 -05:00
parent e1b5ebb46c
commit 863fab4007
4 changed files with 75 additions and 3 deletions

View File

@ -29,6 +29,7 @@ import org.elasticsearch.tasks.Task;
import org.elasticsearch.tasks.TaskId; import org.elasticsearch.tasks.TaskId;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.TimeUnit;
/** /**
* Information about a currently running task. * Information about a currently running task.
@ -50,17 +51,24 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
private final String description; private final String description;
private final long startTime;
private final long runningTimeNanos;
private final Task.Status status; private final Task.Status status;
private final TaskId parentTaskId; private final TaskId parentTaskId;
public TaskInfo(DiscoveryNode node, long id, String type, String action, String description, Task.Status status, TaskId parentTaskId) { public TaskInfo(DiscoveryNode node, long id, String type, String action, String description, Task.Status status, long startTime,
long runningTimeNanos, TaskId parentTaskId) {
this.node = node; this.node = node;
this.taskId = new TaskId(node.getId(), id); this.taskId = new TaskId(node.getId(), id);
this.type = type; this.type = type;
this.action = action; this.action = action;
this.description = description; this.description = description;
this.status = status; this.status = status;
this.startTime = startTime;
this.runningTimeNanos = runningTimeNanos;
this.parentTaskId = parentTaskId; this.parentTaskId = parentTaskId;
} }
@ -75,6 +83,8 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
} else { } else {
status = null; status = null;
} }
startTime = in.readLong();
runningTimeNanos = in.readLong();
parentTaskId = new TaskId(in); parentTaskId = new TaskId(in);
} }
@ -110,6 +120,23 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
return status; return status;
} }
/**
* Returns the task start time
*/
public long getStartTime() {
return startTime;
}
/**
* Returns the task running time
*/
public long getRunningTimeNanos() {
return runningTimeNanos;
}
/**
* Returns the parent task id
*/
public TaskId getParentTaskId() { public TaskId getParentTaskId() {
return parentTaskId; return parentTaskId;
} }
@ -132,6 +159,8 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
} else { } else {
out.writeBoolean(false); out.writeBoolean(false);
} }
out.writeLong(startTime);
out.writeLong(runningTimeNanos);
parentTaskId.writeTo(out); parentTaskId.writeTo(out);
} }
@ -147,6 +176,8 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
if (description != null) { if (description != null) {
builder.field("description", description); builder.field("description", description);
} }
builder.dateValueField("start_time_in_millis", "start_time", startTime);
builder.timeValueField("running_time_in_nanos", "running_time", runningTimeNanos, TimeUnit.NANOSECONDS);
if (parentTaskId.isSet() == false) { if (parentTaskId.isSet() == false) {
builder.field("parent_task_id", parentTaskId.toString()); builder.field("parent_task_id", parentTaskId.toString());
} }

View File

@ -48,7 +48,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.concurrent.TimeUnit;
/** /**
* *
@ -961,6 +961,23 @@ public final class XContentBuilder implements BytesStream, Releasable {
return this; return this;
} }
public XContentBuilder timeValueField(String rawFieldName, String readableFieldName, long rawTime, TimeUnit timeUnit) throws
IOException {
if (humanReadable) {
field(readableFieldName, new TimeValue(rawTime, timeUnit).toString());
}
field(rawFieldName, rawTime);
return this;
}
public XContentBuilder dateValueField(String rawFieldName, String readableFieldName, long rawTimestamp) throws IOException {
if (humanReadable) {
field(readableFieldName, defaultDatePrinter.print(rawTimestamp));
}
field(rawFieldName, rawTimestamp);
return this;
}
public XContentBuilder byteSizeField(XContentBuilderString rawFieldName, XContentBuilderString readableFieldName, ByteSizeValue byteSizeValue) throws IOException { public XContentBuilder byteSizeField(XContentBuilderString rawFieldName, XContentBuilderString readableFieldName, ByteSizeValue byteSizeValue) throws IOException {
if (humanReadable) { if (humanReadable) {
field(readableFieldName, byteSizeValue.toString()); field(readableFieldName, byteSizeValue.toString());

View File

@ -40,16 +40,26 @@ public class Task {
private final TaskId parentTask; private final TaskId parentTask;
private final long startTime;
private final long startTimeNanos;
public Task(long id, String type, String action, String description) { public Task(long id, String type, String action, String description) {
this(id, type, action, description, TaskId.EMPTY_TASK_ID); this(id, type, action, description, TaskId.EMPTY_TASK_ID);
} }
public Task(long id, String type, String action, String description, TaskId parentTask) { public Task(long id, String type, String action, String description, TaskId parentTask) {
this(id, type, action, description, parentTask, System.currentTimeMillis(), System.nanoTime());
}
public Task(long id, String type, String action, String description, TaskId parentTask, long startTime, long startTimeNanos) {
this.id = id; this.id = id;
this.type = type; this.type = type;
this.action = action; this.action = action;
this.description = description; this.description = description;
this.parentTask = parentTask; this.parentTask = parentTask;
this.startTime = startTime;
this.startTimeNanos = startTimeNanos;
} }
/** /**
@ -69,7 +79,8 @@ public class Task {
description = getDescription(); description = getDescription();
status = getStatus(); status = getStatus();
} }
return new TaskInfo(node, getId(), getType(), getAction(), description, status, parentTask); return new TaskInfo(node, getId(), getType(), getAction(), description, status, startTime, System.nanoTime() - startTimeNanos,
parentTask);
} }
/** /**
@ -100,6 +111,13 @@ public class Task {
return description; return description;
} }
/**
* Returns the task start time
*/
public long getStartTime() {
return startTime;
}
/** /**
* Returns id of the parent task or NO_PARENT_ID if the task doesn't have any parent tasks * Returns id of the parent task or NO_PARENT_ID if the task doesn't have any parent tasks
*/ */

View File

@ -63,6 +63,7 @@ import java.util.concurrent.atomic.AtomicReference;
import static org.elasticsearch.action.support.PlainActionFuture.newFuture; import static org.elasticsearch.action.support.PlainActionFuture.newFuture;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
public class TransportTasksActionTests extends TaskManagerTestCase { public class TransportTasksActionTests extends TaskManagerTestCase {
@ -461,10 +462,12 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
} }
public void testTasksDescriptions() throws Exception { public void testTasksDescriptions() throws Exception {
long minimalStartTime = System.currentTimeMillis();
setupTestNodes(Settings.EMPTY); setupTestNodes(Settings.EMPTY);
connectNodes(testNodes); connectNodes(testNodes);
CountDownLatch checkLatch = new CountDownLatch(1); CountDownLatch checkLatch = new CountDownLatch(1);
ActionFuture<NodesResponse> future = startBlockingTestNodesAction(checkLatch); ActionFuture<NodesResponse> future = startBlockingTestNodesAction(checkLatch);
long maximumStartTimeNanos = System.nanoTime();
// Check task counts using transport with filtering // Check task counts using transport with filtering
TestNode testNode = testNodes[randomIntBetween(0, testNodes.length - 1)]; TestNode testNode = testNodes[randomIntBetween(0, testNodes.length - 1)];
@ -478,12 +481,15 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
} }
// Check task counts using transport with detailed description // Check task counts using transport with detailed description
long minimalDurationNanos = System.nanoTime() - maximumStartTimeNanos;
listTasksRequest.detailed(true); // same request only with detailed description listTasksRequest.detailed(true); // same request only with detailed description
response = testNode.transportListTasksAction.execute(listTasksRequest).get(); response = testNode.transportListTasksAction.execute(listTasksRequest).get();
assertEquals(testNodes.length, response.getPerNodeTasks().size()); assertEquals(testNodes.length, response.getPerNodeTasks().size());
for (Map.Entry<DiscoveryNode, List<TaskInfo>> entry : response.getPerNodeTasks().entrySet()) { for (Map.Entry<DiscoveryNode, List<TaskInfo>> entry : response.getPerNodeTasks().entrySet()) {
assertEquals(1, entry.getValue().size()); assertEquals(1, entry.getValue().size());
assertEquals("CancellableNodeRequest[Test Request, true]", entry.getValue().get(0).getDescription()); assertEquals("CancellableNodeRequest[Test Request, true]", entry.getValue().get(0).getDescription());
assertThat(entry.getValue().get(0).getStartTime(), greaterThanOrEqualTo(minimalStartTime));
assertThat(entry.getValue().get(0).getRunningTimeNanos(), greaterThanOrEqualTo(minimalDurationNanos));
} }
// Release all tasks and wait for response // Release all tasks and wait for response