diff --git a/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/ResourceUsageInfo.java b/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/ResourceUsageInfo.java
index a278b61894a65..e7b51c3389b52 100644
--- a/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/ResourceUsageInfo.java
+++ b/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/ResourceUsageInfo.java
@@ -104,6 +104,10 @@ public long getTotalValue() {
return endValue.get() - startValue;
}
+ public long getStartValue() {
+ return startValue;
+ }
+
@Override
public String toString() {
return String.valueOf(getTotalValue());
diff --git a/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/TaskResourceInfo.java b/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/TaskResourceInfo.java
new file mode 100644
index 0000000000000..d22a6ffe1533c
--- /dev/null
+++ b/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/TaskResourceInfo.java
@@ -0,0 +1,104 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+package org.opensearch.core.tasks.resourcetracker;
+
+import org.opensearch.common.annotation.PublicApi;
+import org.opensearch.core.ParseField;
+import org.opensearch.core.common.Strings;
+import org.opensearch.core.common.io.stream.StreamInput;
+import org.opensearch.core.common.io.stream.StreamOutput;
+import org.opensearch.core.common.io.stream.Writeable;
+import org.opensearch.core.tasks.TaskId;
+import org.opensearch.core.xcontent.ConstructingObjectParser;
+import org.opensearch.core.xcontent.MediaTypeRegistry;
+import org.opensearch.core.xcontent.ToXContentFragment;
+import org.opensearch.core.xcontent.XContentBuilder;
+import org.opensearch.core.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import static org.opensearch.core.xcontent.ConstructingObjectParser.constructorArg;
+
+/**
+ * Task resource usage information with minimal information about the task
+ *
+ * Writeable TaskResourceInfo objects are used to represent resource usage
+ * information of running tasks, which can be propagated to coordinator node
+ * to infer query-level resource usage
+ *
+ * @opensearch.api
+ */
+@PublicApi(since = "2.1.0")
+public class TaskResourceInfo implements Writeable, ToXContentFragment {
+ public TaskResourceUsage taskResourceUsage;
+ public String action;
+ public long taskId;
+ public long parentTaskId;
+
+ public TaskResourceInfo() {
+ this.action = "";
+ this.taskId = -1L;
+ this.taskResourceUsage = new TaskResourceUsage(0, 0);
+ }
+
+ public TaskResourceInfo(String action, long taskId, long cpuTimeInNanos, long memoryInBytes) {
+ this.action = action;
+ this.taskId = taskId;
+ this.taskResourceUsage = new TaskResourceUsage(cpuTimeInNanos, memoryInBytes);
+ }
+
+ /**
+ * Read from a stream.
+ */
+ public static TaskResourceInfo readFromStream(StreamInput in) throws IOException {
+ TaskResourceInfo info = new TaskResourceInfo();
+ info.action = in.readString();
+ info.taskId = in.readLong();
+ info.taskResourceUsage = TaskResourceUsage.readFromStream(in);
+ info.parentTaskId = in.readLong();
+ return info;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeString(action);
+ out.writeLong(taskId);
+ taskResourceUsage.writeTo(out);
+ out.writeLong(parentTaskId);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ // TODO: change to a constant
+ builder.field("Action", action);
+ taskResourceUsage.toXContent(builder, params);
+ return builder;
+ }
+
+ @Override
+ public String toString() {
+ return Strings.toString(MediaTypeRegistry.JSON, this, false, true);
+ }
+
+ // Implements equals and hashcode for testing
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || obj.getClass() != TaskResourceInfo.class) {
+ return false;
+ }
+ TaskResourceInfo other = (TaskResourceInfo) obj;
+ return action.equals(other.action) && taskId == other.taskId && taskResourceUsage.equals(other.taskResourceUsage);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(action, taskId, taskResourceUsage);
+ }
+}
diff --git a/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/TaskResourceUsage.java b/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/TaskResourceUsage.java
index 654f1c5695937..d20fb62c90bb0 100644
--- a/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/TaskResourceUsage.java
+++ b/libs/core/src/main/java/org/opensearch/core/tasks/resourcetracker/TaskResourceUsage.java
@@ -90,7 +90,7 @@ public static TaskResourceUsage fromXContent(XContentParser parser) {
@Override
public String toString() {
- return Strings.toString(MediaTypeRegistry.JSON, this, true, true);
+ return Strings.toString(MediaTypeRegistry.JSON, this, false, true);
}
// Implements equals and hashcode for testing
diff --git a/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java b/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java
index cf2736a8583d2..a28a4f93f2826 100644
--- a/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java
+++ b/modules/analysis-common/src/main/java/org/opensearch/analysis/common/CommonAnalysisModulePlugin.java
@@ -153,6 +153,7 @@
import org.opensearch.repositories.RepositoriesService;
import org.opensearch.script.ScriptContext;
import org.opensearch.script.ScriptService;
+import org.opensearch.tasks.TaskResourceTrackingService;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.watcher.ResourceWatcherService;
@@ -187,7 +188,8 @@ public Collection