Merge branch 'stable-2.13'

* stable-2.13:
  Add hostname label to Gerrit Metrics in ElasticSearch
  Update ElasticSearch library and its dependencies

Change-Id: Idd7040ca41cb77337c00bad1d61b284f37d8c3a4
diff --git a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritElasticsearchReporter.java b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritElasticsearchReporter.java
index abb933f..75dec90 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritElasticsearchReporter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/metricsreporters/GerritElasticsearchReporter.java
@@ -13,9 +13,11 @@
 // limitations under the License.
 package com.googlesource.gerrit.plugins.metricsreporters;
 
+import com.google.gerrit.common.Nullable;
 import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.events.LifecycleListener;
+import com.google.gerrit.server.config.CanonicalWebUrl;
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -26,7 +28,13 @@
 import org.elasticsearch.metrics.ElasticsearchReporter;
 
 import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
 import java.util.concurrent.TimeUnit;
+import java.util.Map;
+import java.util.HashMap;
 
 @Listen
 @Singleton
@@ -37,21 +45,48 @@
   public GerritElasticsearchReporter(
       PluginConfigFactory configFactory,
       @PluginName String pluginName,
+      @Nullable @CanonicalWebUrl String gerritUrl,
       MetricRegistry registry) {
     Config config = configFactory.getGlobalPluginConfig(pluginName);
     String[] hosts = config.getStringList("elasticsearch", null, "host");
     if (hosts.length == 0) {
         hosts = new String[] { "localhost:9200" };
     }
+
+    Map<String, Object> additionalFields = new HashMap<>(1);
+    try {
+      String hostName;
+      if (gerritUrl != null) {
+        URL u = new URL(gerritUrl);
+        hostName = u.getHost() != null ? u.getHost() : getLocalHostName();
+      } else {
+        hostName = "Gerrit";
+      }
+      // Tools like Grafana has a gotcha related to how it treats
+      // Hostnames, especially FQDN’s, and IP addresses (due to
+      // their dots). When included in values for metric keys they will be
+      // interpreted by Graphite as separate pieces.
+      // To combat this we replace all dots in hostnames and IP addresses
+      // with underscores.
+      additionalFields.put("host", hostName.replace('.', '_'));
+    } catch (MalformedURLException | UnknownHostException e) {
+      throw new RuntimeException(e);
+    }
+
     try {
       reporter = ElasticsearchReporter.forRegistry(registry)
           .hosts(hosts)
+          .additionalFields(additionalFields)
           .build();
     } catch (IOException e) {
       throw new RuntimeException(e);
     }
   }
 
+  private String getLocalHostName() throws UnknownHostException {
+    return InetAddress.getLocalHost().getCanonicalHostName();
+  }
+
   @Override
   public void start() {
     reporter.start(60, TimeUnit.SECONDS);