Add Metric containing Gerrit and Java version information

So far the Gerrit version could not be retrieved from Prometheus,
when using it to store metrics.

The version information can be send to Prometheus with a trick by
setting this information as label values in an otherwise static
metric. The labels can then be extracted and viewed in a table,
e.g. in Grafana. This allows to associate the Gerrit version with
the metrics measured at the same timeframe.

This change adds the gerrit_build_info metric with the labels:

- javaversion
- version (Gerrit version)
- revision (revision of Gerrit, if not using a release)

Change-Id: I4076c579fa4a137a5ce6c69777adb03eaa6de26f
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
index b7c96cc..0dba67a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusExporter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporterprometheus/GerritPrometheusExporter.java
@@ -42,6 +42,7 @@
   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;
 
@@ -54,6 +55,7 @@
     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))
@@ -73,6 +75,7 @@
   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;