From cee8e881cf71ea4dfd8e93fda88fd50a63314cba Mon Sep 17 00:00:00 2001 From: Manik Magar Date: Tue, 26 Nov 2024 16:20:49 +0530 Subject: [PATCH 01/11] feat: capture message attributes for flow logs --- .gitignore | 5 +- pom.xml | 2 +- .../FlowLogAttributesExpression.java | 60 +++++++++++++++++++ .../api/processor/MessageAttributes.java | 4 ++ .../config/CustomLoggerConfiguration.java | 34 +++++++++++ ...tomLoggerAbstractNotificationListener.java | 23 ++++++- ...stomLoggerFlowRefNotificationListener.java | 4 +- ...tomLoggerPipelineNotificationListener.java | 5 +- .../mule/logger/CustomLoggerArtifactTest.java | 5 +- src/test/resources/custom-logger-config.xml | 15 ++++- 10 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java diff --git a/.gitignore b/.gitignore index a697110..f4d290d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ target/ *.iml anypoint-pom.xml -unit-test.log \ No newline at end of file +unit-test.log + +docs/ +.flattened-pom.xml \ No newline at end of file diff --git a/pom.xml b/pom.xml index 88dbbdc..d083b30 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ mule-custom-logger - 3.0.1-SNAPSHOT + 3.1.0-SNAPSHOT mule-extension Mule Custom Logger Mule Custom Logger module that provides standard structured logging diff --git a/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java new file mode 100644 index 0000000..ab29037 --- /dev/null +++ b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java @@ -0,0 +1,60 @@ +package com.avioconsulting.mule.logger.api.processor; + +import org.mule.runtime.extension.api.annotation.Alias; +import org.mule.runtime.extension.api.annotation.param.Parameter; +import org.mule.runtime.extension.api.annotation.param.display.Summary; + +import java.util.Objects; + +@Alias("flow-attributes-expression") +public class FlowLogAttributesExpression { + + @Parameter + @Summary("Name of the flow to associate given expression as attributes") + private String flowName; + @Parameter + @Summary("A valid dataweave expression that resolves to a Map object with key-value pairs") + private String expressionText; + + public String getFlowName() { + return flowName; + } + + public FlowLogAttributesExpression setFlowName(String flowName) { + this.flowName = flowName; + return this; + } + + public String getExpressionText() { + return expressionText; + } + + public FlowLogAttributesExpression setExpressionText(String expressionText) { + this.expressionText = expressionText; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + FlowLogAttributesExpression that = (FlowLogAttributesExpression) o; + return Objects.equals(getFlowName(), that.getFlowName()) + && Objects.equals(getExpressionText(), that.getExpressionText()); + } + + @Override + public int hashCode() { + return Objects.hash(getFlowName(), getExpressionText()); + } + + @Override + public String toString() { + return "FlowLogAttributesExpression{" + + "flowName='" + flowName + '\'' + + ", attributeExpression='" + expressionText + '\'' + + '}'; + } +} diff --git a/src/main/java/com/avioconsulting/mule/logger/api/processor/MessageAttributes.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/MessageAttributes.java index 7a3e63b..6be85d5 100644 --- a/src/main/java/com/avioconsulting/mule/logger/api/processor/MessageAttributes.java +++ b/src/main/java/com/avioconsulting/mule/logger/api/processor/MessageAttributes.java @@ -41,6 +41,10 @@ public List getAttributeList() { return this.messageAttributes; } + public void addAttributes(Map attributes) { + attributes.forEach((key, value) -> messageAttributes.add(new MessageAttribute(key, value))); + } + public Map getAttributes() { Map attributes = new LinkedHashMap<>(); if (messageAttributes != null) { diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java index 821930f..97aaeae 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java @@ -4,6 +4,7 @@ import com.avioconsulting.mule.logger.api.processor.Compressor; import com.avioconsulting.mule.logger.api.processor.EncryptionAlgorithm; +import com.avioconsulting.mule.logger.api.processor.FlowLogAttributesExpression; import com.avioconsulting.mule.logger.api.processor.LogProperties; import com.avioconsulting.mule.logger.internal.CustomLogger; import com.avioconsulting.mule.logger.internal.CustomLoggerOperation; @@ -18,14 +19,20 @@ import org.mule.runtime.api.lifecycle.Startable; import org.mule.runtime.api.meta.ExpressionSupport; import org.mule.runtime.api.notification.NotificationListenerRegistry; +import org.mule.runtime.core.api.el.ExpressionManager; import org.mule.runtime.extension.api.annotation.Expression; import org.mule.runtime.extension.api.annotation.Operations; +import org.mule.runtime.extension.api.annotation.param.NullSafe; import org.mule.runtime.extension.api.annotation.param.Optional; import org.mule.runtime.extension.api.annotation.param.Parameter; import org.mule.runtime.extension.api.annotation.param.display.*; import org.mule.runtime.extension.api.client.ExtensionsClient; import org.slf4j.LoggerFactory; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + /** * This class represents an extension configuration, values set in this class * are commonly used across multiple @@ -83,6 +90,14 @@ public class CustomLoggerConfiguration implements Startable, Initialisable { @Expression(ExpressionSupport.NOT_SUPPORTED) private LogProperties.LogLevel flowLogLevel; + @Parameter + @DisplayName("Flow Log Attributes") + @Summary("The level flow logs will be logged at if enabled") + @NullSafe + @Optional + @Expression(ExpressionSupport.NOT_SUPPORTED) + private List flowLogAttributes; + @Parameter @DisplayName("Flow Log Category Suffix") @Summary("This category will be appended to the default logger category and used for all flow logs") @@ -138,6 +153,10 @@ public class CustomLoggerConfiguration implements Startable, Initialisable { @Inject ExtensionsClient extensionsClient; + @Inject + ExpressionManager expressionManager; + private Map flowLogAttributesMap; + /** * Default constructor for auto-initialization */ @@ -175,6 +194,15 @@ public CustomLoggerConfiguration(CustomLoggerRegistrationService customLoggerReg private static boolean isNotificationListenerRegistered = false; + public Map getFlowLogAttributesMap() { + return flowLogAttributesMap; + } + + public CustomLoggerConfiguration setFlowLogAttributes(List flowLogAttributes) { + this.flowLogAttributes = flowLogAttributes; + return this; + } + public String getApplicationName() { return applicationName; } @@ -291,6 +319,10 @@ public ExtensionsClient getExtensionsClient() { return extensionsClient; } + public ExpressionManager getExpressionManager() { + return expressionManager; + } + /** * This method is invoked by the MuleSoft application when the AVIO Custom * Logger is invoked to create the connection. @@ -312,6 +344,8 @@ public void start() throws MuleException { customLoggerRegistrationService.setConfig(this); if (isEnableFlowLogs()) { classLogger.info("Flow logs enabled"); + flowLogAttributesMap = flowLogAttributes.stream().collect(Collectors + .toMap(FlowLogAttributesExpression::getFlowName, FlowLogAttributesExpression::getExpressionText)); synchronized (CustomLoggerConfiguration.class) { if (!isNotificationListenerRegistered) { classLogger.info("Creating and registering notification listener"); diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index 5aad95a..f9e6f97 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -8,9 +8,15 @@ import com.avioconsulting.mule.logger.internal.config.CustomLoggerConfiguration; import org.mule.runtime.api.component.location.ComponentLocation; import org.mule.runtime.api.event.Event; +import org.mule.runtime.api.metadata.TypedValue; +import org.mule.runtime.api.notification.EnrichedServerNotification; + +import java.util.Collections; +import java.util.Map; public abstract class CustomLoggerAbstractNotificationListener { protected final CustomLoggerConfiguration config; + private Map emptyAttributes = Collections.emptyMap(); public CustomLoggerAbstractNotificationListener(CustomLoggerConfiguration config) { this.config = config; @@ -19,7 +25,7 @@ public CustomLoggerAbstractNotificationListener(CustomLoggerConfiguration config protected abstract org.slf4j.Logger getClassLogger(); protected void logMessage(ComponentLocation location, Event event, String logMessage, String categoryPrefix, - LogProperties.LogLevel level) { + LogProperties.LogLevel level, Map additionalAttributes) { CustomLogger logger = config.getLogger(); LogProperties logProperties = new LogProperties(); MessageAttributes messageAttributes = new MessageAttributes(); @@ -28,6 +34,7 @@ protected void logMessage(ComponentLocation location, Event event, String logMes .getValue(); messageAttributes.setOTelContextObject(oTelContextObject); } + messageAttributes.addAttributes(additionalAttributes); ExceptionProperties exceptionProperties = new ExceptionProperties(); AdditionalProperties additionalProperties = new AdditionalProperties(); additionalProperties.setIncludeLocationInfo(true); @@ -41,4 +48,18 @@ protected void logMessage(ComponentLocation location, Event event, String logMes logger.log(logProperties, messageAttributes, exceptionProperties, additionalProperties, config, location, correlationId); } + + protected Map getFlowLogAttributes(EnrichedServerNotification notification) { + Map value = emptyAttributes; + String expression = config.getFlowLogAttributesMap().get(notification.getResourceIdentifier()); + if (expression != null) { + TypedValue> evaluate = (TypedValue>) config.getExpressionManager() + .evaluate("#[" + expression + "]", + notification.getEvent().asBindingContext()); + value = evaluate.getValue(); + if (value == null) + value = emptyAttributes; + } + return value; + } } diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerFlowRefNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerFlowRefNotificationListener.java index a95ac71..4cea2a2 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerFlowRefNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerFlowRefNotificationListener.java @@ -59,8 +59,9 @@ public void onNotification(MessageProcessorNotification notification) { return; } classLogger.info(message); + Map flowLogAttributes = getFlowLogAttributes(notification); logMessage(location, notification.getEvent(), message, FLOW_REF_CATEGORY_SUFFIX, - config.getFlowLogLevel()); + config.getFlowLogLevel(), flowLogAttributes); } catch (Exception e) { classLogger.error("Error processing flow notification", e); } @@ -69,4 +70,5 @@ public void onNotification(MessageProcessorNotification notification) { "Configuration hasn't been supplied to notification listener yet, flow logs won't be generated."); } } + } diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java index 7710f91..23ed3e0 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java @@ -6,6 +6,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; + /* * Listener for Mule notifications on flow start, end and completion. */ @@ -49,9 +51,10 @@ public void onNotification(PipelineMessageNotification notification) { return; } classLogger.debug(message); + Map flowLogAttributes = getFlowLogAttributes(notification); logMessage(notification.getComponent().getLocation(), notification.getEvent(), message, config.getFlowCategorySuffix(), - config.getFlowLogLevel()); + config.getFlowLogLevel(), flowLogAttributes); } catch (Exception e) { classLogger.error("Error processing flow notification", e); } diff --git a/src/test/java/com/avioconsulting/mule/logger/CustomLoggerArtifactTest.java b/src/test/java/com/avioconsulting/mule/logger/CustomLoggerArtifactTest.java index ad93121..567200c 100644 --- a/src/test/java/com/avioconsulting/mule/logger/CustomLoggerArtifactTest.java +++ b/src/test/java/com/avioconsulting/mule/logger/CustomLoggerArtifactTest.java @@ -13,7 +13,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.time.Duration; +import java.util.Collections; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; @@ -44,7 +44,8 @@ public void cleanup() throws Exception { @Test public void testLoggerConfigForCorrelationId() throws Exception { // TODO: Intercept logs and validate entries - CoreEvent coreEvent = flowRunner("custom-logger-configFlow").run(); + CoreEvent coreEvent = flowRunner("custom-logger-configFlow") + .withAttributes(Collections.singletonMap("some", "value")).run(); Assert.assertNotNull(coreEvent); } diff --git a/src/test/resources/custom-logger-config.xml b/src/test/resources/custom-logger-config.xml index f0ff318..991774b 100644 --- a/src/test/resources/custom-logger-config.xml +++ b/src/test/resources/custom-logger-config.xml @@ -5,11 +5,20 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/avio-logger http://www.mulesoft.org/schema/mule/avio-logger/current/mule-avio-logger.xsd"> - + applicationVersion="1" applicationName="munit" environment="test" compressor="GZIP" encryptionAlgorithm="PBEWithHmacSHA512AndAES_128" encryptionPassword="example" enableFlowLogs="true" formatAsJson="true" flowLogLevel="INFO"> + + + + + + + + + + From fddda637cb8c85995d332a4b869a2b634883fb58 Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Wed, 11 Dec 2024 15:12:41 -0600 Subject: [PATCH 02/11] Allowing wildcards on the flownames to log message attributes when flow level logging is enabled --- ...tomLoggerAbstractNotificationListener.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index f9e6f97..de1aa8c 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -12,7 +12,9 @@ import org.mule.runtime.api.notification.EnrichedServerNotification; import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public abstract class CustomLoggerAbstractNotificationListener { protected final CustomLoggerConfiguration config; @@ -60,6 +62,51 @@ protected Map getFlowLogAttributes(EnrichedServerNotification no if (value == null) value = emptyAttributes; } + /** Flow name can contain wildcard (*) + * We only look for wildcard either starting of the string or ending of the string + * ex: mq-listener-* will look for all the flows that starts with mq-listener + * ex: *-mq-flow will look for all the flows that ends with -mq-flow **/ + else { + List> matchedEntries = config.getFlowLogAttributesMap().entrySet().stream() + .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) + .collect(Collectors.toList()); + if (!matchedEntries.isEmpty()) { + expression = matchedEntries.get(0).getValue(); + TypedValue> evaluate = (TypedValue>) config + .getExpressionManager() + .evaluate("#[" + expression + "]", + notification.getEvent().asBindingContext()); + value = evaluate.getValue(); + if (value == null) + value = emptyAttributes; + } + } return value; } + + public boolean matchWildcard(String wildcardKey, String searchString) { + // Trim the wildcard key + String cleanWildcardKey = wildcardKey.trim(); + + // If wildcard key is just '*', match everything + if (cleanWildcardKey.equals("*")) { + return true; + } + + // Handle start wildcard + if (cleanWildcardKey.startsWith("*")) { + String suffix = cleanWildcardKey.substring(1); + return searchString.endsWith(suffix); + } + + // Handle end wildcard + if (cleanWildcardKey.endsWith("*")) { + String prefix = cleanWildcardKey.substring(0, cleanWildcardKey.length() - 1); + return searchString.startsWith(prefix); + } + + // Exact match if no wildcards + return searchString.equals(wildcardKey); + } + } From 36241a5f9cfea43a3e0e3c99d52e4aeaab91459d Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Wed, 11 Dec 2024 15:37:20 -0600 Subject: [PATCH 03/11] Fixed formatting issue --- .../CustomLoggerAbstractNotificationListener.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index de1aa8c..f748ad1 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -62,10 +62,13 @@ protected Map getFlowLogAttributes(EnrichedServerNotification no if (value == null) value = emptyAttributes; } - /** Flow name can contain wildcard (*) - * We only look for wildcard either starting of the string or ending of the string + /** + * Flow name can contain wildcard (*) + * We only look for wildcard either starting of the string or ending of the + * string * ex: mq-listener-* will look for all the flows that starts with mq-listener - * ex: *-mq-flow will look for all the flows that ends with -mq-flow **/ + * ex: *-mq-flow will look for all the flows that ends with -mq-flow + **/ else { List> matchedEntries = config.getFlowLogAttributesMap().entrySet().stream() .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) From cc3abc0cad8675933561a0f5fc824f133a0a0bdb Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Wed, 18 Dec 2024 11:58:14 -0600 Subject: [PATCH 04/11] Added message expression and updated the flow log attributes --- pom.xml | 2 +- .../FlowLogAttributesExpression.java | 60 ------------------- .../logger/api/processor/FlowLogConfig.java | 34 +++++++++++ .../config/CustomLoggerConfiguration.java | 19 +++--- ...tomLoggerAbstractNotificationListener.java | 19 +++--- ...tomLoggerPipelineNotificationListener.java | 18 +++++- 6 files changed, 70 insertions(+), 82 deletions(-) delete mode 100644 src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java create mode 100644 src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java diff --git a/pom.xml b/pom.xml index d083b30..1dc96ae 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ mule-custom-logger - 3.1.0-SNAPSHOT + 3.1.12-SNAPSHOT mule-extension Mule Custom Logger Mule Custom Logger module that provides standard structured logging diff --git a/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java deleted file mode 100644 index ab29037..0000000 --- a/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogAttributesExpression.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.avioconsulting.mule.logger.api.processor; - -import org.mule.runtime.extension.api.annotation.Alias; -import org.mule.runtime.extension.api.annotation.param.Parameter; -import org.mule.runtime.extension.api.annotation.param.display.Summary; - -import java.util.Objects; - -@Alias("flow-attributes-expression") -public class FlowLogAttributesExpression { - - @Parameter - @Summary("Name of the flow to associate given expression as attributes") - private String flowName; - @Parameter - @Summary("A valid dataweave expression that resolves to a Map object with key-value pairs") - private String expressionText; - - public String getFlowName() { - return flowName; - } - - public FlowLogAttributesExpression setFlowName(String flowName) { - this.flowName = flowName; - return this; - } - - public String getExpressionText() { - return expressionText; - } - - public FlowLogAttributesExpression setExpressionText(String expressionText) { - this.expressionText = expressionText; - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - FlowLogAttributesExpression that = (FlowLogAttributesExpression) o; - return Objects.equals(getFlowName(), that.getFlowName()) - && Objects.equals(getExpressionText(), that.getExpressionText()); - } - - @Override - public int hashCode() { - return Objects.hash(getFlowName(), getExpressionText()); - } - - @Override - public String toString() { - return "FlowLogAttributesExpression{" + - "flowName='" + flowName + '\'' + - ", attributeExpression='" + expressionText + '\'' + - '}'; - } -} diff --git a/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java new file mode 100644 index 0000000..34e2978 --- /dev/null +++ b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java @@ -0,0 +1,34 @@ +package com.avioconsulting.mule.logger.api.processor; + +import org.mule.runtime.extension.api.annotation.Alias; +import org.mule.runtime.extension.api.annotation.param.Parameter; +import org.mule.runtime.extension.api.annotation.param.ParameterGroup; +import org.mule.runtime.extension.api.annotation.param.display.Summary; + +@Alias("flow-logs-config") +public class FlowLogConfig { + + @Parameter + @Summary("Name of the flow to associate given expression as attributes") + private String flowName; + + @ParameterGroup(name = "Flow Attributes") + private ExpressionText expressionText; + + public String getFlowName() { + return flowName; + } + + public FlowLogConfig setFlowName(String flowName) { + this.flowName = flowName; + return this; + } + + public ExpressionText getExpressionText() { + return expressionText; + } + + public void setExpressionText(ExpressionText expressionText) { + this.expressionText = expressionText; + } +} diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java index 97aaeae..60ab109 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java @@ -4,7 +4,7 @@ import com.avioconsulting.mule.logger.api.processor.Compressor; import com.avioconsulting.mule.logger.api.processor.EncryptionAlgorithm; -import com.avioconsulting.mule.logger.api.processor.FlowLogAttributesExpression; +import com.avioconsulting.mule.logger.api.processor.FlowLogConfig; import com.avioconsulting.mule.logger.api.processor.LogProperties; import com.avioconsulting.mule.logger.internal.CustomLogger; import com.avioconsulting.mule.logger.internal.CustomLoggerOperation; @@ -31,6 +31,7 @@ import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -96,7 +97,7 @@ public class CustomLoggerConfiguration implements Startable, Initialisable { @NullSafe @Optional @Expression(ExpressionSupport.NOT_SUPPORTED) - private List flowLogAttributes; + private List flowLogConfigs; @Parameter @DisplayName("Flow Log Category Suffix") @@ -155,7 +156,7 @@ public class CustomLoggerConfiguration implements Startable, Initialisable { @Inject ExpressionManager expressionManager; - private Map flowLogAttributesMap; + private Map flowLogConfigMap; /** * Default constructor for auto-initialization @@ -194,12 +195,12 @@ public CustomLoggerConfiguration(CustomLoggerRegistrationService customLoggerReg private static boolean isNotificationListenerRegistered = false; - public Map getFlowLogAttributesMap() { - return flowLogAttributesMap; + public Map getFlowLogConfigMap() { + return flowLogConfigMap; } - public CustomLoggerConfiguration setFlowLogAttributes(List flowLogAttributes) { - this.flowLogAttributes = flowLogAttributes; + public CustomLoggerConfiguration setFlowLogConfigs(List flowLogConfigs) { + this.flowLogConfigs = flowLogConfigs; return this; } @@ -344,8 +345,8 @@ public void start() throws MuleException { customLoggerRegistrationService.setConfig(this); if (isEnableFlowLogs()) { classLogger.info("Flow logs enabled"); - flowLogAttributesMap = flowLogAttributes.stream().collect(Collectors - .toMap(FlowLogAttributesExpression::getFlowName, FlowLogAttributesExpression::getExpressionText)); + flowLogConfigMap = flowLogConfigs.stream().collect( + Collectors.toMap(FlowLogConfig::getFlowName, Function.identity())); synchronized (CustomLoggerConfiguration.class) { if (!isNotificationListenerRegistered) { classLogger.info("Creating and registering notification listener"); diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index f748ad1..1bcf39d 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -1,9 +1,6 @@ package com.avioconsulting.mule.logger.internal.listeners; -import com.avioconsulting.mule.logger.api.processor.AdditionalProperties; -import com.avioconsulting.mule.logger.api.processor.ExceptionProperties; -import com.avioconsulting.mule.logger.api.processor.LogProperties; -import com.avioconsulting.mule.logger.api.processor.MessageAttributes; +import com.avioconsulting.mule.logger.api.processor.*; import com.avioconsulting.mule.logger.internal.CustomLogger; import com.avioconsulting.mule.logger.internal.config.CustomLoggerConfiguration; import org.mule.runtime.api.component.location.ComponentLocation; @@ -53,10 +50,10 @@ protected void logMessage(ComponentLocation location, Event event, String logMes protected Map getFlowLogAttributes(EnrichedServerNotification notification) { Map value = emptyAttributes; - String expression = config.getFlowLogAttributesMap().get(notification.getResourceIdentifier()); - if (expression != null) { + FlowLogConfig flowLogConfig = config.getFlowLogConfigMap().get(notification.getResourceIdentifier()); + if (flowLogConfig != null) { TypedValue> evaluate = (TypedValue>) config.getExpressionManager() - .evaluate("#[" + expression + "]", + .evaluate("#[" + flowLogConfig.getExpressionText().getAttributesExpressionText() + "]", notification.getEvent().asBindingContext()); value = evaluate.getValue(); if (value == null) @@ -70,14 +67,14 @@ protected Map getFlowLogAttributes(EnrichedServerNotification no * ex: *-mq-flow will look for all the flows that ends with -mq-flow **/ else { - List> matchedEntries = config.getFlowLogAttributesMap().entrySet().stream() + List> matchedEntries = config.getFlowLogConfigMap().entrySet().stream() .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) .collect(Collectors.toList()); if (!matchedEntries.isEmpty()) { - expression = matchedEntries.get(0).getValue(); + flowLogConfig = matchedEntries.get(0).getValue(); TypedValue> evaluate = (TypedValue>) config .getExpressionManager() - .evaluate("#[" + expression + "]", + .evaluate("#[" + flowLogConfig.getExpressionText().getAttributesExpressionText() + "]", notification.getEvent().asBindingContext()); value = evaluate.getValue(); if (value == null) @@ -112,4 +109,4 @@ public boolean matchWildcard(String wildcardKey, String searchString) { return searchString.equals(wildcardKey); } -} +} \ No newline at end of file diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java index 23ed3e0..886a9b4 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java @@ -1,12 +1,16 @@ package com.avioconsulting.mule.logger.internal.listeners; +import com.avioconsulting.mule.logger.api.processor.FlowLogConfig; import com.avioconsulting.mule.logger.internal.config.CustomLoggerConfiguration; +import org.mule.runtime.api.metadata.TypedValue; import org.mule.runtime.api.notification.PipelineMessageNotification; import org.mule.runtime.api.notification.PipelineMessageNotificationListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /* * Listener for Mule notifications on flow start, end and completion. @@ -37,10 +41,22 @@ public void onNotification(PipelineMessageNotification notification) { + "]"); if (config != null) { try { + String msgToAppend = ""; + List> matchedEntries = config.getFlowLogConfigMap().entrySet().stream() + .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) + .collect(Collectors.toList()); + if (!matchedEntries.isEmpty()) { + FlowLogConfig flowLogConfig = matchedEntries.get(0).getValue(); + TypedValue evaluate = (TypedValue) config + .getExpressionManager() + .evaluate("#[" + flowLogConfig.getExpressionText().getMessageExpressionText() + "]", + notification.getEvent().asBindingContext()); + msgToAppend = evaluate.getValue(); + } String message = "Event not processed yet, this should never be shown"; switch (Integer.parseInt(notification.getAction().getIdentifier())) { case PipelineMessageNotification.PROCESS_START: - message = "Flow [" + notification.getResourceIdentifier() + "]" + " start"; + message = "Flow [" + notification.getResourceIdentifier() + "]" + " start " + msgToAppend; break; case PipelineMessageNotification.PROCESS_COMPLETE: message = "Flow [" + notification.getResourceIdentifier() + "]" + " end"; From 77ace2b477cd177b9ff55a0bb80a4b6b57920f02 Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Wed, 18 Dec 2024 14:05:42 -0600 Subject: [PATCH 05/11] Updated validation loginc for flow log attributes --- .../logger/api/processor/ExpressionText.java | 35 ++++++++++++++++ .../config/CustomLoggerConfiguration.java | 7 ++++ ...tomLoggerAbstractNotificationListener.java | 42 +++++++------------ ...tomLoggerPipelineNotificationListener.java | 7 +++- 4 files changed, 64 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java diff --git a/src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java new file mode 100644 index 0000000..924e069 --- /dev/null +++ b/src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java @@ -0,0 +1,35 @@ +package com.avioconsulting.mule.logger.api.processor; + +import org.mule.runtime.extension.api.annotation.param.ExclusiveOptionals; +import org.mule.runtime.extension.api.annotation.param.Optional; +import org.mule.runtime.extension.api.annotation.param.Parameter; +import org.mule.runtime.extension.api.annotation.param.display.Summary; + +public class ExpressionText { + + @Parameter + @Optional + @Summary("A valid dataweave expression that resolves to a Map object with key-value pairs") + private String attributesExpressionText; + + @Parameter + @Optional + @Summary("A valid dataweave expression that results in a String to append to default flow start message") + private String messageExpressionText; + + public String getAttributesExpressionText() { + return attributesExpressionText; + } + + public void setAttributesExpressionText(String attributesExpressionText) { + this.attributesExpressionText = attributesExpressionText; + } + + public String getMessageExpressionText() { + return messageExpressionText; + } + + public void setMessageExpressionText(String messageExpressionText) { + this.messageExpressionText = messageExpressionText; + } +} diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java index 60ab109..1c0eaef 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java @@ -345,6 +345,13 @@ public void start() throws MuleException { customLoggerRegistrationService.setConfig(this); if (isEnableFlowLogs()) { classLogger.info("Flow logs enabled"); + flowLogConfigs.forEach(flowLogConfig -> { + if (flowLogConfig.getExpressionText().getMessageExpressionText() == null + && flowLogConfig.getExpressionText().getAttributesExpressionText() == null) { + throw new IllegalStateException( + "One of attributesExpressionText or messageExpressionText must be defined in flow-logs-config"); + } + }); flowLogConfigMap = flowLogConfigs.stream().collect( Collectors.toMap(FlowLogConfig::getFlowName, Function.identity())); synchronized (CustomLoggerConfiguration.class) { diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index 1bcf39d..a0911e2 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -51,14 +51,6 @@ protected void logMessage(ComponentLocation location, Event event, String logMes protected Map getFlowLogAttributes(EnrichedServerNotification notification) { Map value = emptyAttributes; FlowLogConfig flowLogConfig = config.getFlowLogConfigMap().get(notification.getResourceIdentifier()); - if (flowLogConfig != null) { - TypedValue> evaluate = (TypedValue>) config.getExpressionManager() - .evaluate("#[" + flowLogConfig.getExpressionText().getAttributesExpressionText() + "]", - notification.getEvent().asBindingContext()); - value = evaluate.getValue(); - if (value == null) - value = emptyAttributes; - } /** * Flow name can contain wildcard (*) * We only look for wildcard either starting of the string or ending of the @@ -66,20 +58,18 @@ protected Map getFlowLogAttributes(EnrichedServerNotification no * ex: mq-listener-* will look for all the flows that starts with mq-listener * ex: *-mq-flow will look for all the flows that ends with -mq-flow **/ - else { - List> matchedEntries = config.getFlowLogConfigMap().entrySet().stream() - .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) - .collect(Collectors.toList()); - if (!matchedEntries.isEmpty()) { - flowLogConfig = matchedEntries.get(0).getValue(); - TypedValue> evaluate = (TypedValue>) config - .getExpressionManager() - .evaluate("#[" + flowLogConfig.getExpressionText().getAttributesExpressionText() + "]", - notification.getEvent().asBindingContext()); - value = evaluate.getValue(); - if (value == null) - value = emptyAttributes; - } + List> matchedEntries = config.getFlowLogConfigMap().entrySet().stream() + .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) + .collect(Collectors.toList()); + if (!matchedEntries.isEmpty()) { + flowLogConfig = matchedEntries.get(0).getValue(); + TypedValue> evaluate = (TypedValue>) config + .getExpressionManager() + .evaluate("#[" + flowLogConfig.getExpressionText().getAttributesExpressionText() + "]", + notification.getEvent().asBindingContext()); + value = evaluate.getValue(); + if (value == null) + value = emptyAttributes; } return value; } @@ -88,8 +78,8 @@ public boolean matchWildcard(String wildcardKey, String searchString) { // Trim the wildcard key String cleanWildcardKey = wildcardKey.trim(); - // If wildcard key is just '*', match everything - if (cleanWildcardKey.equals("*")) { + // Exact match if no wildcards + if (searchString.equals(wildcardKey)) { return true; } @@ -105,8 +95,8 @@ public boolean matchWildcard(String wildcardKey, String searchString) { return searchString.startsWith(prefix); } - // Exact match if no wildcards - return searchString.equals(wildcardKey); + // If wildcard key is just '*', match everything + return cleanWildcardKey.equals("*"); } } \ No newline at end of file diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java index 886a9b4..f6b852c 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java @@ -72,7 +72,12 @@ public void onNotification(PipelineMessageNotification notification) { config.getFlowCategorySuffix(), config.getFlowLogLevel(), flowLogAttributes); } catch (Exception e) { - classLogger.error("Error processing flow notification", e); + if (e.getClass().getName().equals("java.lang.ClassCastException") + || e.getClass().getName().equals("ClassCastException")) { + classLogger.error("Message expression text in flow-log-config needs to be a String", e); + } else { + classLogger.error("Error processing flow notification", e); + } } } else { classLogger.warn( From cf7a830e4730332d69400091c55dae37d20a8cdd Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Wed, 18 Dec 2024 14:18:24 -0600 Subject: [PATCH 06/11] Updated custom-logger-config.xml --- src/test/resources/custom-logger-config.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/resources/custom-logger-config.xml b/src/test/resources/custom-logger-config.xml index 991774b..e72c87b 100644 --- a/src/test/resources/custom-logger-config.xml +++ b/src/test/resources/custom-logger-config.xml @@ -8,9 +8,9 @@ http://www.mulesoft.org/schema/mule/avio-logger http://www.mulesoft.org/schema/m - - - + + + Date: Wed, 18 Dec 2024 14:38:01 -0600 Subject: [PATCH 07/11] Updated AVIO Custom logger Flow logs configuration for tests --- src/test/resources/custom-logger-config.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/resources/custom-logger-config.xml b/src/test/resources/custom-logger-config.xml index e72c87b..dc5bc30 100644 --- a/src/test/resources/custom-logger-config.xml +++ b/src/test/resources/custom-logger-config.xml @@ -15,9 +15,9 @@ http://www.mulesoft.org/schema/mule/avio-logger http://www.mulesoft.org/schema/m - - - + + + From c26f06bee80ad2e27556fd6acc3c6c68e9e757ae Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Wed, 18 Dec 2024 15:48:06 -0600 Subject: [PATCH 08/11] Updated default flow start log message with messageAttributeText --- .../listeners/CustomLoggerAbstractNotificationListener.java | 2 +- .../listeners/CustomLoggerPipelineNotificationListener.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index a0911e2..eeaf8ec 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -50,7 +50,7 @@ protected void logMessage(ComponentLocation location, Event event, String logMes protected Map getFlowLogAttributes(EnrichedServerNotification notification) { Map value = emptyAttributes; - FlowLogConfig flowLogConfig = config.getFlowLogConfigMap().get(notification.getResourceIdentifier()); + FlowLogConfig flowLogConfig; /** * Flow name can contain wildcard (*) * We only look for wildcard either starting of the string or ending of the diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java index f6b852c..74f60cd 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java @@ -56,7 +56,8 @@ public void onNotification(PipelineMessageNotification notification) { String message = "Event not processed yet, this should never be shown"; switch (Integer.parseInt(notification.getAction().getIdentifier())) { case PipelineMessageNotification.PROCESS_START: - message = "Flow [" + notification.getResourceIdentifier() + "]" + " start " + msgToAppend; + message = "Flow [" + notification.getResourceIdentifier() + "]" + " start " + + (msgToAppend != null ? msgToAppend : ""); break; case PipelineMessageNotification.PROCESS_COMPLETE: message = "Flow [" + notification.getResourceIdentifier() + "]" + " end"; From 3a2785796c7fa55166ce419f85dd7898cdff23d0 Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Wed, 18 Dec 2024 22:33:24 -0600 Subject: [PATCH 09/11] Updated with the review suggestions --- pom.xml | 2 +- .../logger/api/processor/ExpressionText.java | 35 ------------------ .../logger/api/processor/FlowLogConfig.java | 37 ++++++++++++++----- .../config/CustomLoggerConfiguration.java | 19 ++++++---- ...tomLoggerAbstractNotificationListener.java | 13 ++++--- ...tomLoggerPipelineNotificationListener.java | 12 +++--- src/test/resources/custom-logger-config.xml | 4 +- 7 files changed, 56 insertions(+), 66 deletions(-) delete mode 100644 src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java diff --git a/pom.xml b/pom.xml index 1dc96ae..d083b30 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ mule-custom-logger - 3.1.12-SNAPSHOT + 3.1.0-SNAPSHOT mule-extension Mule Custom Logger Mule Custom Logger module that provides standard structured logging diff --git a/src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java deleted file mode 100644 index 924e069..0000000 --- a/src/main/java/com/avioconsulting/mule/logger/api/processor/ExpressionText.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.avioconsulting.mule.logger.api.processor; - -import org.mule.runtime.extension.api.annotation.param.ExclusiveOptionals; -import org.mule.runtime.extension.api.annotation.param.Optional; -import org.mule.runtime.extension.api.annotation.param.Parameter; -import org.mule.runtime.extension.api.annotation.param.display.Summary; - -public class ExpressionText { - - @Parameter - @Optional - @Summary("A valid dataweave expression that resolves to a Map object with key-value pairs") - private String attributesExpressionText; - - @Parameter - @Optional - @Summary("A valid dataweave expression that results in a String to append to default flow start message") - private String messageExpressionText; - - public String getAttributesExpressionText() { - return attributesExpressionText; - } - - public void setAttributesExpressionText(String attributesExpressionText) { - this.attributesExpressionText = attributesExpressionText; - } - - public String getMessageExpressionText() { - return messageExpressionText; - } - - public void setMessageExpressionText(String messageExpressionText) { - this.messageExpressionText = messageExpressionText; - } -} diff --git a/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java index 34e2978..58adb80 100644 --- a/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java +++ b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java @@ -1,19 +1,43 @@ package com.avioconsulting.mule.logger.api.processor; import org.mule.runtime.extension.api.annotation.Alias; +import org.mule.runtime.extension.api.annotation.param.Optional; import org.mule.runtime.extension.api.annotation.param.Parameter; import org.mule.runtime.extension.api.annotation.param.ParameterGroup; import org.mule.runtime.extension.api.annotation.param.display.Summary; -@Alias("flow-logs-config") +@Alias("flow-log-config") public class FlowLogConfig { @Parameter @Summary("Name of the flow to associate given expression as attributes") private String flowName; - @ParameterGroup(name = "Flow Attributes") - private ExpressionText expressionText; + @Parameter + @Optional + @Summary("A valid dataweave expression that resolves to a Map object with key-value pairs") + private String attributesExpressionText; + + @Parameter + @Optional + @Summary("A valid dataweave expression that results in a String to append to default flow start message") + private String messageExpressionText; + + public String getAttributesExpressionText() { + return attributesExpressionText; + } + + public void setAttributesExpressionText(String attributesExpressionText) { + this.attributesExpressionText = attributesExpressionText; + } + + public String getMessageExpressionText() { + return messageExpressionText; + } + + public void setMessageExpressionText(String messageExpressionText) { + this.messageExpressionText = messageExpressionText; + } public String getFlowName() { return flowName; @@ -24,11 +48,4 @@ public FlowLogConfig setFlowName(String flowName) { return this; } - public ExpressionText getExpressionText() { - return expressionText; - } - - public void setExpressionText(ExpressionText expressionText) { - this.expressionText = expressionText; - } } diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java index 1c0eaef..0e37d01 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java @@ -345,13 +345,6 @@ public void start() throws MuleException { customLoggerRegistrationService.setConfig(this); if (isEnableFlowLogs()) { classLogger.info("Flow logs enabled"); - flowLogConfigs.forEach(flowLogConfig -> { - if (flowLogConfig.getExpressionText().getMessageExpressionText() == null - && flowLogConfig.getExpressionText().getAttributesExpressionText() == null) { - throw new IllegalStateException( - "One of attributesExpressionText or messageExpressionText must be defined in flow-logs-config"); - } - }); flowLogConfigMap = flowLogConfigs.stream().collect( Collectors.toMap(FlowLogConfig::getFlowName, Function.identity())); synchronized (CustomLoggerConfiguration.class) { @@ -387,5 +380,17 @@ public void initialise() throws InitialisationException { throw new InitialisationException(createStaticMessage( "Encryption Algorithm must be provided if encryption password is being supplied"), this); } + flowLogConfigs.forEach(flowLogConfig -> { + if (flowLogConfig.getMessageExpressionText() == null + && flowLogConfig.getAttributesExpressionText() == null) { + try { + throw new InitialisationException(createStaticMessage( + "One of attributesExpressionText or messageExpressionText must be defined in flow-logs-config"), + this); + } catch (InitialisationException e) { + throw new RuntimeException(e); + } + } + }); } } diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index eeaf8ec..7917063 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; public abstract class CustomLoggerAbstractNotificationListener { @@ -58,14 +59,14 @@ protected Map getFlowLogAttributes(EnrichedServerNotification no * ex: mq-listener-* will look for all the flows that starts with mq-listener * ex: *-mq-flow will look for all the flows that ends with -mq-flow **/ - List> matchedEntries = config.getFlowLogConfigMap().entrySet().stream() + Optional> matchedEntry = config.getFlowLogConfigMap().entrySet().stream() .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) - .collect(Collectors.toList()); - if (!matchedEntries.isEmpty()) { - flowLogConfig = matchedEntries.get(0).getValue(); + .findFirst(); + if (matchedEntry.isPresent()) { + flowLogConfig = matchedEntry.get().getValue(); TypedValue> evaluate = (TypedValue>) config .getExpressionManager() - .evaluate("#[" + flowLogConfig.getExpressionText().getAttributesExpressionText() + "]", + .evaluate("#[" + flowLogConfig.getAttributesExpressionText() + "]", notification.getEvent().asBindingContext()); value = evaluate.getValue(); if (value == null) @@ -79,7 +80,7 @@ public boolean matchWildcard(String wildcardKey, String searchString) { String cleanWildcardKey = wildcardKey.trim(); // Exact match if no wildcards - if (searchString.equals(wildcardKey)) { + if (searchString.equalsIgnoreCase(wildcardKey.toLowerCase())) { return true; } diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java index 74f60cd..256586f 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /* @@ -42,14 +43,15 @@ public void onNotification(PipelineMessageNotification notification) { if (config != null) { try { String msgToAppend = ""; - List> matchedEntries = config.getFlowLogConfigMap().entrySet().stream() + Optional> matchedEntry = config.getFlowLogConfigMap().entrySet() + .stream() .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier())) - .collect(Collectors.toList()); - if (!matchedEntries.isEmpty()) { - FlowLogConfig flowLogConfig = matchedEntries.get(0).getValue(); + .findFirst(); + if (matchedEntry.isPresent()) { + FlowLogConfig flowLogConfig = matchedEntry.get().getValue(); TypedValue evaluate = (TypedValue) config .getExpressionManager() - .evaluate("#[" + flowLogConfig.getExpressionText().getMessageExpressionText() + "]", + .evaluate("#[" + flowLogConfig.getMessageExpressionText() + "]", notification.getEvent().asBindingContext()); msgToAppend = evaluate.getValue(); } diff --git a/src/test/resources/custom-logger-config.xml b/src/test/resources/custom-logger-config.xml index dc5bc30..96f6c63 100644 --- a/src/test/resources/custom-logger-config.xml +++ b/src/test/resources/custom-logger-config.xml @@ -9,14 +9,14 @@ http://www.mulesoft.org/schema/mule/avio-logger http://www.mulesoft.org/schema/m - + - + From c2050121bac655edbad23fd6b1abc49d39ed6b38 Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Thu, 19 Dec 2024 00:33:07 -0600 Subject: [PATCH 10/11] Updated ClassCastException handling and error message --- .../internal/config/CustomLoggerConfiguration.java | 2 +- .../CustomLoggerPipelineNotificationListener.java | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java index 0e37d01..8aff082 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/config/CustomLoggerConfiguration.java @@ -385,7 +385,7 @@ public void initialise() throws InitialisationException { && flowLogConfig.getAttributesExpressionText() == null) { try { throw new InitialisationException(createStaticMessage( - "One of attributesExpressionText or messageExpressionText must be defined in flow-logs-config"), + "Both 'attributesExpressionText' and 'messageExpressionText' cannot be empty, at least one or both must be specified."), this); } catch (InitialisationException e) { throw new RuntimeException(e); diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java index 256586f..931fcee 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerPipelineNotificationListener.java @@ -74,13 +74,10 @@ public void onNotification(PipelineMessageNotification notification) { logMessage(notification.getComponent().getLocation(), notification.getEvent(), message, config.getFlowCategorySuffix(), config.getFlowLogLevel(), flowLogAttributes); + } catch (ClassCastException castException) { + classLogger.error("Message expression text in flow-log-config needs to be a String", castException); } catch (Exception e) { - if (e.getClass().getName().equals("java.lang.ClassCastException") - || e.getClass().getName().equals("ClassCastException")) { - classLogger.error("Message expression text in flow-log-config needs to be a String", e); - } else { - classLogger.error("Error processing flow notification", e); - } + classLogger.error("Error processing flow notification", e); } } else { classLogger.warn( From bea33c0c6eb1e5cc109bf91625703387e916f5eb Mon Sep 17 00:00:00 2001 From: Anil Konakalla Date: Thu, 19 Dec 2024 00:43:23 -0600 Subject: [PATCH 11/11] Removed redundant validation for case insensitive validation in String --- .../listeners/CustomLoggerAbstractNotificationListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java index 7917063..e795d74 100644 --- a/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java +++ b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java @@ -80,7 +80,7 @@ public boolean matchWildcard(String wildcardKey, String searchString) { String cleanWildcardKey = wildcardKey.trim(); // Exact match if no wildcards - if (searchString.equalsIgnoreCase(wildcardKey.toLowerCase())) { + if (searchString.equalsIgnoreCase(wildcardKey)) { return true; }