From 7f85a9ae4f79c4d3e56e196795f90729213c8797 Mon Sep 17 00:00:00 2001 From: zsitole Date: Tue, 12 Apr 2022 14:16:15 +0300 Subject: [PATCH 1/4] GEODE-10231 : Add configuration for suppressing FunctionException logging Use Log4j Markers for FunctionException logs --- .../internal/cache/execute/AbstractExecution.java | 9 ++++++++- .../DistributedRegionFunctionResultSender.java | 9 ++++++++- .../cache/execute/MemberFunctionResultSender.java | 9 ++++++++- .../PartitionedRegionFunctionResultSender.java | 9 ++++++++- .../execute/ServerToClientFunctionResultSender.java | 12 +++++++++--- .../internal/cache/tier/sockets/BaseCommand.java | 5 +++++ .../tier/sockets/command/ExecuteFunction70.java | 4 ++++ .../sockets/command/ExecuteRegionFunction66.java | 6 +++--- .../cli/functions/UserFunctionExecution.java | 12 ++++++++++++ 9 files changed, 65 insertions(+), 10 deletions(-) diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/AbstractExecution.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/AbstractExecution.java index 73c02c405545..ef74ada2d5fd 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/AbstractExecution.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/AbstractExecution.java @@ -22,9 +22,12 @@ import java.util.concurrent.TimeUnit; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; import org.apache.geode.InternalGemFireException; import org.apache.geode.SystemFailure; +import org.apache.geode.annotations.Immutable; import org.apache.geode.annotations.internal.MakeNotStatic; import org.apache.geode.cache.LowMemoryException; import org.apache.geode.cache.TransactionException; @@ -55,6 +58,9 @@ */ public abstract class AbstractExecution implements InternalExecution { private static final Logger logger = LogService.getLogger(); + @Immutable + private static final Marker functionExceptionMarker = + MarkerManager.getMarker("FUNCTION_EXCEPTION_MARKER"); public static final int DEFAULT_CLIENT_FUNCTION_TIMEOUT = 0; private static final String CLIENT_FUNCTION_TIMEOUT_SYSTEM_PROPERTY = @@ -504,7 +510,8 @@ private void handleException(Throwable functionException, final Function fn, ((InternalResultSender) sender).setException(functionException); } } else { - logger.warn("Exception occurred on local node while executing Function:", + logger.warn(functionException instanceof FunctionException ? functionExceptionMarker : null, + "Exception occurred on local node while executing Function:", functionException); } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/DistributedRegionFunctionResultSender.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/DistributedRegionFunctionResultSender.java index 5ab445b20ae1..afd2083e5b8e 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/DistributedRegionFunctionResultSender.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/DistributedRegionFunctionResultSender.java @@ -15,7 +15,10 @@ package org.apache.geode.internal.cache.execute; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.geode.annotations.Immutable; import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.ResultCollector; @@ -29,6 +32,9 @@ public class DistributedRegionFunctionResultSender implements InternalResultSender { private static final Logger logger = LogService.getLogger(); + @Immutable + private static final Marker functionExceptionMarker = + MarkerManager.getMarker("FUNCTION_EXCEPTION_MARKER"); DistributedRegionFunctionStreamingMessage msg = null; @@ -224,7 +230,8 @@ public void setException(Throwable exception) { } else { ((LocalResultCollector) rc).setException(exception); // this.lastResult(exception); - logger.info("Unexpected exception during function execution on local node Distributed Region", + logger.info(exception instanceof FunctionException ? functionExceptionMarker : null, + "Unexpected exception during function execution on local node Distributed Region", exception); } rc.endResults(); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/MemberFunctionResultSender.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/MemberFunctionResultSender.java index 64de9a36c5e7..eb2c15fde071 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/MemberFunctionResultSender.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/MemberFunctionResultSender.java @@ -16,7 +16,10 @@ package org.apache.geode.internal.cache.execute; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.geode.annotations.Immutable; import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.ResultCollector; @@ -31,6 +34,9 @@ public class MemberFunctionResultSender implements InternalResultSender { private static final Logger logger = LogService.getLogger(); + @Immutable + private static final Marker functionExceptionMarker = + MarkerManager.getMarker("FUNCTION_EXCEPTION_MARKER"); MemberFunctionStreamingMessage msg = null; @@ -232,7 +238,8 @@ public void sendException(Throwable exception) { public void setException(Throwable exception) { ((LocalResultCollector) rc).setException(exception); // this.lastResult(exception); - logger.info("Unexpected exception during function execution local member", + logger.info(exception instanceof FunctionException ? functionExceptionMarker : null, + "Unexpected exception during function execution local member", exception); rc.endResults(); localLastResultReceived = true; diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/PartitionedRegionFunctionResultSender.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/PartitionedRegionFunctionResultSender.java index 69a0450294a7..3e2fd5d1fcd6 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/PartitionedRegionFunctionResultSender.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/PartitionedRegionFunctionResultSender.java @@ -17,7 +17,10 @@ import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.geode.annotations.Immutable; import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.ResultCollector; @@ -42,6 +45,9 @@ public class PartitionedRegionFunctionResultSender implements InternalResultSender { private static final Logger logger = LogService.getLogger(); + @Immutable + private static final Marker functionExceptionMarker = + MarkerManager.getMarker("FUNCTION_EXCEPTION_MARKER"); PartitionedRegionFunctionStreamingMessage msg = null; @@ -390,7 +396,8 @@ public void setException(Throwable exception) { serverSender.setException(exception); } else { ((LocalResultCollector) rc).setException(exception); - logger.info("Unexpected exception during function execution on local node Partitioned Region", + logger.info(exception instanceof FunctionException ? functionExceptionMarker : null, + "Unexpected exception during function execution on local node Partitioned Region", exception); } rc.endResults(); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/ServerToClientFunctionResultSender.java b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/ServerToClientFunctionResultSender.java index 8f49951fb90c..decd8db5eeb1 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/execute/ServerToClientFunctionResultSender.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/execute/ServerToClientFunctionResultSender.java @@ -20,7 +20,10 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.geode.annotations.Immutable; import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.ResultSender; @@ -37,6 +40,9 @@ public class ServerToClientFunctionResultSender implements ResultSender { private static final Logger logger = LogService.getLogger(); + @Immutable + private static final Marker functionExceptionMarker = + MarkerManager.getMarker("FUNCTION_EXCEPTION_MARKER"); protected ChunkedMessage msg = null; @@ -321,9 +327,9 @@ public synchronized void setException(Throwable exception) { } String exceptionMessage = exception.getMessage() != null ? exception.getMessage() : "Exception occurred during function execution"; - logger.warn(String.format("Exception on server while executing function : %s", - fn), - exception); + logger.warn(exception instanceof FunctionException ? functionExceptionMarker : null, + "Exception on server while executing function : {}", fn, exception); + if (logger.isDebugEnabled()) { logger.debug("ServerToClientFunctionResultSender sending Function Exception : "); } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java index 9566723f7435..dc109901bbc6 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommand.java @@ -34,6 +34,8 @@ import java.util.regex.Pattern; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -88,6 +90,9 @@ public abstract class BaseCommand implements Command { protected static final Logger logger = LogService.getLogger(); + @Immutable + protected static final Marker functionExceptionMarker = + MarkerManager.getMarker("FUNCTION_EXCEPTION_MARKER"); @Immutable private static final byte[] OK_BYTES = new byte[] {0}; diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction70.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction70.java index 53795fb1896c..cc11c0e130f8 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction70.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteFunction70.java @@ -431,6 +431,10 @@ private void executeFunctionLocally(final Function fn, final FunctionContext cx, if (logger.isDebugEnabled()) { logger.debug("Exception on server while executing function: {}", fn, e); } + } catch (FunctionException e) { + stats.endFunctionExecutionWithException(startExecution, fn.hasResult()); + logger.warn(functionExceptionMarker, "Exception on server while executing function: {}", + fn, e); } catch (Exception e) { stats.endFunctionExecutionWithException(startExecution, fn.hasResult()); logger.warn("Exception on server while executing function: {}", fn, e); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java index 80f6cfb636d2..ffe701674475 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/ExecuteRegionFunction66.java @@ -220,9 +220,9 @@ public void cmdExecute(final @NotNull Message clientMessage, resultSender.setException(fe); } else { if (setLastResultReceived(resultSender)) { - logger.warn(String.format("Exception on server while executing function : %s", - function), - fe); + logger.warn(functionExceptionMarker, + "Exception on server while executing function : {}", + function, fe); sendException(hasResult, clientMessage, message, serverConnection, fe); } } diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/UserFunctionExecution.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/UserFunctionExecution.java index d3bdd1d242f9..321058617350 100644 --- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/UserFunctionExecution.java +++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/UserFunctionExecution.java @@ -28,13 +28,17 @@ import java.util.stream.Collectors; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; import org.apache.shiro.subject.Subject; +import org.apache.geode.annotations.Immutable; import org.apache.geode.cache.Cache; import org.apache.geode.cache.Region; import org.apache.geode.cache.execute.Execution; import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionContext; +import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.FunctionService; import org.apache.geode.cache.execute.ResultCollector; import org.apache.geode.cache.query.RegionNotFoundException; @@ -55,6 +59,10 @@ public class UserFunctionExecution implements InternalFunction { private static final long serialVersionUID = 1L; private static final Logger logger = LogService.getLogger(); + @Immutable + private static final Marker functionExceptionMarker = + MarkerManager.getMarker("FUNCTION_EXCEPTION_MARKER"); + protected static final String ID = "org.apache.geode.management.internal.cli.functions.UserFunctionExecution"; @@ -244,6 +252,10 @@ public void execute(FunctionContext context) { CliStrings.format( CliStrings.EXECUTE_FUNCTION__MSG__RESULT_COLLECTOR_0_NOT_FOUND_ERROR_1, resultCollectorName, e.getMessage()))); + } catch (FunctionException e) { + logger.error(functionExceptionMarker, "error executing function {}", functionId, e); + context.getResultSender().lastResult( + new CliFunctionResult(context.getMemberName(), ERROR, "Exception: " + e.getMessage())); } catch (Exception e) { logger.error("error executing function " + functionId, e); context.getResultSender().lastResult( From 20d420cc6c884c176f299c6e1746366909e9111c Mon Sep 17 00:00:00 2001 From: zsitole Date: Fri, 22 Apr 2022 17:31:06 +0300 Subject: [PATCH 2/4] GEODE-10231 : Add configuration for suppressing FunctionException logging Add documentation for FunctionException logging --- .../developing/function_exec/function_execution.html.md.erb | 2 +- geode-docs/managing/logging/configuring_log4j2.html.md.erb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/geode-docs/developing/function_exec/function_execution.html.md.erb b/geode-docs/developing/function_exec/function_execution.html.md.erb index 9542daab1390..ca2d4d8f2a99 100644 --- a/geode-docs/developing/function_exec/function_execution.html.md.erb +++ b/geode-docs/developing/function_exec/function_execution.html.md.erb @@ -57,7 +57,7 @@ See [Authorization of Function Execution](../../managing/security/implementing_a - For partitioned regions, the `PartitionRegionHelper` provides access to additional information and data for the region. For single regions, use `getLocalDataForContext`. For colocated regions, use `getLocalColocatedRegions`. **Note:** When you use `PartitionRegionHelper.getLocalDataForContext`, `putIfAbsent` may not return expected results if you are working on local data set instead of the region. - 4. To propagate an error condition or exception back to the caller of the function, throw a FunctionException from the `execute` method. <%=vars.product_name%> transmits the exception back to the caller as if it had been thrown on the calling side. See the Java API documentation for [FunctionException](/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionException.html) for more information. + 4. To propagate an error condition or exception back to the caller of the function, throw a FunctionException from the `execute` method. <%=vars.product_name%> transmits the exception back to the caller as if it had been thrown on the calling side. See the Java API documentation for [FunctionException](/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionException.html) for more information. Note, FunctionException logging on server side can be disabled by the Log4J filter for marker FUNCTION\_EXCEPTION\_MARKER. See [Advanced Users—Configuring Log4j 2 for <%=vars.product_name%>](../../managing/logging/configuring_log4j2.html) for more details. Example function code: diff --git a/geode-docs/managing/logging/configuring_log4j2.html.md.erb b/geode-docs/managing/logging/configuring_log4j2.html.md.erb index 460af7992f4e..39c17cf55501 100644 --- a/geode-docs/managing/logging/configuring_log4j2.html.md.erb +++ b/geode-docs/managing/logging/configuring_log4j2.html.md.erb @@ -64,6 +64,11 @@ Custom Log4j 2 configuration in <%=vars.product_name%> comes with some caveats a You can enable the GEODE\_VERBOSE log statements by changing `onMatch="DENY"` to `onMatch="ACCEPT"`. Typically, it's more useful to simply enable DEBUG or TRACE on certain classes or packages instead of for the entire <%=vars.product_name%> product. However, this setting can be used for internal debugging purposes if all other debugging methods fail. - The usage of filters can have an impact on performance. <%=vars.product_name%> has some logging optimizations that are deactivated when filters are used (except for the GEODE_VERBOSE marker mentioned previously). +- The FUNCTION\_EXCEPTION\_MARKER marker (Log4J2 Marker) can be used to FunctionException logs on server side during execution function. For example <%=vars.product_name%> `log4j2.xml` filter disables FunctionException logs with this line: + + ``` pre + + ``` - Geode's custom Log4j 2 Appenders can be used in a custom log4j2.xml. This requires: From 92ab68dd6d9b708680b1c5d0ce753ae8cca6d08e Mon Sep 17 00:00:00 2001 From: zsitole Date: Tue, 26 Apr 2022 10:59:14 +0300 Subject: [PATCH 3/4] GEODE-10231 : Add configuration for suppressing FunctionException logging Hotfix documentation for FunctionException logging --- geode-docs/managing/logging/configuring_log4j2.html.md.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geode-docs/managing/logging/configuring_log4j2.html.md.erb b/geode-docs/managing/logging/configuring_log4j2.html.md.erb index 39c17cf55501..ad0bc5923cd9 100644 --- a/geode-docs/managing/logging/configuring_log4j2.html.md.erb +++ b/geode-docs/managing/logging/configuring_log4j2.html.md.erb @@ -64,7 +64,7 @@ Custom Log4j 2 configuration in <%=vars.product_name%> comes with some caveats a You can enable the GEODE\_VERBOSE log statements by changing `onMatch="DENY"` to `onMatch="ACCEPT"`. Typically, it's more useful to simply enable DEBUG or TRACE on certain classes or packages instead of for the entire <%=vars.product_name%> product. However, this setting can be used for internal debugging purposes if all other debugging methods fail. - The usage of filters can have an impact on performance. <%=vars.product_name%> has some logging optimizations that are deactivated when filters are used (except for the GEODE_VERBOSE marker mentioned previously). -- The FUNCTION\_EXCEPTION\_MARKER marker (Log4J2 Marker) can be used to FunctionException logs on server side during execution function. For example <%=vars.product_name%> `log4j2.xml` filter disables FunctionException logs with this line: +- The FUNCTION\_EXCEPTION\_MARKER marker (Log4J2 Marker) can be used to disable FunctionException logs on server side during function execution. For example <%=vars.product_name%> `log4j2.xml` filter disables FunctionException logs with this line: ``` pre From 61fda98c0c836faa5fb658261f2d92a53f714597 Mon Sep 17 00:00:00 2001 From: Nabarun Nag Date: Wed, 27 Apr 2022 10:45:24 -0700 Subject: [PATCH 4/4] Fixed Log4j capital letters --- .../developing/function_exec/function_execution.html.md.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geode-docs/developing/function_exec/function_execution.html.md.erb b/geode-docs/developing/function_exec/function_execution.html.md.erb index ca2d4d8f2a99..82289ad73ead 100644 --- a/geode-docs/developing/function_exec/function_execution.html.md.erb +++ b/geode-docs/developing/function_exec/function_execution.html.md.erb @@ -57,7 +57,7 @@ See [Authorization of Function Execution](../../managing/security/implementing_a - For partitioned regions, the `PartitionRegionHelper` provides access to additional information and data for the region. For single regions, use `getLocalDataForContext`. For colocated regions, use `getLocalColocatedRegions`. **Note:** When you use `PartitionRegionHelper.getLocalDataForContext`, `putIfAbsent` may not return expected results if you are working on local data set instead of the region. - 4. To propagate an error condition or exception back to the caller of the function, throw a FunctionException from the `execute` method. <%=vars.product_name%> transmits the exception back to the caller as if it had been thrown on the calling side. See the Java API documentation for [FunctionException](/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionException.html) for more information. Note, FunctionException logging on server side can be disabled by the Log4J filter for marker FUNCTION\_EXCEPTION\_MARKER. See [Advanced Users—Configuring Log4j 2 for <%=vars.product_name%>](../../managing/logging/configuring_log4j2.html) for more details. + 4. To propagate an error condition or exception back to the caller of the function, throw a FunctionException from the `execute` method. <%=vars.product_name%> transmits the exception back to the caller as if it had been thrown on the calling side. See the Java API documentation for [FunctionException](/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionException.html) for more information. Note, FunctionException logging on server side can be disabled by the Log4j filter for marker FUNCTION\_EXCEPTION\_MARKER. See [Advanced Users—Configuring Log4j 2 for <%=vars.product_name%>](../../managing/logging/configuring_log4j2.html) for more details. Example function code: