Merge branch 'stable-3.6' into stable-3.7

* stable-3.6:
  Index.replace: Log responses containing errors
  Remove warning stating that Elasticsearch is not production ready
  Add trace timer around Elasticsearch's performRequest
  Fix Flogger issues flagged by error prone
  Fix incorrect symlink in build docs
  Fix Flogger compile time errors

Release-Notes: skip
Change-Id: Ie0ec42836a3444c44ae660c2c858486f054feca5
diff --git a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index 408b582..47de0b6 100644
--- a/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -51,6 +51,8 @@
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.index.IndexUtils;
 import com.google.gerrit.server.index.options.AutoFlush;
+import com.google.gerrit.server.logging.Metadata;
+import com.google.gerrit.server.logging.TraceContext;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonArray;
@@ -280,7 +282,11 @@
           String.format("Expected %s, but was: %s", ContentType.APPLICATION_JSON, contentType));
       String responseStr = EntityUtils.toString(response.getEntity());
       JsonObject responseJson = (JsonObject) new JsonParser().parse(responseStr);
-      return responseJson.get("errors").getAsBoolean();
+      boolean hasErrors = responseJson.get("errors").getAsBoolean();
+      if (hasErrors) {
+        logger.atSevere().log("Response with errors: %s", responseJson);
+      }
+      return hasErrors;
     } catch (IOException e) {
       throw new StorageException(e);
     }
@@ -352,7 +358,15 @@
     for (Map.Entry<String, String> entry : params.entrySet()) {
       request.addParameter(entry.getKey(), entry.getValue());
     }
-    try {
+    try (TraceContext.TraceTimer traceTimer =
+        TraceContext.newTimer(
+            "Elasticsearch perform request",
+            Metadata.builder()
+                .indexName(indexName)
+                .operationName(
+                    String.format(
+                        "method:%s uri:%s payload:%s params:%s", method, uri, payload, params))
+                .build())) {
       return client.get().performRequest(request);
     } catch (IOException e) {
       throw new StorageException(e);
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 1954cb0..5d0dead 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -22,8 +22,7 @@
 
 ## Section elasticsearch
 
-WARNING: Support for Elasticsearch is still experimental and is not recommended for production
-use. For compatibility information, please refer to the [project homepage](https://www.gerritcodereview.com/elasticsearch.html).
+For compatibility information, please refer to the [project homepage](https://www.gerritcodereview.com/elasticsearch.html).
 
 Note that when Gerrit is configured to use Elasticsearch, the Elasticsearch
 server(s) must be reachable during the site initialization.