Add metrics to count the number of OWNERS cache/backend loads per change
With these new metrics we want to record how many OWNERS files we need
to cache/load per change when computing file code owner statuses. E.g.
this can help us understand better how much memory gets used by the
TransientCodeOwnerConfigCache.
Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: I40f1eaae058ab69b93905a5fba5e81fd2b4e702f
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheck.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheck.java
index c25fe52..897131a 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheck.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerApprovalCheck.java
@@ -289,23 +289,30 @@
FallbackCodeOwners fallbackCodeOwners = codeOwnersConfig.getFallbackCodeOwners();
CodeOwnerConfigHierarchy codeOwnerConfigHierarchy = codeOwnerConfigHierarchyProvider.get();
- return changedFiles
- .compute(changeNotes.getProjectName(), changeNotes.getCurrentPatchSet().commitId())
- .stream()
- .map(
- changedFile ->
- getFileStatus(
- codeOwnerConfigHierarchy,
- branch,
- revision,
- globalCodeOwners,
- enableImplicitApprovalFromUploader,
- patchSetUploader,
- reviewerAccountIds,
- approverAccountIds,
- fallbackCodeOwners,
- hasOverride,
- changedFile));
+ try {
+ return changedFiles
+ .compute(changeNotes.getProjectName(), changeNotes.getCurrentPatchSet().commitId())
+ .stream()
+ .map(
+ changedFile ->
+ getFileStatus(
+ codeOwnerConfigHierarchy,
+ branch,
+ revision,
+ globalCodeOwners,
+ enableImplicitApprovalFromUploader,
+ patchSetUploader,
+ reviewerAccountIds,
+ approverAccountIds,
+ fallbackCodeOwners,
+ hasOverride,
+ changedFile));
+ } finally {
+ codeOwnerMetrics.codeOwnerConfigBackendReadsPerChange.record(
+ codeOwnerConfigHierarchy.getCodeOwnerConfigCounters().getBackendReadCount());
+ codeOwnerMetrics.codeOwnerConfigCacheReadsPerChange.record(
+ codeOwnerConfigHierarchy.getCodeOwnerConfigCounters().getCacheReadCount());
+ }
}
}
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchy.java b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchy.java
index 6b4da27..6ce1a87 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchy.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/CodeOwnerConfigHierarchy.java
@@ -234,4 +234,9 @@
String.format("failed to read %s", metaCodeOwnerConfigKey), e);
}
}
+
+ /** Returns the counters for cache and backend reads of code owner config files. */
+ public TransientCodeOwnerConfigCache.Counters getCodeOwnerConfigCounters() {
+ return transientCodeOwnerConfigCache.getCounters();
+ }
}
diff --git a/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java b/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java
index 96e0a31..61f014b 100644
--- a/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java
+++ b/java/com/google/gerrit/plugins/codeowners/backend/TransientCodeOwnerConfigCache.java
@@ -38,7 +38,7 @@
public class TransientCodeOwnerConfigCache implements CodeOwnerConfigLoader {
private final GitRepositoryManager repoManager;
private final CodeOwners codeOwners;
- private final CodeOwnerMetrics codeOwnerMetrics;
+ private final Counters counters;
private final HashMap<CacheKey, Optional<CodeOwnerConfig>> cache = new HashMap<>();
@Inject
@@ -46,7 +46,7 @@
GitRepositoryManager repoManager, CodeOwners codeOwners, CodeOwnerMetrics codeOwnerMetrics) {
this.repoManager = repoManager;
this.codeOwners = codeOwners;
- this.codeOwnerMetrics = codeOwnerMetrics;
+ this.counters = new Counters(codeOwnerMetrics);
}
/**
@@ -59,7 +59,7 @@
CacheKey cacheKey = CacheKey.create(codeOwnerConfigKey, revision);
Optional<CodeOwnerConfig> cachedCodeOwnerConfig = cache.get(cacheKey);
if (cachedCodeOwnerConfig != null) {
- codeOwnerMetrics.countCodeOwnerConfigCacheReads.increment();
+ counters.incrementCacheReads();
return cachedCodeOwnerConfig;
}
return loadAndCache(cacheKey);
@@ -76,6 +76,7 @@
/** Load a code owner config and puts it into the cache. */
private Optional<CodeOwnerConfig> loadAndCache(CacheKey cacheKey) {
+ counters.incrementBackendReads();
Optional<CodeOwnerConfig> codeOwnerConfig;
if (cacheKey.revision().isPresent()) {
codeOwnerConfig = codeOwners.get(cacheKey.codeOwnerConfigKey(), cacheKey.revision().get());
@@ -128,4 +129,38 @@
codeOwnerConfigKey, Optional.ofNullable(revision));
}
}
+
+ public Counters getCounters() {
+ return counters;
+ }
+
+ public static class Counters {
+ private final CodeOwnerMetrics codeOwnerMetrics;
+
+ private int cacheReadCount;
+ private int backendReadCount;
+
+ private Counters(CodeOwnerMetrics codeOwnerMetrics) {
+ this.codeOwnerMetrics = codeOwnerMetrics;
+ }
+
+ private void incrementCacheReads() {
+ codeOwnerMetrics.countCodeOwnerConfigCacheReads.increment();
+ cacheReadCount++;
+ }
+
+ private void incrementBackendReads() {
+ // we do not increase the countCodeOwnerConfigReads metric here, since this is already done in
+ // CodeOwners
+ backendReadCount++;
+ }
+
+ public int getBackendReadCount() {
+ return backendReadCount;
+ }
+
+ public int getCacheReadCount() {
+ return cacheReadCount;
+ }
+ }
}
diff --git a/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java b/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java
index 56aec3c..5d523a6 100644
--- a/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java
+++ b/java/com/google/gerrit/plugins/codeowners/metrics/CodeOwnerMetrics.java
@@ -18,6 +18,7 @@
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Description.Units;
import com.google.gerrit.metrics.Field;
+import com.google.gerrit.metrics.Histogram0;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.metrics.Timer1;
@@ -41,7 +42,9 @@
public final Timer0 resolvePathCodeOwners;
public final Timer0 runCodeOwnerSubmitRule;
- // code owner config latency metrics
+ // code owner config metrics
+ public final Histogram0 codeOwnerConfigBackendReadsPerChange;
+ public final Histogram0 codeOwnerConfigCacheReadsPerChange;
public final Timer1<String> loadCodeOwnerConfig;
public final Timer0 readCodeOwnerConfig;
public final Timer1<String> parseCodeOwnerConfig;
@@ -102,7 +105,15 @@
createLatencyTimer(
"run_code_owner_submit_rule", "Latency for running the code owner submit rule");
- // code owner config latency metrics
+ // code owner config metrics
+ this.codeOwnerConfigBackendReadsPerChange =
+ createHistogram(
+ "code_owner_config_backend_reads_per_change",
+ "Number of code owner config backend reads per change");
+ this.codeOwnerConfigCacheReadsPerChange =
+ createHistogram(
+ "code_owner_config_cache_reads_per_change",
+ "Number of code owner config cache reads per change");
this.loadCodeOwnerConfig =
createTimerWithClassField(
"load_code_owner_config",
@@ -151,4 +162,9 @@
private Counter0 createCounter(String name, String description) {
return metricMaker.newCounter("code_owners/" + name, new Description(description).setRate());
}
+
+ private Histogram0 createHistogram(String name, String description) {
+ return metricMaker.newHistogram(
+ "code_owners/" + name, new Description(description).setCumulative());
+ }
}
diff --git a/resources/Documentation/metrics.md b/resources/Documentation/metrics.md
index 3abb6f8..8e6ee6d 100644
--- a/resources/Documentation/metrics.md
+++ b/resources/Documentation/metrics.md
@@ -30,8 +30,12 @@
* `run_code_owner_submit_rule`:
Latency for running the code owner submit rule.
-### <a id="codeOwnerConfigLatencyMetrics"> Code Owner Config Latency Metrics
+## <a id="codeOwnerConfigMetrics"> Code Owner Config Metrics
+* `code_owner_config_cache_reads_per_change`:
+ Number of code owner config cache reads per change.
+* `code_owner_config_backend_reads_per_change`:
+ Number of code owner config backend reads per change.
* `load_code_owner_config`:
Latency for loading a code owner config file (read + parse).
* `parse_code_owner_config`: