Add a --task--include-statistics flag
Add some task plugin statistics to the last change in the query when the
new --task--include-statistics flag is specified. This is intended to
help task configurators and system administrators profile task queries
to help improve their performance.
Change-Id: I708a5345be8369bec2c8cf5fbf2458ddb4a32023
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java b/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java
index 3a8d903..6f8d5cd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/Modules.java
@@ -61,6 +61,9 @@
@Option(name = "--evaluation-time", usage = "Include elapsed evaluation time on each task")
public boolean evaluationTime = false;
+ @Option(name = "--include-statistics", usage = "Include statistcs about the task evaluations")
+ public boolean includeStatistics = false;
+
@Option(
name = "--preview",
metaVar = "{CHANGE,PATCHSET}",
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
index 688faa2..e77b97a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
@@ -50,6 +50,12 @@
FAIL;
}
+ public static class Statistics {
+ public long numberOfChanges;
+ public long numberOfNodes;
+ public long numberOfTaskPluginAttributes;
+ }
+
public static class TaskAttribute {
public Boolean applicable;
public Map<String, String> exported;
@@ -69,12 +75,15 @@
public static class TaskPluginAttribute extends PluginDefinedInfo {
public List<TaskAttribute> roots = new ArrayList<>();
+ public Statistics queryStatistics;
}
protected final TaskTree definitions;
protected final PredicateCache predicateCache;
protected Modules.MyOptions options;
+ protected TaskPluginAttribute lastTaskPluginAttribute;
+ protected Statistics statistics;
@Inject
public TaskAttributeFactory(TaskTree definitions, PredicateCache predicateCache) {
@@ -88,10 +97,14 @@
Map<Change.Id, PluginDefinedInfo> pluginInfosByChange = new HashMap<>();
options = (Modules.MyOptions) beanProvider.getDynamicBean(plugin);
if (options.all || options.onlyApplicable || options.onlyInvalid) {
+ initStatistics();
for (PatchSetArgument psa : options.patchSetArguments) {
definitions.masquerade(psa);
}
cds.forEach(cd -> pluginInfosByChange.put(cd.getId(), createWithExceptions(cd)));
+ if (lastTaskPluginAttribute != null) {
+ lastTaskPluginAttribute.queryStatistics = getStatistics(pluginInfosByChange);
+ }
}
return pluginInfosByChange;
}
@@ -114,6 +127,7 @@
if (a.roots.isEmpty()) {
return null;
}
+ lastTaskPluginAttribute = a;
return a;
}
@@ -128,6 +142,9 @@
this.matchCache = matchCache;
this.task = node.task;
this.attribute = new TaskAttribute(task.name());
+ if (options.includeStatistics) {
+ statistics.numberOfNodes++;
+ }
}
public Optional<TaskAttribute> create() {
@@ -295,7 +312,22 @@
return System.nanoTime() / 1000000;
}
- protected TaskAttribute invalid() {
+ public void initStatistics() {
+ if (options.includeStatistics) {
+ statistics = new Statistics();
+ }
+ }
+
+ public Statistics getStatistics(Map<Change.Id, PluginDefinedInfo> pluginInfosByChange) {
+ if (statistics != null) {
+ statistics.numberOfChanges = pluginInfosByChange.size();
+ statistics.numberOfTaskPluginAttributes =
+ pluginInfosByChange.values().stream().filter(tpa -> tpa != null).count();
+ }
+ return statistics;
+ }
+
+ protected static TaskAttribute invalid() {
// For security reasons, do not expose the task name without knowing
// the visibility which is derived from its applicability.
TaskAttribute a = unknown();
@@ -303,13 +335,13 @@
return a;
}
- protected TaskAttribute unknown() {
+ protected static TaskAttribute unknown() {
TaskAttribute a = new TaskAttribute("UNKNOWN");
a.status = Status.UNKNOWN;
return a;
}
- protected String getHint(Status status, Task def) {
+ protected static String getHint(Status status, Task def) {
if (status != null) {
switch (status) {
case READY: