You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/02/11 11:01:09 UTC

(camel) 01/04: CAMEL-20408: camel-core - Tracer should include exchange variables

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch var-trace
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 69887262c90eafaf0a57a73fd60c10dff68d5977
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Feb 11 11:16:35 2024 +0100

    CAMEL-20408: camel-core - Tracer should include exchange variables
---
 .../main/camel-main-configuration-metadata.json    |   1 +
 .../java/org/apache/camel/spi/BacklogDebugger.java |  10 ++
 .../java/org/apache/camel/spi/BacklogTracer.java   |  10 ++
 .../apache/camel/impl/debugger/BacklogTracer.java  |  11 ++
 .../impl/debugger/DefaultBacklogDebugger.java      |  15 ++-
 .../camel/impl/engine/CamelInternalProcessor.java  |  14 ++-
 .../DebuggerConfigurationPropertiesConfigurer.java |   6 ++
 .../camel-main-configuration-metadata.json         |   1 +
 core/camel-main/src/main/docs/main.adoc            |   3 +-
 .../org/apache/camel/main/BaseMainSupport.java     |   1 +
 .../main/DebuggerConfigurationProperties.java      |  21 ++++
 .../mbean/ManagedBacklogDebuggerMBean.java         |   6 ++
 .../mbean/ManagedBacklogTracerMBean.java           |  12 ++-
 .../management/mbean/ManagedBacklogDebugger.java   |  10 ++
 .../management/mbean/ManagedBacklogTracer.java     |  10 ++
 .../org/apache/camel/support/MessageHelper.java    | 111 +++++++++++++++++----
 16 files changed, 210 insertions(+), 32 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 099d60d0bcc..127e310a2c6 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -143,6 +143,7 @@
     { "name": "camel.debug.fallbackTimeout", "description": "Fallback Timeout in seconds (300 seconds as default) when block the message processing in Camel. A timeout used for waiting for a message to arrive at a given breakpoint.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "integer", "javaType": "long", "defaultValue": 300 },
     { "name": "camel.debug.includeException", "description": "Trace messages to include exception if the message failed", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.debug.includeExchangeProperties", "description": "Whether to include the exchange properties in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
+    { "name": "camel.debug.includeExchangeVariables", "description": "Whether to include the exchange variables in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.debug.loggingLevel", "description": "The debugger logging level to use when logging activity.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "object", "javaType": "org.apache.camel.LoggingLevel", "defaultValue": "INFO", "enum": [ "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" ] },
     { "name": "camel.debug.singleStepIncludeStartEnd", "description": "In single step mode, then when the exchange is created and completed, then simulate a breakpoint at start and end, that allows to suspend and watch the incoming\/complete exchange at the route (you can see message body as response, failed exception etc).", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.debug.standby", "description": "To set the debugger in standby mode, where the debugger will be installed by not automatic enabled. The debugger can then later be enabled explicit from Java, JMX or tooling.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java
index b8582c98f12..19d1b601b18 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java
@@ -352,6 +352,16 @@ public interface BacklogDebugger extends StatefulService {
      */
     void setIncludeExchangeProperties(boolean includeExchangeProperties);
 
+    /**
+     * Whether to include the exchange variables in the traced message
+     */
+    boolean isIncludeExchangeVariables();
+
+    /**
+     * Whether to include the exchange variables in the traced message
+     */
+    void setIncludeExchangeVariables(boolean includeExchangeVariables);
+
     /**
      * Trace messages to include exception if the message failed
      */
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java
index 3c894a95294..8e2f6db25cc 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java
@@ -109,6 +109,16 @@ public interface BacklogTracer {
      */
     void setIncludeExchangeProperties(boolean includeExchangeProperties);
 
+    /**
+     * Trace messages to include exchange variables
+     */
+    boolean isIncludeExchangeVariables();
+
+    /**
+     * Trace messages to include exchange variables
+     */
+    void setIncludeExchangeVariables(boolean includeExchangeVariables);
+
     /**
      * Trace messages to include exception if the message failed
      */
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java
index a2c3dc003a3..bc49984feef 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java
@@ -61,6 +61,7 @@ public final class BacklogTracer extends ServiceSupport implements org.apache.ca
     private boolean bodyIncludeStreams;
     private boolean bodyIncludeFiles = true;
     private boolean includeExchangeProperties = true;
+    private boolean includeExchangeVariables = true;
     private boolean includeException = true;
     private boolean traceRests;
     private boolean traceTemplates;
@@ -236,6 +237,16 @@ public final class BacklogTracer extends ServiceSupport implements org.apache.ca
         this.includeExchangeProperties = includeExchangeProperties;
     }
 
+    @Override
+    public boolean isIncludeExchangeVariables() {
+        return includeExchangeVariables;
+    }
+
+    @Override
+    public void setIncludeExchangeVariables(boolean includeExchangeVariables) {
+        this.includeExchangeVariables = includeExchangeVariables;
+    }
+
     @Override
     public boolean isIncludeException() {
         return includeException;
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java
index ddf5dfa51a2..93f6e87d5e8 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java
@@ -82,6 +82,7 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
     private boolean bodyIncludeStreams;
     private boolean bodyIncludeFiles = true;
     private boolean includeExchangeProperties = true;
+    private boolean includeExchangeVariables = true;
     private boolean includeException = true;
 
     /**
@@ -677,6 +678,16 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
         this.includeExchangeProperties = includeExchangeProperties;
     }
 
+    @Override
+    public boolean isIncludeExchangeVariables() {
+        return includeExchangeVariables;
+    }
+
+    @Override
+    public void setIncludeExchangeVariables(boolean includeExchangeVariables) {
+        this.includeExchangeVariables = includeExchangeVariables;
+    }
+
     @Override
     public boolean isIncludeException() {
         return includeException;
@@ -792,7 +803,7 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
      * @return          the XML
      */
     private String dumpAsXml(Exchange exchange) {
-        return MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, true, 2, true,
+        return MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, includeExchangeVariables, true, 2, true,
                 isBodyIncludeStreams(), isBodyIncludeFiles(),
                 getBodyMaxChars());
     }
@@ -804,7 +815,7 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
      * @return          the JSon
      */
     private String dumpAsJSon(Exchange exchange) {
-        return MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, true, 2, true,
+        return MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, includeExchangeVariables, true, 2, true,
                 isBodyIncludeStreams(), isBodyIncludeFiles(),
                 getBodyMaxChars(), true);
     }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java
index f1560cf6122..9823a00f2f9 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java
@@ -636,10 +636,13 @@ public class CamelInternalProcessor extends DelegateAsyncProcessor implements In
                 String toNode = processorDefinition.getId();
                 String exchangeId = exchange.getExchangeId();
                 boolean includeExchangeProperties = backlogTracer.isIncludeExchangeProperties();
-                String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, true, 4,
+                boolean includeExchangeVariables = backlogTracer.isIncludeExchangeVariables();
+                String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties,
+                        includeExchangeVariables, true, 4,
                         true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(),
                         backlogTracer.getBodyMaxChars());
-                String messageAsJSon = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, true, 4,
+                String messageAsJSon = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties,
+                        includeExchangeVariables, true, 4,
                         true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(),
                         backlogTracer.getBodyMaxChars(), true);
 
@@ -675,12 +678,15 @@ public class CamelInternalProcessor extends DelegateAsyncProcessor implements In
                     String routeId = routeDefinition != null ? routeDefinition.getRouteId() : null;
                     String exchangeId = exchange.getExchangeId();
                     boolean includeExchangeProperties = backlogTracer.isIncludeExchangeProperties();
+                    boolean includeExchangeVariables = backlogTracer.isIncludeExchangeVariables();
                     long created = exchange.getClock().getCreated();
-                    String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, true, 4,
+                    String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties,
+                            includeExchangeVariables, true, 4,
                             true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(),
                             backlogTracer.getBodyMaxChars());
                     String messageAsJSon
-                            = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, true, 4,
+                            = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, includeExchangeVariables,
+                                    true, 4,
                                     true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(),
                                     backlogTracer.getBodyMaxChars(), true);
                     DefaultBacklogTracerEventMessage pseudoLast = new DefaultBacklogTracerEventMessage(
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java
index c9b2f6c3d92..b2bf189dfd5 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java
@@ -37,6 +37,8 @@ public class DebuggerConfigurationPropertiesConfigurer extends org.apache.camel.
         case "IncludeException": target.setIncludeException(property(camelContext, boolean.class, value)); return true;
         case "includeexchangeproperties":
         case "IncludeExchangeProperties": target.setIncludeExchangeProperties(property(camelContext, boolean.class, value)); return true;
+        case "includeexchangevariables":
+        case "IncludeExchangeVariables": target.setIncludeExchangeVariables(property(camelContext, boolean.class, value)); return true;
         case "logginglevel":
         case "LoggingLevel": target.setLoggingLevel(property(camelContext, org.apache.camel.LoggingLevel.class, value)); return true;
         case "singlestepincludestartend":
@@ -68,6 +70,8 @@ public class DebuggerConfigurationPropertiesConfigurer extends org.apache.camel.
         case "IncludeException": return boolean.class;
         case "includeexchangeproperties":
         case "IncludeExchangeProperties": return boolean.class;
+        case "includeexchangevariables":
+        case "IncludeExchangeVariables": return boolean.class;
         case "logginglevel":
         case "LoggingLevel": return org.apache.camel.LoggingLevel.class;
         case "singlestepincludestartend":
@@ -100,6 +104,8 @@ public class DebuggerConfigurationPropertiesConfigurer extends org.apache.camel.
         case "IncludeException": return target.isIncludeException();
         case "includeexchangeproperties":
         case "IncludeExchangeProperties": return target.isIncludeExchangeProperties();
+        case "includeexchangevariables":
+        case "IncludeExchangeVariables": return target.isIncludeExchangeVariables();
         case "logginglevel":
         case "LoggingLevel": return target.getLoggingLevel();
         case "singlestepincludestartend":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 099d60d0bcc..127e310a2c6 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -143,6 +143,7 @@
     { "name": "camel.debug.fallbackTimeout", "description": "Fallback Timeout in seconds (300 seconds as default) when block the message processing in Camel. A timeout used for waiting for a message to arrive at a given breakpoint.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "integer", "javaType": "long", "defaultValue": 300 },
     { "name": "camel.debug.includeException", "description": "Trace messages to include exception if the message failed", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.debug.includeExchangeProperties", "description": "Whether to include the exchange properties in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
+    { "name": "camel.debug.includeExchangeVariables", "description": "Whether to include the exchange variables in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.debug.loggingLevel", "description": "The debugger logging level to use when logging activity.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "object", "javaType": "org.apache.camel.LoggingLevel", "defaultValue": "INFO", "enum": [ "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" ] },
     { "name": "camel.debug.singleStepIncludeStartEnd", "description": "In single step mode, then when the exchange is created and completed, then simulate a breakpoint at start and end, that allows to suspend and watch the incoming\/complete exchange at the route (you can see message body as response, failed exception etc).", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.debug.standby", "description": "To set the debugger in standby mode, where the debugger will be installed by not automatic enabled. The debugger can then later be enabled explicit from Java, JMX or tooling.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index cc34a460ad7..c709db4e390 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -187,7 +187,7 @@ The camel.server supports 12 options, which are listed below.
 
 
 === Camel Debugger configurations
-The camel.debug supports 12 options, which are listed below.
+The camel.debug supports 13 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -200,6 +200,7 @@ The camel.debug supports 12 options, which are listed below.
 | *camel.debug.fallbackTimeout* | Fallback Timeout in seconds (300 seconds as default) when block the message processing in Camel. A timeout used for waiting for a message to arrive at a given breakpoint. | 300 | long
 | *camel.debug.includeException* | Trace messages to include exception if the message failed | true | boolean
 | *camel.debug.includeExchange{zwsp}Properties* | Whether to include the exchange properties in the traced message | true | boolean
+| *camel.debug.includeExchange{zwsp}Variables* | Whether to include the exchange variables in the traced message | true | boolean
 | *camel.debug.loggingLevel* | The debugger logging level to use when logging activity. | INFO | LoggingLevel
 | *camel.debug.singleStepInclude{zwsp}StartEnd* | In single step mode, then when the exchange is created and completed, then simulate a breakpoint at start and end, that allows to suspend and watch the incoming/complete exchange at the route (you can see message body as response, failed exception etc). | false | boolean
 | *camel.debug.standby* | To set the debugger in standby mode, where the debugger will be installed by not automatic enabled. The debugger can then later be enabled explicit from Java, JMX or tooling. | false | boolean
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index 0537932ae48..e01c21dc446 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -1649,6 +1649,7 @@ public abstract class BaseMainSupport extends BaseService {
         debugger.setBodyIncludeStreams(config.isBodyIncludeStreams());
         debugger.setBodyIncludeFiles(config.isBodyIncludeFiles());
         debugger.setIncludeExchangeProperties(config.isIncludeExchangeProperties());
+        debugger.setIncludeExchangeVariables(config.isIncludeExchangeVariables());
         debugger.setIncludeException(config.isIncludeException());
         debugger.setLoggingLevel(config.getLoggingLevel().name());
         debugger.setSuspendMode(config.isWaitForAttach());
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java
index 684e53d68bc..931ce75f930 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java
@@ -50,6 +50,8 @@ public class DebuggerConfigurationProperties implements BootstrapCloseable {
     @Metadata(defaultValue = "true")
     private boolean includeExchangeProperties = true;
     @Metadata(defaultValue = "true")
+    private boolean includeExchangeVariables = true;
+    @Metadata(defaultValue = "true")
     private boolean includeException = true;
     @Metadata(label = "advanced", defaultValue = "300")
     private long fallbackTimeout = 300;
@@ -185,6 +187,17 @@ public class DebuggerConfigurationProperties implements BootstrapCloseable {
         this.includeExchangeProperties = includeExchangeProperties;
     }
 
+    public boolean isIncludeExchangeVariables() {
+        return includeExchangeVariables;
+    }
+
+    /**
+     * Whether to include the exchange variables in the traced message
+     */
+    public void setIncludeExchangeVariables(boolean includeExchangeVariables) {
+        this.includeExchangeVariables = includeExchangeVariables;
+    }
+
     public boolean isIncludeException() {
         return includeException;
     }
@@ -296,6 +309,14 @@ public class DebuggerConfigurationProperties implements BootstrapCloseable {
         return this;
     }
 
+    /**
+     * Whether to include the exchange variables in the traced message
+     */
+    public DebuggerConfigurationProperties withIncludeExchangeVariables(boolean includeExchangeVariables) {
+        this.includeExchangeVariables = includeExchangeVariables;
+        return this;
+    }
+
     /**
      * Trace messages to include exception if the message failed
      */
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java
index 3a1dc32a26c..783c6a5d2cd 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java
@@ -137,6 +137,12 @@ public interface ManagedBacklogDebuggerMBean {
     @ManagedAttribute(description = "Whether to include exchange properties in the trace message.")
     void setIncludeExchangeProperties(boolean includeExchangeProperties);
 
+    @ManagedAttribute(description = "Whether to include exchange variables in the trace message.")
+    boolean isIncludeExchangeVariables();
+
+    @ManagedAttribute(description = "Whether to include exchange variables in the trace message.")
+    void setIncludeExchangeVariables(boolean includeExchangeVariables);
+
     @ManagedOperation(description = "Dumps the messages in XML format from the suspended breakpoint at the given node.")
     String dumpTracedMessagesAsXml(String nodeId);
 
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java
index d89f8b63b68..0f343d4c60c 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java
@@ -93,15 +93,21 @@ public interface ManagedBacklogTracerMBean {
     @ManagedAttribute(description = "Whether to include exchange properties in the trace message.")
     boolean isIncludeExchangeProperties();
 
+    @ManagedAttribute(description = "Whether to include exchange properties in the trace message.")
+    void setIncludeExchangeProperties(boolean includeExchangeProperties);
+
+    @ManagedAttribute(description = "Whether to include exchange variables in the trace message.")
+    boolean isIncludeExchangeVariables();
+
+    @ManagedAttribute(description = "Whether to include exchange variables in the trace message.")
+    void setIncludeExchangeVariables(boolean includeExchangeVariables);
+
     @ManagedAttribute(description = "Whether tracing routes created from Rest DSL.")
     boolean isTraceRests();
 
     @ManagedAttribute(description = "Whether tracing routes created from route templates or kamelets.")
     boolean isTraceTemplates();
 
-    @ManagedAttribute(description = "Whether to include exchange properties in the trace message.")
-    void setIncludeExchangeProperties(boolean includeExchangeProperties);
-
     @ManagedOperation(description = "Dumps the traced messages for the given node or route")
     List<BacklogTracerEventMessage> dumpTracedMessages(String nodeOrRouteId);
 
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java
index f5980dced53..edb5fc411db 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java
@@ -236,6 +236,16 @@ public class ManagedBacklogDebugger implements ManagedBacklogDebuggerMBean {
         backlogDebugger.setIncludeExchangeProperties(includeExchangeProperties);
     }
 
+    @Override
+    public boolean isIncludeExchangeVariables() {
+        return backlogDebugger.isIncludeExchangeVariables();
+    }
+
+    @Override
+    public void setIncludeExchangeVariables(boolean includeExchangeVariables) {
+        backlogDebugger.setIncludeExchangeVariables(includeExchangeVariables);
+    }
+
     @Override
     public boolean isBodyIncludeStreams() {
         return backlogDebugger.isBodyIncludeStreams();
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java
index d697e8d79af..706d6ae5324 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java
@@ -171,6 +171,16 @@ public class ManagedBacklogTracer implements ManagedBacklogTracerMBean {
         backlogTracer.setIncludeExchangeProperties(includeExchangeProperties);
     }
 
+    @Override
+    public boolean isIncludeExchangeVariables() {
+        return backlogTracer.isIncludeExchangeVariables();
+    }
+
+    @Override
+    public void setIncludeExchangeVariables(boolean includeExchangeVariables) {
+        backlogTracer.setIncludeExchangeVariables(includeExchangeVariables);
+    }
+
     @Override
     public boolean isTraceRests() {
         return backlogTracer.isTraceRests();
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java
index 4382bb347d4..440af06d3d8 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java
@@ -470,15 +470,16 @@ public final class MessageHelper {
      */
     public static String dumpAsXml(
             Message message, boolean includeBody, int indent, boolean allowStreams, boolean allowFiles, int maxChars) {
-        return dumpAsXml(message, false, includeBody, indent, allowStreams, allowStreams, allowFiles, maxChars);
+        return dumpAsXml(message, false, false, includeBody, indent, allowStreams, allowStreams, allowFiles, maxChars);
     }
 
     /**
      * Dumps the message as a generic XML structure.
      *
      * @param  message                   the message
-     * @param  includeBody               whether or not to include the message body
      * @param  includeExchangeProperties whether or not to include exchange properties
+     * @param  includeExchangeVariables  whether or not to include exchange variables
+     * @param  includeBody               whether or not to include the message body
      * @param  indent                    number of spaces to indent
      * @param  allowCachedStreams        whether to include message body if they are stream cache based
      * @param  allowStreams              whether to include message body if they are stream based
@@ -488,8 +489,9 @@ public final class MessageHelper {
      * @return                           the XML
      */
     public static String dumpAsXml(
-            Message message, boolean includeExchangeProperties, boolean includeBody, int indent,
-            boolean allowCachedStreams, boolean allowStreams, boolean allowFiles, int maxChars) {
+            Message message, boolean includeExchangeProperties, boolean includeExchangeVariables,
+            boolean includeBody, int indent, boolean allowCachedStreams, boolean allowStreams,
+            boolean allowFiles, int maxChars) {
         StringBuilder sb = new StringBuilder();
 
         StringBuilder prefix = new StringBuilder();
@@ -504,6 +506,40 @@ public final class MessageHelper {
                 .append("\" exchangeType=\"").append(exchangeType)
                 .append("\" messageType=\"").append(messageType).append("\">\n");
 
+        // exchange variables
+        if (includeExchangeVariables && message.getExchange().hasVariables()) {
+            sb.append(prefix);
+            sb.append("  <exchangeVariables>\n");
+            // sort the exchange variables so they are listed A..Z
+            Map<String, Object> variables = new TreeMap<>(message.getExchange().getVariables());
+            for (Map.Entry<String, Object> entry : variables.entrySet()) {
+                String key = entry.getKey();
+                Object value = entry.getValue();
+                String type = ObjectHelper.classCanonicalName(value);
+                sb.append(prefix);
+                sb.append("    <exchangeVariable key=\"").append(key).append("\"");
+                if (type != null) {
+                    sb.append(" type=\"").append(type).append("\"");
+                }
+                sb.append(">");
+
+                // dump value as XML, use Camel type converter to convert to String
+                if (value != null) {
+                    try {
+                        String xml = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars);
+                        if (xml != null) {
+                            // must always xml encode
+                            sb.append(StringHelper.xmlEncode(xml));
+                        }
+                    } catch (Exception e) {
+                        // ignore as the body is for logging purpose
+                    }
+                }
+                sb.append("</exchangeVariable>\n");
+            }
+            sb.append(prefix);
+            sb.append("  </exchangeVariables>\n");
+        }
         // exchange properties
         if (includeExchangeProperties && message.getExchange().hasProperties()) {
             sb.append(prefix);
@@ -525,12 +561,10 @@ public final class MessageHelper {
                 }
                 sb.append(">");
 
-                // dump header value as XML, use Camel type converter to convert
-                // to String
+                // dump value as XML, use Camel type converter to convert to String
                 if (value != null) {
                     try {
-                        String xml = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class,
-                                message.getExchange(), value);
+                        String xml = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars);
                         if (xml != null) {
                             // must always xml encode
                             sb.append(StringHelper.xmlEncode(xml));
@@ -539,7 +573,6 @@ public final class MessageHelper {
                         // ignore as the body is for logging purpose
                     }
                 }
-
                 sb.append("</exchangeProperty>\n");
             }
             sb.append(prefix);
@@ -561,12 +594,10 @@ public final class MessageHelper {
                 }
                 sb.append(">");
 
-                // dump header value as XML, use Camel type converter to convert
-                // to String
+                // dump value as XML, use Camel type converter to convert to String
                 if (value != null) {
                     try {
-                        String xml = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class,
-                                message.getExchange(), value);
+                        String xml = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars);
                         if (xml != null) {
                             // must always xml encode
                             sb.append(StringHelper.xmlEncode(xml));
@@ -575,7 +606,6 @@ public final class MessageHelper {
                         // ignore as the body is for logging purpose
                     }
                 }
-
                 sb.append("</header>\n");
             }
             sb.append(prefix);
@@ -859,7 +889,7 @@ public final class MessageHelper {
     public static String dumpAsJSon(
             Message message, boolean includeBody, int indent, boolean allowStreams, boolean allowFiles, int maxChars,
             boolean pretty) {
-        return dumpAsJSon(message, false, includeBody, indent, false, allowStreams, allowFiles, maxChars, pretty);
+        return dumpAsJSon(message, false, false, includeBody, indent, false, allowStreams, allowFiles, maxChars, pretty);
     }
 
     /**
@@ -867,6 +897,7 @@ public final class MessageHelper {
      *
      * @param  message                   the message
      * @param  includeExchangeProperties whether or not to include exchange properties
+     * @param  includeExchangeVariables  whether or not to include exchange variables
      * @param  includeBody               whether or not to include the message body
      * @param  indent                    number of spaces to indent
      * @param  allowCachedStreams        whether to include message body if they are stream cached based
@@ -878,10 +909,12 @@ public final class MessageHelper {
      * @return                           the JSon
      */
     public static String dumpAsJSon(
-            Message message, boolean includeExchangeProperties, boolean includeBody, int indent,
+            Message message, boolean includeExchangeProperties, boolean includeExchangeVariables, boolean includeBody,
+            int indent,
             boolean allowCachedStreams, boolean allowStreams, boolean allowFiles, int maxChars, boolean pretty) {
 
-        JsonObject jo = dumpAsJSonObject(message, includeExchangeProperties, includeBody, allowCachedStreams, allowStreams,
+        JsonObject jo = dumpAsJSonObject(message, includeExchangeProperties, includeExchangeVariables, includeBody,
+                allowCachedStreams, allowStreams,
                 allowFiles, maxChars);
         String answer = jo.toJson();
         if (pretty) {
@@ -899,6 +932,7 @@ public final class MessageHelper {
      *
      * @param  message                   the message
      * @param  includeExchangeProperties whether or not to include exchange properties
+     * @param  includeExchangeVariables  whether or not to include exchange variables
      * @param  includeBody               whether or not to include the message body
      * @param  allowCachedStreams        whether to include message body if they are stream cached based
      * @param  allowStreams              whether to include message body if they are stream based
@@ -908,7 +942,7 @@ public final class MessageHelper {
      * @return                           the JSon Object
      */
     public static JsonObject dumpAsJSonObject(
-            Message message, boolean includeExchangeProperties, boolean includeBody,
+            Message message, boolean includeExchangeProperties, boolean includeExchangeVariables, boolean includeBody,
             boolean allowCachedStreams, boolean allowStreams, boolean allowFiles, int maxChars) {
 
         JsonObject root = new JsonObject();
@@ -919,6 +953,41 @@ public final class MessageHelper {
         jo.put("exchangeType", ObjectHelper.classCanonicalName(message.getExchange()));
         jo.put("messageType", ObjectHelper.classCanonicalName(message));
 
+        // exchange variables
+        if (includeExchangeVariables && message.getExchange().hasVariables()) {
+            JsonArray arr = new JsonArray();
+            // sort the exchange variables so they are listed A..Z
+            Map<String, Object> properties = new TreeMap<>(message.getExchange().getVariables());
+            for (Map.Entry<String, Object> entry : properties.entrySet()) {
+                Object value = entry.getValue();
+                String type = ObjectHelper.classCanonicalName(value);
+                JsonObject jh = new JsonObject();
+                String key = entry.getKey();
+                jh.put("key", key);
+                if (type != null) {
+                    jh.put("type", type);
+                }
+                if (value != null) {
+                    Object s = Jsoner.trySerialize(value);
+                    if (s == null) {
+                        // cannot JSon serialize out of the box, so we need to use string value
+                        try {
+                            s = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars);
+                        } catch (Exception e) {
+                            // ignore
+                        }
+                    } else {
+                        // use the value as-is because it can be serialized in json
+                        s = value;
+                    }
+                    jh.put("value", s);
+                }
+                arr.add(jh);
+            }
+            if (!arr.isEmpty()) {
+                jo.put("exchangeVariables", arr);
+            }
+        }
         // exchange properties
         if (includeExchangeProperties && message.getExchange().hasProperties()) {
             JsonArray arr = new JsonArray();
@@ -942,8 +1011,7 @@ public final class MessageHelper {
                     if (s == null) {
                         // cannot JSon serialize out of the box, so we need to use string value
                         try {
-                            s = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class,
-                                    message.getExchange(), value);
+                            s = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars);
                         } catch (Exception e) {
                             // ignore
                         }
@@ -978,8 +1046,7 @@ public final class MessageHelper {
                     if (s == null) {
                         // cannot JSon serialize out of the box, so we need to use string value
                         try {
-                            s = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class,
-                                    message.getExchange(), value);
+                            s = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars);
                         } catch (Exception e) {
                             // ignore
                         }