Browse Source

QL: Add error logging for *QL (#101057)

This adds logging for the *QL query failures.
Exceptions resulting in a 5xx-class response are logged on `WARN` level, otherwise `DEBUG`.
Bogdan Pintea 2 years ago
parent
commit
0c76b4d135

+ 5 - 0
docs/changelog/101057.yaml

@@ -0,0 +1,5 @@
+pr: 101057
+summary: Add error logging for *QL
+area: EQL
+type: enhancement
+issues: []

+ 6 - 4
x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/RestEqlSearchAction.java

@@ -6,13 +6,13 @@
  */
 package org.elasticsearch.xpack.eql.plugin;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.index.IndexNotFoundException;
+import org.elasticsearch.logging.LogManager;
+import org.elasticsearch.logging.Logger;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
 import org.elasticsearch.rest.RestResponse;
@@ -32,10 +32,11 @@ import java.util.List;
 
 import static org.elasticsearch.rest.RestRequest.Method.GET;
 import static org.elasticsearch.rest.RestRequest.Method.POST;
+import static org.elasticsearch.xpack.ql.util.LoggingUtils.logOnFailure;
 
 @ServerlessScope(Scope.PUBLIC)
 public class RestEqlSearchAction extends BaseRestHandler {
-    private static Logger logger = LogManager.getLogger(RestEqlSearchAction.class);
+    private static final Logger LOGGER = LogManager.getLogger(RestEqlSearchAction.class);
     private static final String SEARCH_PATH = "/{index}/_eql/search";
 
     @Override
@@ -93,11 +94,12 @@ public class RestEqlSearchAction extends BaseRestHandler {
                             finalException = new IndexNotFoundException(indices, infe.getCause());
                         }
                     }
+                    logOnFailure(LOGGER, finalException);
                     try {
                         channel.sendResponse(new RestResponse(channel, finalException));
                     } catch (Exception inner) {
                         inner.addSuppressed(finalException);
-                        logger.error("failed to send failure response", inner);
+                        LOGGER.error("failed to send failure response", inner);
                     }
                 }
             });

+ 3 - 1
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlResponseListener.java

@@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
 
 import static org.elasticsearch.xpack.esql.formatter.TextFormat.CSV;
 import static org.elasticsearch.xpack.esql.formatter.TextFormat.URL_PARAM_DELIMITER;
+import static org.elasticsearch.xpack.ql.util.LoggingUtils.logOnFailure;
 
 /**
  * Listens for a single {@link EsqlQueryResponse}, builds a corresponding {@link RestResponse} and sends it.
@@ -162,8 +163,9 @@ public class EsqlResponseListener extends RestResponseListener<EsqlQueryResponse
         }, ex -> {
             // In case of failure, stop the time manually before sending out the response.
             long timeMillis = stopWatch.stop().getMillis();
-            onFailure(ex);
             LOGGER.info("Failed execution of ESQL query.\nQuery string: [{}]\nExecution time: [{}]ms", esqlQuery, timeMillis);
+            logOnFailure(LOGGER, ex);
+            onFailure(ex);
         });
     }
 }

+ 24 - 0
x-pack/plugin/ql/src/main/java/org/elasticsearch/xpack/ql/util/LoggingUtils.java

@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.ql.util;
+
+import org.elasticsearch.ExceptionsHelper;
+import org.elasticsearch.logging.Level;
+import org.elasticsearch.logging.Logger;
+import org.elasticsearch.rest.RestStatus;
+
+public final class LoggingUtils {
+
+    private LoggingUtils() {}
+
+    public static void logOnFailure(Logger logger, Throwable throwable) {
+        RestStatus status = ExceptionsHelper.status(throwable);
+        logger.log(status.getStatus() >= 500 ? Level.WARN : Level.DEBUG, () -> "Request failed with status [" + status + "]: ", throwable);
+    }
+
+}

+ 12 - 1
x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/RestSqlQueryAction.java

@@ -9,6 +9,8 @@ package org.elasticsearch.xpack.sql.plugin;
 
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.core.RestApiVersion;
+import org.elasticsearch.logging.LogManager;
+import org.elasticsearch.logging.Logger;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
 import org.elasticsearch.rest.Scope;
@@ -26,10 +28,12 @@ import java.util.Set;
 
 import static org.elasticsearch.rest.RestRequest.Method.GET;
 import static org.elasticsearch.rest.RestRequest.Method.POST;
+import static org.elasticsearch.xpack.ql.util.LoggingUtils.logOnFailure;
 import static org.elasticsearch.xpack.sql.proto.CoreProtocol.URL_PARAM_DELIMITER;
 
 @ServerlessScope(Scope.PUBLIC)
 public class RestSqlQueryAction extends BaseRestHandler {
+    private static final Logger LOGGER = LogManager.getLogger(RestSqlQueryAction.class);
 
     @Override
     public List<Route> routes() {
@@ -52,7 +56,14 @@ public class RestSqlQueryAction extends BaseRestHandler {
 
         return channel -> {
             RestCancellableNodeClient cancellableClient = new RestCancellableNodeClient(client, request.getHttpChannel());
-            cancellableClient.execute(SqlQueryAction.INSTANCE, sqlRequest, new SqlResponseListener(channel, request, sqlRequest));
+            cancellableClient.execute(
+                SqlQueryAction.INSTANCE,
+                sqlRequest,
+                new SqlResponseListener(channel, request, sqlRequest).delegateResponse((l, ex) -> {
+                    logOnFailure(LOGGER, ex);
+                    l.onFailure(ex);
+                })
+            );
         };
     }