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_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/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.SubmitTypeRecord;
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.server.index.OnlineReindexMode;
import com.google.gerrit.server.plugincontext.PluginSetContext;
@@ -44,6 +48,8 @@ public class SubmitRuleEvaluator {
private final ProjectCache projectCache;
private final PrologRule prologRule;
private final PluginSetContext<SubmitRule> submitRules;
private final Timer0 submitRuleEvaluationLatency;
private final Timer0 submitTypeEvaluationLatency;
private final SubmitRuleOptions opts;
public interface Factory {
@@ -56,10 +62,23 @@ public class SubmitRuleEvaluator {
ProjectCache projectCache,
PrologRule prologRule,
PluginSetContext<SubmitRule> submitRules,
MetricMaker metricMaker,
@Assisted SubmitRuleOptions options) {
this.projectCache = projectCache;
this.prologRule = prologRule;
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;
}
@@ -87,34 +106,36 @@ public class SubmitRuleEvaluator {
* @param cd ChangeData to evaluate
*/
public List<SubmitRecord> evaluate(ChangeData cd) {
Change change;
ProjectState projectState;
try {
change = cd.change();
if (change == null) {
throw new StorageException("Change not found");
try (Timer0.Context ignored = submitRuleEvaluationLatency.start()) {
Change change;
ProjectState projectState;
try {
change = cd.change();
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 (projectState == null) {
throw new NoSuchProjectException(cd.project());
if ((!opts.allowClosed() || OnlineReindexMode.isActive()) && change.isClosed()) {
SubmitRecord rec = new SubmitRecord();
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()) {
SubmitRecord rec = new SubmitRecord();
rec.status = SubmitRecord.Status.CLOSED;
return Collections.singletonList(rec);
// 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());
}
// 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) {
@@ -129,17 +150,19 @@ public class SubmitRuleEvaluator {
* @param cd
*/
public SubmitTypeRecord getSubmitType(ChangeData cd) {
ProjectState projectState;
try {
projectState = projectCache.get(cd.project());
if (projectState == null) {
throw new NoSuchProjectException(cd.project());
try (Timer0.Context ignored = submitTypeEvaluationLatency.start()) {
ProjectState projectState;
try {
projectState = projectCache.get(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) {