Merge branch 'stable-2.16'

* stable-2.16:
  Add option to exclude metrics

Change-Id: I40b9b70476c67c4131d626542944ccbbaa4bee21
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
index a43a779..7387838 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
@@ -13,6 +13,8 @@
 // limitations under the License.
 package com.googlesource.gerrit.plugins.metricsreporters;
 
+import com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricFilter;
 import com.codahale.metrics.MetricRegistry;
 import com.google.common.base.Strings;
 import com.google.common.net.HttpHeaders;
@@ -24,7 +26,10 @@
 import io.prometheus.client.dropwizard.DropwizardExports;
 import io.prometheus.client.exporter.MetricsServlet;
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Optional;
+import java.util.Set;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -35,6 +40,7 @@
 @Singleton
 public class GerritPrometheusExporter extends MetricsServlet {
   private static final String PROMETHEUS_BEARER_TOKEN = "prometheusBearerToken";
+  private static final String EXCLUDE_KEY = "excludeMetrics";
 
   private final CapabilityChecker capabilityChecker;
   private final String prometheusBearerToken;
@@ -49,9 +55,28 @@
     this.prometheusBearerToken =
         cfgFactory.getFromGerritConfig(pluginName).getString(PROMETHEUS_BEARER_TOKEN);
 
+    /* Copy the registry to avoid filtering the global one */
+    MetricRegistry filteredRegistry = new MetricRegistry();
+    filteredRegistry.registerAll(registry);
+
+    Set<String> excludedMetrics = new HashSet<>();
+    excludedMetrics.addAll(
+        Arrays.asList(cfgFactory.getFromGerritConfig(pluginName).getStringList(EXCLUDE_KEY)));
+
+    excludedMetrics.forEach(
+        exclude -> {
+          filteredRegistry.removeMatching(
+              new MetricFilter() {
+                @Override
+                public boolean matches(String name, Metric metric) {
+                  return name.matches(exclude);
+                }
+              });
+        });
+
     // Hook the Dropwizard registry into the Prometheus registry
     // via the DropwizardExports collector.
-    CollectorRegistry.defaultRegistry.register(new DropwizardExports(registry));
+    CollectorRegistry.defaultRegistry.register(new DropwizardExports(filteredRegistry));
   }
 
   @Override
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index c8edf5c..f45f16f 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -24,6 +24,12 @@
 See [Prometheus documentation](https://prometheus.io/docs/prometheus/latest/configuration/configuration)
 for how to configure the integration with Prometheus.
 
+plugin.@PLUGIN@.excludeMetrics
+:   String used to exclude metrics from the report. It can be specified multiple times.
+    Parsed as regular expression. Note, ^ and $ are automatically added around the string.
+    By default no metric is excluded.
+    For example, to exclude all cache metrics, use: `excludeMetrics = cache.*`
+
 [Back to @PLUGIN@ documentation index][index]
 
 [index]: index.html