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: