Implement configuration file usage

A configuration file can be used to specify plugin properties.
Unwanted metrics can be disabled via the "exclude" property.

Change-Id: Ib4da8ba8ad5d6ba3f1cbb0b3f83375cfcef3af67
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/Configuration.java
new file mode 100644
index 0000000..efd075d
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/Configuration.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.googlesource.gerrit.plugins.metricsreporters;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Configuration {
+  private static final Logger log = LoggerFactory.getLogger(Configuration.class);
+
+  // configuration parameters
+  private static final String METRICS_SECTION = "metrics";
+  private static final String EXCLUDE_KEY = "exclude";
+
+  private final Set<String> excludes = new HashSet<>();
+
+  @Inject
+  public Configuration(@PluginName String pluginName, SitePaths site) {
+    Path pluginConfigFile = site.etc_dir.resolve(pluginName + ".config");
+
+    FileBasedConfig config = new FileBasedConfig(pluginConfigFile.toFile(), FS.DETECTED);
+
+    try {
+      config.load();
+      excludes.addAll(Arrays.asList(config.getStringList(METRICS_SECTION, null, EXCLUDE_KEY)));
+    } catch (IOException e) {
+      log.error("Failed to open configuration file '" + pluginConfigFile.toString() + "'");
+    } catch (ConfigInvalidException e) {
+      log.error("Failed to parse configuration file '" + pluginConfigFile.toString() + "'");
+    }
+  }
+
+  public Set<String> getExcludes() {
+    return excludes;
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritJmxReporter.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritJmxReporter.java
index cdfbb22..9935c67 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritJmxReporter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritJmxReporter.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.codahale.metrics.jmx.JmxReporter;
 import com.google.gerrit.extensions.annotations.Listen;
@@ -26,8 +28,26 @@
   private final JmxReporter reporter;
 
   @Inject
-  public GerritJmxReporter(MetricRegistry registry) {
-    this.reporter = JmxReporter.forRegistry(registry).build();
+  public GerritJmxReporter(MetricRegistry registry, Configuration config) {
+
+    /* Copy the registry to avoid filtering the global one */
+    MetricRegistry filteredRegistry = new MetricRegistry();
+    filteredRegistry.registerAll(registry);
+
+    config
+        .getExcludes()
+        .forEach(
+            exclude -> {
+              filteredRegistry.removeMatching(
+                  new MetricFilter() {
+                    @Override
+                    public boolean matches(String name, Metric metric) {
+                      return name.matches(exclude);
+                    }
+                  });
+            });
+
+    this.reporter = JmxReporter.forRegistry(filteredRegistry).build();
   }
 
   @Override
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
new file mode 100644
index 0000000..bf82194
--- /dev/null
+++ b/src/main/resources/Documentation/config.md
@@ -0,0 +1,19 @@
+@PLUGIN@ Configuration
+=========================
+
+The following fields can be specified in `$site_path/etc/@PLUGIN@.config` file:
+
+File '@PLUGIN@.config'
+--------------------
+
+### Exclude metrics
+
+```
+[metrics]
+  exclude = caches.*
+  exclude = events.*
+```
+
+```metrics.exclude```
+:   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.