Allow plugin to be reloaded The plugin tries to register metrics every time is reloaded. This raises an exception since metrics might already be registered in the MetricRegistry. Avoid re-registering a metric if already present. Bug: Issue 16082 Change-Id: I616ec0f01cdf87efef15927401944e3473d21620
diff --git a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCache.java b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCache.java index f1d46b2..ced3ab2 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCache.java +++ b/src/main/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCache.java
@@ -14,6 +14,7 @@ package com.googlesource.gerrit.plugins.gitrepometrics; +import com.codahale.metrics.MetricRegistry; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Supplier; import com.google.common.collect.Maps; @@ -33,6 +34,7 @@ private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private Map<String, Long> metrics; private final MetricMaker metricMaker; + private final MetricRegistry metricRegistry; private final List<String> projects; private Map<String, Long> collectedAt; private final long gracePeriodMs; @@ -42,8 +44,13 @@ public static List<GitRepoMetric> metricsNames = new ArrayList<>(GitStats.availableMetrics()); @VisibleForTesting - GitRepoMetricsCache(MetricMaker metricMaker, GitRepoMetricsConfig config, Clock clock) { + GitRepoMetricsCache( + MetricMaker metricMaker, + MetricRegistry metricRegistry, + GitRepoMetricsConfig config, + Clock clock) { this.metricMaker = metricMaker; + this.metricRegistry = metricRegistry; this.projects = config.getRepositoryNames(); this.metrics = Maps.newHashMap(); this.collectedAt = Maps.newHashMap(); @@ -52,8 +59,9 @@ } @Inject - GitRepoMetricsCache(MetricMaker metricMaker, GitRepoMetricsConfig config) { - this(metricMaker, config, Clock.systemDefaultZone()); + GitRepoMetricsCache( + MetricMaker metricMaker, MetricRegistry metricRegistry, GitRepoMetricsConfig config) { + this(metricMaker, metricRegistry, config, Clock.systemDefaultZone()); } public Map<String, Long> getMetrics() { @@ -88,13 +96,19 @@ } }; - metricMaker.newCallbackMetric( - name, - Long.class, - new Description(gitRepoMetric.getDescription()) - .setRate() - .setUnit(gitRepoMetric.getUnit()), - supplier); + if (!metricRegistry + .getMetrics() + .containsKey( + GitRepoMetricsCache.getFullyQualifiedMetricName( + gitRepoMetric.getName(), projectName))) { + metricMaker.newCallbackMetric( + name, + Long.class, + new Description(gitRepoMetric.getDescription()) + .setRate() + .setUnit(gitRepoMetric.getUnit()), + supplier); + } }); }); } @@ -103,6 +117,12 @@ return String.format("%s_%s", metricName, projectName).toLowerCase(Locale.ROOT); } + @VisibleForTesting + static String getFullyQualifiedMetricName(String metricName, String projectName) { + return String.format( + "%s/%s/%s", "plugins", "git-repo-metrics", getMetricName(metricName, projectName)); + } + public boolean shouldCollectStats(String projectName) { long lastCollectionTime = collectedAt.getOrDefault(projectName, 0L); long currentTimeMs = System.currentTimeMillis();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheTest.java b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheTest.java index 70c2dd9..dcd9a88 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitRepoMetricsCacheTest.java
@@ -16,6 +16,8 @@ import static com.google.common.truth.Truth.assertThat; +import com.codahale.metrics.Metric; +import com.codahale.metrics.MetricRegistry; import com.google.common.collect.ImmutableMap; import com.google.gerrit.metrics.CallbackMetric0; import com.google.gerrit.metrics.Description; @@ -45,7 +47,30 @@ public void shouldRegisterMetrics() throws IOException { gitRepoMetricsConfig = configSetupUtils.getGitRepoMetricsConfig(); fakeMetricMaker = new FakeMetricMaker(); - gitRepoMetricsCache = new GitRepoMetricsCache(fakeMetricMaker, gitRepoMetricsConfig); + gitRepoMetricsCache = + new GitRepoMetricsCache(fakeMetricMaker, new MetricRegistry(), gitRepoMetricsConfig); + gitRepoMetricsCache.initCache(); + assertThat(fakeMetricMaker.callsCounter).isEqualTo(GitStats.availableMetrics().size()); + } + + @Test + public void shouldRegisterMetricsOnlyOnce() throws IOException { + gitRepoMetricsConfig = configSetupUtils.getGitRepoMetricsConfig(); + MetricRegistry metricRegistry = new MetricRegistry(); + fakeMetricMaker = new FakeMetricMaker(); + gitRepoMetricsCache = + new GitRepoMetricsCache(fakeMetricMaker, metricRegistry, gitRepoMetricsConfig); + + gitRepoMetricsCache.initCache(); + assertThat(fakeMetricMaker.callsCounter).isEqualTo(GitStats.availableMetrics().size()); + + GitRepoMetricsCache.metricsNames.forEach( + gitRepoMetric -> + metricRegistry.register( + GitRepoMetricsCache.getFullyQualifiedMetricName( + gitRepoMetric.getName(), enabledRepo), + new FakeMetric())); + gitRepoMetricsCache.initCache(); assertThat(fakeMetricMaker.callsCounter).isEqualTo(GitStats.availableMetrics().size()); } @@ -53,7 +78,8 @@ @Test public void shouldCollectStatsForEnabledRepo() throws IOException { gitRepoMetricsConfig = configSetupUtils.getGitRepoMetricsConfig(); - gitRepoMetricsCache = new GitRepoMetricsCache(new FakeMetricMaker(), gitRepoMetricsConfig); + gitRepoMetricsCache = + new GitRepoMetricsCache(new FakeMetricMaker(), new MetricRegistry(), gitRepoMetricsConfig); assertThat(gitRepoMetricsCache.shouldCollectStats(enabledRepo)).isTrue(); } @@ -62,7 +88,8 @@ public void shouldNotCollectStatsForDisabledRepo() throws IOException { String disabledRepo = "disabledRepo"; gitRepoMetricsConfig = configSetupUtils.getGitRepoMetricsConfig(); - gitRepoMetricsCache = new GitRepoMetricsCache(new FakeMetricMaker(), gitRepoMetricsConfig); + gitRepoMetricsCache = + new GitRepoMetricsCache(new FakeMetricMaker(), new MetricRegistry(), gitRepoMetricsConfig); assertThat(gitRepoMetricsCache.shouldCollectStats(disabledRepo)).isFalse(); } @@ -72,7 +99,8 @@ ConfigSetupUtils configSetupUtils = new ConfigSetupUtils(Collections.singletonList(enabledRepo)); gitRepoMetricsConfig = configSetupUtils.getGitRepoMetricsConfig(); - gitRepoMetricsCache = new GitRepoMetricsCache(new FakeMetricMaker(), gitRepoMetricsConfig); + gitRepoMetricsCache = + new GitRepoMetricsCache(new FakeMetricMaker(), new MetricRegistry(), gitRepoMetricsConfig); gitRepoMetricsCache.setMetrics(ImmutableMap.of("anyMetric", 0L), enabledRepo); @@ -84,7 +112,8 @@ ConfigSetupUtils configSetupUtils = new ConfigSetupUtils(Collections.singletonList(enabledRepo), "5 m"); gitRepoMetricsConfig = configSetupUtils.getGitRepoMetricsConfig(); - gitRepoMetricsCache = new GitRepoMetricsCache(new FakeMetricMaker(), gitRepoMetricsConfig); + gitRepoMetricsCache = + new GitRepoMetricsCache(new FakeMetricMaker(), new MetricRegistry(), gitRepoMetricsConfig); gitRepoMetricsCache.setMetrics(ImmutableMap.of("anyMetric", 0L), enabledRepo); @@ -99,6 +128,7 @@ gitRepoMetricsCache = new GitRepoMetricsCache( new FakeMetricMaker(), + new MetricRegistry(), gitRepoMetricsConfig, Clock.fixed( Instant.now().minus(2, ChronoUnit.SECONDS), Clock.systemDefaultZone().getZone())); @@ -113,7 +143,8 @@ ConfigSetupUtils configSetupUtils = new ConfigSetupUtils(Collections.singletonList(enabledRepo)); gitRepoMetricsConfig = configSetupUtils.getGitRepoMetricsConfig(); - gitRepoMetricsCache = new GitRepoMetricsCache(new FakeMetricMaker(), gitRepoMetricsConfig); + gitRepoMetricsCache = + new GitRepoMetricsCache(new FakeMetricMaker(), new MetricRegistry(), gitRepoMetricsConfig); long currentTimeStamp = System.currentTimeMillis(); @@ -144,4 +175,8 @@ }; } } + + private class FakeMetric implements Metric { + FakeMetric() {} + } }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitUpdateListenerTest.java b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitUpdateListenerTest.java index 0747b23..f6cdb11 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitUpdateListenerTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/GitUpdateListenerTest.java
@@ -19,6 +19,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; +import com.codahale.metrics.MetricRegistry; import com.google.gerrit.entities.Project; import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.api.changes.NotifyHandling; @@ -64,7 +65,9 @@ new ConfigSetupUtils(Collections.singletonList(testProject)); gitRepoMetricsCache = new GitRepoMetricsCache( - new DisabledMetricMaker(), configSetupUtils.getGitRepoMetricsConfig()); + new DisabledMetricMaker(), + new MetricRegistry(), + configSetupUtils.getGitRepoMetricsConfig()); AbstractModule m = new AbstractModule() {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTaskTest.java b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTaskTest.java index d27c22f..45fb988 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTaskTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/gitrepometrics/UpdateGitMetricsTaskTest.java
@@ -17,6 +17,7 @@ import static com.google.common.truth.Truth.assertThat; import static java.nio.file.Files.delete; +import com.codahale.metrics.MetricRegistry; import com.google.gerrit.entities.Project; import com.google.gerrit.metrics.DisabledMetricMaker; import com.google.gerrit.server.config.GerritServerConfig; @@ -49,7 +50,9 @@ ConfigSetupUtils configSetupUtils = new ConfigSetupUtils(Collections.singletonList("repo1")); gitRepoMetricsCache = new GitRepoMetricsCache( - new DisabledMetricMaker(), configSetupUtils.getGitRepoMetricsConfig()); + new DisabledMetricMaker(), + new MetricRegistry(), + configSetupUtils.getGitRepoMetricsConfig()); AbstractModule m = new AbstractModule() {