Instrument submit rule evaluation

This commit instruments the latency for submit rule evaluation and for
computing the submit type if done dynamically. We already have metrics
per SubmitRule through the plugin instrumentation, but also want to know
how long the total submit rule evaluation takes.

Change-Id: I18edf9840ddd5fe2c73cc584a4587b7bec47c67a
This commit is contained in:
Patrick Hiesel
2019-08-09 10:51:30 +02:00
parent 57bce3c662
commit 8b38428c2c
2 changed files with 60 additions and 32 deletions

View File

@@ -57,6 +57,11 @@ objects needing finalization.
* `caches/disk_cached`: Disk entries used by persistent cache. * `caches/disk_cached`: Disk entries used by persistent cache.
* `caches/disk_hit_ratio`: Disk hit ratio for persistent cache. * `caches/disk_hit_ratio`: Disk hit ratio for persistent cache.
=== Change
* `change/submit_rule_evaluation`: Latency for evaluating submit rules on a change.
* `change/submit_type_evaluation`: Latency for evaluating the submit type on a change.
=== HTTP === HTTP
* `http/server/error_count`: Rate of REST API error responses. * `http/server/error_count`: Rate of REST API error responses.

View File

@@ -19,6 +19,10 @@ import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.SubmitRecord; import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.common.data.SubmitTypeRecord; import com.google.gerrit.common.data.SubmitTypeRecord;
import com.google.gerrit.exceptions.StorageException; import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Description.Units;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.index.OnlineReindexMode; import com.google.gerrit.server.index.OnlineReindexMode;
import com.google.gerrit.server.plugincontext.PluginSetContext; import com.google.gerrit.server.plugincontext.PluginSetContext;
@@ -44,6 +48,8 @@ public class SubmitRuleEvaluator {
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final PrologRule prologRule; private final PrologRule prologRule;
private final PluginSetContext<SubmitRule> submitRules; private final PluginSetContext<SubmitRule> submitRules;
private final Timer0 submitRuleEvaluationLatency;
private final Timer0 submitTypeEvaluationLatency;
private final SubmitRuleOptions opts; private final SubmitRuleOptions opts;
public interface Factory { public interface Factory {
@@ -56,10 +62,23 @@ public class SubmitRuleEvaluator {
ProjectCache projectCache, ProjectCache projectCache,
PrologRule prologRule, PrologRule prologRule,
PluginSetContext<SubmitRule> submitRules, PluginSetContext<SubmitRule> submitRules,
MetricMaker metricMaker,
@Assisted SubmitRuleOptions options) { @Assisted SubmitRuleOptions options) {
this.projectCache = projectCache; this.projectCache = projectCache;
this.prologRule = prologRule; this.prologRule = prologRule;
this.submitRules = submitRules; this.submitRules = submitRules;
this.submitRuleEvaluationLatency =
metricMaker.newTimer(
"change/submit_rule_evaluation",
new Description("Latency for evaluating submit rules on a change.")
.setCumulative()
.setUnit(Units.MILLISECONDS));
this.submitTypeEvaluationLatency =
metricMaker.newTimer(
"change/submit_type_evaluation",
new Description("Latency for evaluating the submit type on a change.")
.setCumulative()
.setUnit(Units.MILLISECONDS));
this.opts = options; this.opts = options;
} }
@@ -87,34 +106,36 @@ public class SubmitRuleEvaluator {
* @param cd ChangeData to evaluate * @param cd ChangeData to evaluate
*/ */
public List<SubmitRecord> evaluate(ChangeData cd) { public List<SubmitRecord> evaluate(ChangeData cd) {
Change change; try (Timer0.Context ignored = submitRuleEvaluationLatency.start()) {
ProjectState projectState; Change change;
try { ProjectState projectState;
change = cd.change(); try {
if (change == null) { change = cd.change();
throw new StorageException("Change not found"); if (change == null) {
throw new StorageException("Change not found");
}
projectState = projectCache.get(cd.project());
if (projectState == null) {
throw new NoSuchProjectException(cd.project());
}
} catch (StorageException | NoSuchProjectException e) {
return ruleError("Error looking up change " + cd.getId(), e);
} }
projectState = projectCache.get(cd.project()); if ((!opts.allowClosed() || OnlineReindexMode.isActive()) && change.isClosed()) {
if (projectState == null) { SubmitRecord rec = new SubmitRecord();
throw new NoSuchProjectException(cd.project()); rec.status = SubmitRecord.Status.CLOSED;
return Collections.singletonList(rec);
} }
} catch (StorageException | NoSuchProjectException e) {
return ruleError("Error looking up change " + cd.getId(), e);
}
if ((!opts.allowClosed() || OnlineReindexMode.isActive()) && change.isClosed()) { // We evaluate all the plugin-defined evaluators,
SubmitRecord rec = new SubmitRecord(); // and then we collect the results in one list.
rec.status = SubmitRecord.Status.CLOSED; return Streams.stream(submitRules)
return Collections.singletonList(rec); .map(c -> c.call(s -> s.evaluate(cd)))
.flatMap(Collection::stream)
.collect(Collectors.toList());
} }
// We evaluate all the plugin-defined evaluators,
// and then we collect the results in one list.
return Streams.stream(submitRules)
.map(c -> c.call(s -> s.evaluate(cd)))
.flatMap(Collection::stream)
.collect(Collectors.toList());
} }
private List<SubmitRecord> ruleError(String err, Exception e) { private List<SubmitRecord> ruleError(String err, Exception e) {
@@ -129,17 +150,19 @@ public class SubmitRuleEvaluator {
* @param cd * @param cd
*/ */
public SubmitTypeRecord getSubmitType(ChangeData cd) { public SubmitTypeRecord getSubmitType(ChangeData cd) {
ProjectState projectState; try (Timer0.Context ignored = submitTypeEvaluationLatency.start()) {
try { ProjectState projectState;
projectState = projectCache.get(cd.project()); try {
if (projectState == null) { projectState = projectCache.get(cd.project());
throw new NoSuchProjectException(cd.project()); if (projectState == null) {
throw new NoSuchProjectException(cd.project());
}
} catch (NoSuchProjectException e) {
return typeError("Error looking up change " + cd.getId(), e);
} }
} catch (NoSuchProjectException e) {
return typeError("Error looking up change " + cd.getId(), e);
}
return prologRule.getSubmitType(cd); return prologRule.getSubmitType(cd);
}
} }
private SubmitTypeRecord typeError(String err, Exception e) { private SubmitTypeRecord typeError(String err, Exception e) {