Merge branch 'stable-2.15' into stable-2.16
* stable-2.15:
Add option to exclude metrics
Change-Id: I54c39fbff22495155aa48daeb4e518c6f817aea8
diff --git a/BUILD b/BUILD
index 89cb6c3..ee7c4fb 100644
--- a/BUILD
+++ b/BUILD
@@ -5,8 +5,8 @@
srcs = glob(["src/main/java/**/*.java"]),
manifest_entries = [
"Gerrit-PluginName: metrics-reporter-prometheus",
- "Gerrit-Module: com.googlesource.gerrit.plugins.metricsreporters.GerritPrometheusModule",
- "Gerrit-HttpModule: com.googlesource.gerrit.plugins.metricsreporters.GerritPrometheusHttpModule",
+ "Gerrit-Module: com.googlesource.gerrit.plugins.metricsreporterprometheus.GerritPrometheusModule",
+ "Gerrit-HttpModule: com.googlesource.gerrit.plugins.metricsreporterprometheus.GerritPrometheusHttpModule",
],
resources = glob(["src/main/resources/**/*"]),
deps = [
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/CapabilityChecker.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/CapabilityChecker.java
similarity index 94%
rename from src/main/java/com/googlesource/gerrit/plugins/metricsreporters/CapabilityChecker.java
rename to src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/CapabilityChecker.java
index ae7bc93..f1b936e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/CapabilityChecker.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/CapabilityChecker.java
@@ -11,7 +11,7 @@
// 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;
+package com.googlesource.gerrit.plugins.metricsreporterprometheus;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.extensions.annotations.PluginName;
@@ -44,7 +44,7 @@
public boolean canViewMetrics() {
try {
permissionBackend
- .user(userProvider)
+ .user(userProvider.get())
.checkAny(
ImmutableSet.of(
GlobalPermission.ADMINISTRATE_SERVER,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/FilteredMetricRegistry.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/FilteredMetricRegistry.java
new file mode 100644
index 0000000..87cdcbd
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/FilteredMetricRegistry.java
@@ -0,0 +1,61 @@
+// Copyright (C) 2020 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.metricsreporterprometheus;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricFilter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Timer;
+import java.util.SortedMap;
+import java.util.function.Predicate;
+
+public class FilteredMetricRegistry extends MetricRegistry {
+ private final MetricRegistry registry;
+ private final MetricFilter nonExcluded;
+
+ FilteredMetricRegistry(MetricRegistry registry, Predicate<String> exclusionFilter) {
+ this.registry = registry;
+ this.nonExcluded = (n, m) -> !exclusionFilter.test(n);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public SortedMap<String, Gauge> getGauges() {
+ return registry.getGauges(nonExcluded);
+ }
+
+ @Override
+ public SortedMap<String, Counter> getCounters() {
+ return registry.getCounters(nonExcluded);
+ }
+
+ @Override
+ public SortedMap<String, Histogram> getHistograms() {
+ return registry.getHistograms(nonExcluded);
+ }
+
+ @Override
+ public SortedMap<String, Timer> getTimers() {
+ return registry.getTimers(nonExcluded);
+ }
+
+ @Override
+ public SortedMap<String, Meter> getMeters() {
+ return registry.getMeters(nonExcluded);
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritBuildInformationMetric.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritBuildInformationMetric.java
new file mode 100644
index 0000000..0f567b5
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritBuildInformationMetric.java
@@ -0,0 +1,65 @@
+// Copyright (C) 2020 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.metricsreporterprometheus;
+
+import com.google.gerrit.common.Version;
+import io.prometheus.client.Counter;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+
+public class GerritBuildInformationMetric {
+ static final Counter requests =
+ Counter.build()
+ .name("gerrit_build_info")
+ .help("Gerrit build information.")
+ .labelNames("javaversion", "version", "revision")
+ .register();
+
+ public void compute() {
+ GerritVersionInfo versionInfo = extractVersionComponents();
+ requests.labels(getJavaVersion(), versionInfo.version, versionInfo.revision);
+ }
+
+ private static String getJavaVersion() {
+ RuntimeMXBean mxBean = ManagementFactory.getRuntimeMXBean();
+ return String.format("%s(%s)", mxBean.getSpecVersion(), mxBean.getVmVersion());
+ }
+
+ private static GerritVersionInfo extractVersionComponents() {
+ GerritVersionInfo versionInfo = new GerritVersionInfo();
+ String fullVersion = Version.getVersion();
+
+ if (fullVersion == null) {
+ return versionInfo;
+ }
+
+ String[] versionComponents = fullVersion.split("-");
+
+ versionInfo.version = versionComponents[0];
+
+ if (versionComponents.length > 2) {
+ versionInfo.revision = versionComponents.length > 2 ? versionComponents[2].substring(1) : "";
+ } else {
+ versionInfo.revision = "";
+ }
+
+ return versionInfo;
+ }
+
+ private static class GerritVersionInfo {
+ String revision = "unknown";
+ String version = "unknown";
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusExporter.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusExporter.java
new file mode 100644
index 0000000..0dba67a
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusExporter.java
@@ -0,0 +1,96 @@
+// Copyright (C) 2018 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.metricsreporterprometheus;
+
+import static java.util.stream.Collectors.toList;
+
+import com.codahale.metrics.MetricRegistry;
+import com.google.common.base.Strings;
+import com.google.common.net.HttpHeaders;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import io.prometheus.client.CollectorRegistry;
+import io.prometheus.client.dropwizard.DropwizardExports;
+import io.prometheus.client.exporter.MetricsServlet;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Pattern;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@SuppressWarnings("serial")
+@Singleton
+public class GerritPrometheusExporter extends MetricsServlet {
+ private static final String PROMETHEUS_BEARER_TOKEN = "prometheusBearerToken";
+ private static final String EXCLUDE_KEY = "excludeMetrics";
+
+ private final GerritBuildInformationMetric gerritBuildInfoMetric;
+ private final CapabilityChecker capabilityChecker;
+ private final String prometheusBearerToken;
+
+ @Inject
+ public GerritPrometheusExporter(
+ MetricRegistry registry,
+ CapabilityChecker capabilityChecker,
+ PluginConfigFactory cfgFactory,
+ @PluginName String pluginName) {
+ this.capabilityChecker = capabilityChecker;
+ this.prometheusBearerToken =
+ cfgFactory.getFromGerritConfig(pluginName).getString(PROMETHEUS_BEARER_TOKEN);
+ this.gerritBuildInfoMetric = new GerritBuildInformationMetric();
+
+ List<Pattern> excludes =
+ Arrays.stream(cfgFactory.getFromGerritConfig(pluginName).getStringList(EXCLUDE_KEY))
+ .map(Pattern::compile)
+ .collect(toList());
+
+ FilteredMetricRegistry filteredRegistry =
+ new FilteredMetricRegistry(
+ registry, s -> excludes.stream().anyMatch(e -> e.matcher(s).matches()));
+
+ // Hook the Dropwizard registry into the Prometheus registry
+ // via the DropwizardExports collector.
+ CollectorRegistry.defaultRegistry.register(new DropwizardExports(filteredRegistry));
+ }
+
+ @Override
+ public void service(ServletRequest req, ServletResponse res)
+ throws ServletException, IOException {
+ if (capabilityChecker.canViewMetrics() || canExportUsingPrometheusBearerToken(req)) {
+ gerritBuildInfoMetric.compute();
+ super.service(req, res);
+ } else {
+ HttpServletResponse httpResponse = (HttpServletResponse) res;
+ httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden access");
+ }
+ }
+
+ private boolean canExportUsingPrometheusBearerToken(ServletRequest req) {
+ if (Strings.isNullOrEmpty(prometheusBearerToken)) {
+ return false;
+ }
+
+ HttpServletRequest httpRequest = (HttpServletRequest) req;
+ return Optional.ofNullable(httpRequest.getHeader(HttpHeaders.AUTHORIZATION))
+ .map(h -> h.equals("Bearer " + prometheusBearerToken))
+ .orElse(false);
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusHttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusHttpModule.java
similarity index 92%
rename from src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusHttpModule.java
rename to src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusHttpModule.java
index 5764c38..0a2a625 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusHttpModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusHttpModule.java
@@ -11,7 +11,7 @@
// 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;
+package com.googlesource.gerrit.plugins.metricsreporterprometheus;
import com.google.inject.servlet.ServletModule;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusModule.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusModule.java
similarity index 93%
rename from src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusModule.java
rename to src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusModule.java
index 36c8663..591e81e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusModule.java
@@ -11,7 +11,7 @@
// 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;
+package com.googlesource.gerrit.plugins.metricsreporterprometheus;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.gerrit.extensions.config.CapabilityDefinition;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/ViewMetricsCapability.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/ViewMetricsCapability.java
similarity index 92%
rename from src/main/java/com/googlesource/gerrit/plugins/metricsreporters/ViewMetricsCapability.java
rename to src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/ViewMetricsCapability.java
index c3d22e0..8bb5157 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/ViewMetricsCapability.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/ViewMetricsCapability.java
@@ -11,7 +11,7 @@
// 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;
+package com.googlesource.gerrit.plugins.metricsreporterprometheus;
import com.google.gerrit.extensions.config.CapabilityDefinition;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
deleted file mode 100644
index 217badb..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritPrometheusExporter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2018 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.codahale.metrics.Metric;
-import com.codahale.metrics.MetricFilter;
-import com.codahale.metrics.MetricRegistry;
-import com.google.gerrit.extensions.annotations.PluginName;
-import com.google.gerrit.server.config.PluginConfigFactory;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import io.prometheus.client.CollectorRegistry;
-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.Set;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-
-@SuppressWarnings("serial")
-@Singleton
-public class GerritPrometheusExporter extends MetricsServlet {
- CapabilityChecker capabilityChecker;
- private static final String EXCLUDE_KEY = "excludeMetrics";
-
- @Inject
- public GerritPrometheusExporter(
- MetricRegistry registry,
- CapabilityChecker capabilityChecker,
- PluginConfigFactory cfgFactory,
- @PluginName String pluginName) {
- this.capabilityChecker = capabilityChecker;
-
- /* 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(filteredRegistry));
- }
-
- @Override
- public void service(ServletRequest req, ServletResponse res)
- throws ServletException, IOException {
- if (capabilityChecker.canViewMetrics()) {
- super.service(req, res);
- } else {
- HttpServletResponse httpResponse = (HttpServletResponse) res;
- httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden access");
- }
- }
-};
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 0092de0..96f347e 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -4,4 +4,5 @@
To access the monitoring URL, a user must be a member of a group that is granted
the ‘View Metrics’ capability (provided by this plugin) or the ‘Administrate
-Server’ capability.
\ No newline at end of file
+Server’ capability. Alternatively, authentication using prometheus bearer token
+is also supported.
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index df13ebc..3550c50 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -26,7 +26,7 @@
The output is created in
```
- bazel-genfiles/plugins/@PLUGIN@/@PLUGIN@.jar
+ bazel-bin/plugins/@PLUGIN@/@PLUGIN@.jar
```
This project can be imported into the Eclipse IDE.
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 265a6c7..070151f 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -1,9 +1,13 @@
Configuration
=============
+The configuration of the @PLUGIN@ plugin is done in the `gerrit.config`
+file.
+
To access the monitoring URL, a user must be a member of a group that is granted
the ‘View Metrics’ capability (provided by this plugin) or the ‘Administrate
-Server’ capability.This plugin requires no configuration.
+Server’ capability. Alternatively, authentication using prometheus bearer token
+is also supported.
This capability can be configured in the 'Global Capabilities' section of the
['All-Projects'](@URL@#/admin/projects/All-Projects,access) access right.
@@ -11,12 +15,22 @@
It is possible to allow anonymous access to the metrics by giving the capability
to the 'Anonymous Users' group.
+plugin.@PLUGIN@.prometheusBearerToken
+: Bearer token for allowing Prometheus to query Gerrit metrics through its scraper.
+ Defaults to undefine.
+
+When defined, access to the plugins/@PLUGIN@/metrics URL does not require any
+authentication and do not check any ACL related to the ‘View Metrics’ global capability.
+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.
+: Regex pattern used to exclude metrics from the report. It can be specified multiple times.
+ Note that pattern matching is done on the whole metric name, not only on a part of it.
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
\ No newline at end of file
+[index]: index.html