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/FlowLogConfig.java b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java
new file mode 100644
index 0000000..58adb80
--- /dev/null
+++ b/src/main/java/com/avioconsulting/mule/logger/api/processor/FlowLogConfig.java
@@ -0,0 +1,51 @@
+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-log-config")
+public class FlowLogConfig {
+
+ @Parameter
+ @Summary("Name of the flow to associate given expression as attributes")
+ private String flowName;
+
+ @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;
+ }
+
+ public FlowLogConfig setFlowName(String flowName) {
+ this.flowName = flowName;
+ return this;
+ }
+
+}
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..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
@@ -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.FlowLogConfig;
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,21 @@
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.function.Function;
+import java.util.stream.Collectors;
+
/**
* This class represents an extension configuration, values set in this class
* are commonly used across multiple
@@ -83,6 +91,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 flowLogConfigs;
+
@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 +154,10 @@ public class CustomLoggerConfiguration implements Startable, Initialisable {
@Inject
ExtensionsClient extensionsClient;
+ @Inject
+ ExpressionManager expressionManager;
+ private Map flowLogConfigMap;
+
/**
* Default constructor for auto-initialization
*/
@@ -175,6 +195,15 @@ public CustomLoggerConfiguration(CustomLoggerRegistrationService customLoggerReg
private static boolean isNotificationListenerRegistered = false;
+ public Map getFlowLogConfigMap() {
+ return flowLogConfigMap;
+ }
+
+ public CustomLoggerConfiguration setFlowLogConfigs(List flowLogConfigs) {
+ this.flowLogConfigs = flowLogConfigs;
+ return this;
+ }
+
public String getApplicationName() {
return applicationName;
}
@@ -291,6 +320,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 +345,8 @@ public void start() throws MuleException {
customLoggerRegistrationService.setConfig(this);
if (isEnableFlowLogs()) {
classLogger.info("Flow logs enabled");
+ flowLogConfigMap = flowLogConfigs.stream().collect(
+ Collectors.toMap(FlowLogConfig::getFlowName, Function.identity()));
synchronized (CustomLoggerConfiguration.class) {
if (!isNotificationListenerRegistered) {
classLogger.info("Creating and registering notification listener");
@@ -345,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(
+ "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/CustomLoggerAbstractNotificationListener.java b/src/main/java/com/avioconsulting/mule/logger/internal/listeners/CustomLoggerAbstractNotificationListener.java
index 5aad95a..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
@@ -1,16 +1,22 @@
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;
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.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
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,56 @@ 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;
+ FlowLogConfig flowLogConfig;
+ /**
+ * 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
+ **/
+ Optional> matchedEntry = config.getFlowLogConfigMap().entrySet().stream()
+ .filter(entry -> matchWildcard(entry.getKey(), notification.getResourceIdentifier()))
+ .findFirst();
+ if (matchedEntry.isPresent()) {
+ flowLogConfig = matchedEntry.get().getValue();
+ TypedValue