This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch feature/CAMEL-24003-backlog-tracer-activity-queue in repository https://gitbox.apache.org/repos/asf/camel.git
commit 54a3c9747f4f0553e853c35e3b0b1c183f4f62a9 Author: Claus Ibsen <[email protected]> AuthorDate: Sat Jul 11 10:31:22 2026 +0200 CAMEL-24003: Add activity queue to BacklogTracer Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../apache/camel/catalog/dev-consoles.properties | 1 + .../camel/catalog/dev-consoles/activity.json | 15 ++++ .../main/camel-main-configuration-metadata.json | 1 + .../java/org/apache/camel/spi/BacklogTracer.java | 42 ++++++++++ .../apache/camel/impl/debugger/BacklogTracer.java | 79 ++++++++++++++++++ .../org/apache/camel/dev-console/activity.json | 15 ++++ .../services/org/apache/camel/dev-console/activity | 2 + .../org/apache/camel/dev-consoles.properties | 2 +- .../camel/impl/console/ActivityDevConsole.java | 94 ++++++++++++++++++++++ .../TracerConfigurationPropertiesConfigurer.java | 7 ++ .../camel-main-configuration-metadata.json | 1 + core/camel-main/src/main/docs/main.adoc | 3 +- .../org/apache/camel/main/BaseMainSupport.java | 1 + .../camel/main/TracerConfigurationProperties.java | 23 ++++++ .../mbean/ManagedBacklogTracerMBean.java | 9 +++ .../management/mbean/ManagedBacklogTracer.java | 15 ++++ 16 files changed, 308 insertions(+), 2 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties index 92fda01cffe3..ade3587e222b 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties @@ -1,3 +1,4 @@ +activity aws-secrets aws2-s3 azure-secrets diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/activity.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/activity.json new file mode 100644 index 000000000000..1c8f94954a0e --- /dev/null +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/activity.json @@ -0,0 +1,15 @@ +{ + "console": { + "kind": "console", + "group": "camel", + "name": "activity", + "title": "Camel Activity", + "description": "Recent completed exchange activity", + "deprecated": false, + "javaType": "org.apache.camel.impl.console.ActivityDevConsole", + "groupId": "org.apache.camel", + "artifactId": "camel-console", + "version": "4.22.0-SNAPSHOT" + } +} + 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 034183e3dda7..9c5e7a7718e5 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 @@ -483,6 +483,7 @@ { "name": "camel.threadpool.poolSize", "required": false, "description": "Sets the default core pool size (threads to keep minimum in pool)", "sourceType": "org.apache.camel.main.ThreadPoolConfigurationProperties", "type": "integer", "javaType": "java.lang.Integer", "secret": false }, { "name": "camel.threadpool.rejectedPolicy", "required": false, "description": "Sets the default handler for tasks which cannot be executed by the thread pool.", "sourceType": "org.apache.camel.main.ThreadPoolConfigurationProperties", "type": "enum", "javaType": "org.apache.camel.util.concurrent.ThreadPoolRejectedPolicy", "secret": false, "enum": [ "Abort", "CallerRuns", "DiscardOldest", "Discard" ] }, { "name": "camel.threadpool.timeUnit", "required": false, "description": "Sets the default time unit used for keep alive time", "sourceType": "org.apache.camel.main.ThreadPoolConfigurationProperties", "type": "object", "javaType": "java.util.concurrent.TimeUnit", "secret": false }, + { "name": "camel.trace.activitySize", "required": false, "description": "Defines how many completed exchange summaries to keep in the activity queue (should be between 1 - 1000). The activity queue captures lightweight metadata (no body or headers) each time an exchange completes a route, providing a rolling window of recent exchange activity.", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 100, "secret": false }, { "name": "camel.trace.backlogSize", "required": false, "description": "Defines how many of the last messages to keep in the tracer (should be between 1 - 1000).", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 100, "secret": false }, { "name": "camel.trace.bodyIncludeFiles", "required": false, "description": "Whether to include the message body of file based messages. The overhead is that the file content has to be read from the file.", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true, "secret": false }, { "name": "camel.trace.bodyIncludeStreams", "required": false, "description": "Whether to include the message body of stream based messages. If enabled then beware the stream may not be re-readable later. See more about Stream Caching.", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false }, 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 d56acdc2dde5..e44732e02de9 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 @@ -79,6 +79,24 @@ public interface BacklogTracer { */ void setBacklogSize(int backlogSize); + /** + * Number of completed exchange summaries to keep in the activity queue. Default is 100. + * <p> + * The activity queue captures a lightweight summary (metadata only, no body or headers) each time an exchange + * completes a route. This provides a rolling window of recent exchange activity suitable for live monitoring. + * + * @since 4.22 + */ + int getActivitySize(); + + /** + * Number of completed exchange summaries to keep in the activity queue (should be between 1 - 1000). Default is + * 100. + * + * @since 4.22 + */ + void setActivitySize(int activitySize); + /** * Remove the currently traced messages when dump methods are invoked */ @@ -237,6 +255,30 @@ public interface BacklogTracer { */ Collection<BacklogTracerEventMessage> getLatestMessageHistory(); + /** + * Get all activity summaries (without removing). + * <p> + * Activity summaries are lightweight snapshots captured when an exchange completes a route. They contain only + * metadata (exchange ID, route, elapsed time, status) — no message body or headers. + * + * @since 4.22 + */ + Collection<BacklogTracerEventMessage> getActivity(); + + /** + * Dumps all activity summaries. + * + * @since 4.22 + */ + List<BacklogTracerEventMessage> dumpActivity(); + + /** + * Dumps all activity summaries as JSon. + * + * @since 4.22 + */ + String dumpActivityAsJSon(); + /** * Dumps all tracing data */ 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 17ac2eb04972..ffa1f38ed1ed 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 @@ -66,6 +66,9 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp // use tracer to capture additional information for capturing latest completed exchange message-history private final Queue<BacklogTracerEventMessage> provisionalHistoryQueue = new LinkedBlockingQueue<>(MAX_BACKLOG_SIZE); private final Queue<BacklogTracerEventMessage> completeHistoryQueue = new LinkedBlockingQueue<>(MAX_BACKLOG_SIZE + 1); + // rolling window of completed exchange summaries for activity monitoring + private final Queue<BacklogTracerEventMessage> activityQueue = new LinkedBlockingQueue<>(MAX_BACKLOG_SIZE); + private int activitySize = 100; private volatile String lastCompletedBreadcrumbId; private boolean removeOnDump = true; private int bodyMaxChars = 32 * 1024; @@ -260,6 +263,13 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp completeHistoryQueue.add(event); } } + + // capture completed exchange summaries for activity monitoring + if (event.isLast()) { + drainActivity(); + activityQueue.offer(event); + } + if (!enabled) { return; } @@ -290,6 +300,15 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp } } + private void drainActivity() { + int drain = activityQueue.size() - activitySize + 1; + if (drain > 0) { + for (int i = 0; i < drain; i++) { + activityQueue.poll(); + } + } + } + private boolean shouldTraceFilter(Exchange exchange) { return predicate.matches(exchange); } @@ -331,6 +350,23 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp this.backlogSize = backlogSize; } + @Override + public int getActivitySize() { + return activitySize; + } + + @Override + public void setActivitySize(int activitySize) { + if (activitySize <= 0) { + throw new IllegalArgumentException("The activity size must be a positive number, was: " + activitySize); + } + if (activitySize > MAX_BACKLOG_SIZE) { + throw new IllegalArgumentException( + "The activity size cannot be greater than the max size of " + MAX_BACKLOG_SIZE + ", was: " + activitySize); + } + this.activitySize = activitySize; + } + @Override public boolean isRemoveOnDump() { return removeOnDump; @@ -478,6 +514,48 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp return Collections.unmodifiableCollection(completeHistoryQueue); } + @Override + public Collection<BacklogTracerEventMessage> getActivity() { + return Collections.unmodifiableCollection(activityQueue); + } + + @Override + public List<BacklogTracerEventMessage> dumpActivity() { + List<BacklogTracerEventMessage> answer = new ArrayList<>(activityQueue); + if (isRemoveOnDump()) { + activityQueue.clear(); + } + return answer; + } + + @Override + public String dumpActivityAsJSon() { + List<BacklogTracerEventMessage> events = dumpActivity(); + + JsonObject root = new JsonObject(); + JsonArray arr = new JsonArray(); + root.put("activity", arr); + for (BacklogTracerEventMessage event : events) { + JsonObject jo = new JsonObject(); + jo.put("exchangeId", event.getExchangeId()); + jo.put("routeId", event.getRouteId()); + jo.put("fromRouteId", event.getFromRouteId()); + if (event.getTimestamp() > 0) { + jo.put("timestamp", event.getTimestamp()); + } + jo.put("elapsed", event.getElapsed()); + jo.put("failed", event.isFailed()); + if (event.getEndpointUri() != null) { + jo.put("endpointUri", event.getEndpointUri()); + } + if (event.hasException()) { + jo.put("exception", event.getExceptionAsJSon()); + } + arr.add(jo); + } + return root.toJson(); + } + public List<BacklogTracerEventMessage> dumpTracedMessages(String nodeId) { List<BacklogTracerEventMessage> answer = new ArrayList<>(); if (nodeId != null) { @@ -585,6 +663,7 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp queue.clear(); completeHistoryQueue.clear(); provisionalHistoryQueue.clear(); + activityQueue.clear(); } @Override diff --git a/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/activity.json b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/activity.json new file mode 100644 index 000000000000..1c8f94954a0e --- /dev/null +++ b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/activity.json @@ -0,0 +1,15 @@ +{ + "console": { + "kind": "console", + "group": "camel", + "name": "activity", + "title": "Camel Activity", + "description": "Recent completed exchange activity", + "deprecated": false, + "javaType": "org.apache.camel.impl.console.ActivityDevConsole", + "groupId": "org.apache.camel", + "artifactId": "camel-console", + "version": "4.22.0-SNAPSHOT" + } +} + diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/activity b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/activity new file mode 100644 index 000000000000..fe3ec9d28204 --- /dev/null +++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/activity @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.impl.console.ActivityDevConsole diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties index 4f7ab2e10103..95209ff8cce9 100644 --- a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties +++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties @@ -1,5 +1,5 @@ # Generated by camel build tools - do NOT edit this file! -dev-consoles=bean blocked browse circuit-breaker consumer context datasource debug endpoint errors eval-language event gc health heap-histogram inflight internal-tasks java-security jfr-memory-leak jvm log memory message-history processor producer properties receive reload rest rest-spec route route-controller route-dump route-group route-structure route-topology send service simple-language source sql-query sql-trace startup-recorder system-properties thread top trace transformers type- [...] +dev-consoles=activity bean blocked browse circuit-breaker consumer context datasource debug endpoint errors eval-language event gc health heap-histogram inflight internal-tasks java-security jfr-memory-leak jvm log memory message-history processor producer properties receive reload rest rest-spec route route-controller route-dump route-group route-structure route-topology send service simple-language source sql-query sql-trace startup-recorder system-properties thread top trace transform [...] groupId=org.apache.camel artifactId=camel-console version=4.22.0-SNAPSHOT diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/ActivityDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/ActivityDevConsole.java new file mode 100644 index 000000000000..28fb5dbec054 --- /dev/null +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/ActivityDevConsole.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.impl.console; + +import java.util.Map; + +import org.apache.camel.spi.BacklogTracer; +import org.apache.camel.spi.BacklogTracerEventMessage; +import org.apache.camel.spi.annotations.DevConsole; +import org.apache.camel.support.console.AbstractDevConsole; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; + +@DevConsole(name = "activity", displayName = "Camel Activity", description = "Recent completed exchange activity") +public class ActivityDevConsole extends AbstractDevConsole { + + public ActivityDevConsole() { + super("camel", "activity", "Camel Activity", "Recent completed exchange activity"); + } + + @Override + protected String doCallText(Map<String, Object> options) { + StringBuilder sb = new StringBuilder(); + + BacklogTracer tracer = getCamelContext().getCamelContextExtension().getContextPlugin(BacklogTracer.class); + if (tracer != null) { + sb.append("Activity Size: ").append(tracer.getActivitySize()).append("\n"); + for (BacklogTracerEventMessage event : tracer.getActivity()) { + sb.append(String.format(" %s | %s | %s | %dms | %s%n", + event.getExchangeId(), + event.getRouteId(), + event.getEndpointUri() != null ? event.getEndpointUri() : "", + event.getElapsed(), + event.isFailed() ? "FAILED" : "OK")); + } + } + + return sb.toString(); + } + + @Override + protected JsonObject doCallJson(Map<String, Object> options) { + JsonObject root = new JsonObject(); + + BacklogTracer tracer = getCamelContext().getCamelContextExtension().getContextPlugin(BacklogTracer.class); + if (tracer != null) { + root.put("activitySize", tracer.getActivitySize()); + + JsonArray arr = new JsonArray(); + root.put("activity", arr); + for (BacklogTracerEventMessage event : tracer.dumpActivity()) { + JsonObject jo = new JsonObject(); + jo.put("uid", event.getUid()); + jo.put("exchangeId", event.getExchangeId()); + jo.put("routeId", event.getRouteId()); + if (event.getFromRouteId() != null) { + jo.put("fromRouteId", event.getFromRouteId()); + } + if (event.getTimestamp() > 0) { + jo.put("timestamp", event.getTimestamp()); + } + jo.put("elapsed", event.getElapsed()); + jo.put("failed", event.isFailed()); + if (event.getEndpointUri() != null) { + jo.put("endpointUri", event.getEndpointUri()); + } + if (event.isRemoteEndpoint()) { + jo.put("remoteEndpoint", true); + } + if (event.hasException()) { + jo.put("exception", event.getExceptionAsJSon()); + } + arr.add(jo); + } + } + + return root; + } + +} diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/TracerConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/TracerConfigurationPropertiesConfigurer.java index 2c7cf5cafed8..811931a0aad8 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/TracerConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/TracerConfigurationPropertiesConfigurer.java @@ -22,6 +22,7 @@ public class TracerConfigurationPropertiesConfigurer extends org.apache.camel.su private static final Map<String, Object> ALL_OPTIONS; static { Map<String, Object> map = new CaseInsensitiveMap(); + map.put("ActivitySize", int.class); map.put("BacklogSize", int.class); map.put("BodyIncludeFiles", boolean.class); map.put("BodyIncludeStreams", boolean.class); @@ -43,6 +44,8 @@ public class TracerConfigurationPropertiesConfigurer extends org.apache.camel.su public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { org.apache.camel.main.TracerConfigurationProperties target = (org.apache.camel.main.TracerConfigurationProperties) obj; switch (ignoreCase ? name.toLowerCase() : name) { + case "activitysize": + case "activitySize": target.setActivitySize(property(camelContext, int.class, value)); return true; case "backlogsize": case "backlogSize": target.setBacklogSize(property(camelContext, int.class, value)); return true; case "bodyincludefiles": @@ -81,6 +84,8 @@ public class TracerConfigurationPropertiesConfigurer extends org.apache.camel.su @Override public Class<?> getOptionType(String name, boolean ignoreCase) { switch (ignoreCase ? name.toLowerCase() : name) { + case "activitysize": + case "activitySize": return int.class; case "backlogsize": case "backlogSize": return int.class; case "bodyincludefiles": @@ -115,6 +120,8 @@ public class TracerConfigurationPropertiesConfigurer extends org.apache.camel.su public Object getOptionValue(Object obj, String name, boolean ignoreCase) { org.apache.camel.main.TracerConfigurationProperties target = (org.apache.camel.main.TracerConfigurationProperties) obj; switch (ignoreCase ? name.toLowerCase() : name) { + case "activitysize": + case "activitySize": return target.getActivitySize(); case "backlogsize": case "backlogSize": return target.getBacklogSize(); case "bodyincludefiles": 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 034183e3dda7..9c5e7a7718e5 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 @@ -483,6 +483,7 @@ { "name": "camel.threadpool.poolSize", "required": false, "description": "Sets the default core pool size (threads to keep minimum in pool)", "sourceType": "org.apache.camel.main.ThreadPoolConfigurationProperties", "type": "integer", "javaType": "java.lang.Integer", "secret": false }, { "name": "camel.threadpool.rejectedPolicy", "required": false, "description": "Sets the default handler for tasks which cannot be executed by the thread pool.", "sourceType": "org.apache.camel.main.ThreadPoolConfigurationProperties", "type": "enum", "javaType": "org.apache.camel.util.concurrent.ThreadPoolRejectedPolicy", "secret": false, "enum": [ "Abort", "CallerRuns", "DiscardOldest", "Discard" ] }, { "name": "camel.threadpool.timeUnit", "required": false, "description": "Sets the default time unit used for keep alive time", "sourceType": "org.apache.camel.main.ThreadPoolConfigurationProperties", "type": "object", "javaType": "java.util.concurrent.TimeUnit", "secret": false }, + { "name": "camel.trace.activitySize", "required": false, "description": "Defines how many completed exchange summaries to keep in the activity queue (should be between 1 - 1000). The activity queue captures lightweight metadata (no body or headers) each time an exchange completes a route, providing a rolling window of recent exchange activity.", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 100, "secret": false }, { "name": "camel.trace.backlogSize", "required": false, "description": "Defines how many of the last messages to keep in the tracer (should be between 1 - 1000).", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 100, "secret": false }, { "name": "camel.trace.bodyIncludeFiles", "required": false, "description": "Whether to include the message body of file based messages. The overhead is that the file content has to be read from the file.", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true, "secret": false }, { "name": "camel.trace.bodyIncludeStreams", "required": false, "description": "Whether to include the message body of stream based messages. If enabled then beware the stream may not be re-readable later. See more about Stream Caching.", "sourceType": "org.apache.camel.main.TracerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false }, diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index 20d29d34c351..f19111d9f174 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -282,11 +282,12 @@ The camel.debug supports 15 options, which are listed below. === Camel Tracer configurations -The camel.trace supports 14 options, which are listed below. +The camel.trace supports 15 options, which are listed below. [width="100%",cols="2,5,^1,2",options="header"] |=== | Name | Description | Default | Type +| *camel.trace.activitySize* | Defines how many completed exchange summaries to keep in the activity queue (should be between 1 - 1000). The activity queue captures lightweight metadata (no body or headers) each time an exchange completes a route, providing a rolling window of recent exchange activity. | 100 | int | *camel.trace.backlogSize* | Defines how many of the last messages to keep in the tracer (should be between 1 - 1000). | 100 | int | *camel.trace.bodyIncludeFiles* | Whether to include the message body of file based messages. The overhead is that the file content has to be read from the file. | true | boolean | *camel.trace.bodyIncludeStreams* | Whether to include the message body of stream based messages. If enabled then beware the stream may not be re-readable later. See more about Stream Caching. | 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 b933427bf2c7..26ce5b2e0bb7 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 @@ -2503,6 +2503,7 @@ public abstract class BaseMainSupport extends BaseService { tracer.setEnabled(config.isEnabled()); tracer.setStandby(config.isStandby()); tracer.setBacklogSize(config.getBacklogSize()); + tracer.setActivitySize(config.getActivitySize()); tracer.setRemoveOnDump(config.isRemoveOnDump()); tracer.setBodyMaxChars(config.getBodyMaxChars()); tracer.setBodyIncludeStreams(config.isBodyIncludeStreams()); diff --git a/core/camel-main/src/main/java/org/apache/camel/main/TracerConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/TracerConfigurationProperties.java index 753eb5f0f2c3..de5e6939c335 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/TracerConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/TracerConfigurationProperties.java @@ -34,6 +34,8 @@ public class TracerConfigurationProperties implements BootstrapCloseable { private boolean standby; @Metadata(label = "advanced", defaultValue = "100") private int backlogSize = 100; + @Metadata(label = "advanced", defaultValue = "100") + private int activitySize = 100; @Metadata(label = "advanced", defaultValue = "true") private boolean removeOnDump = true; @Metadata(label = "advanced", defaultValue = "32768") @@ -104,6 +106,19 @@ public class TracerConfigurationProperties implements BootstrapCloseable { this.backlogSize = backlogSize; } + public int getActivitySize() { + return activitySize; + } + + /** + * Defines how many completed exchange summaries to keep in the activity queue (should be between 1 - 1000). The + * activity queue captures lightweight metadata (no body or headers) each time an exchange completes a route, + * providing a rolling window of recent exchange activity. + */ + public void setActivitySize(int activitySize) { + this.activitySize = activitySize; + } + public boolean isRemoveOnDump() { return removeOnDump; } @@ -253,6 +268,14 @@ public class TracerConfigurationProperties implements BootstrapCloseable { return this; } + /** + * Defines how many completed exchange summaries to keep in the activity queue (should be between 1 - 1000). + */ + public TracerConfigurationProperties withActivitySize(int activitySize) { + this.activitySize = activitySize; + return this; + } + /** * Whether all traced messages should be removed when the tracer is dumping. By default, the messages are removed, * which means that dumping will not contain previous dumped messages. 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 d254c9a27c6f..2e63926b8bd7 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 @@ -45,6 +45,12 @@ public interface ManagedBacklogTracerMBean { @ManagedAttribute(description = "Number of maximum traced messages in total to keep in the backlog (FIFO queue)") void setBacklogSize(int backlogSize); + @ManagedAttribute(description = "Number of completed exchange summaries to keep in the activity queue") + int getActivitySize(); + + @ManagedAttribute(description = "Number of completed exchange summaries to keep in the activity queue") + void setActivitySize(int activitySize); + @ManagedAttribute(description = "Whether to remove traced message from backlog when dumping trace messages") boolean isRemoveOnDump(); @@ -135,6 +141,9 @@ public interface ManagedBacklogTracerMBean { @ManagedOperation(description = "Dumps latest completed exchange message history in JSon format") String dumpLatestMessageHistoryAsJSon(); + @ManagedOperation(description = "Dumps completed exchange activity summaries in JSon format") + String dumpActivityAsJSon(); + @ManagedOperation(description = "Clears the backlog") void clear(); 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 098d954ec52c..bd449b0d4134 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 @@ -86,6 +86,16 @@ public class ManagedBacklogTracer implements ManagedBacklogTracerMBean { backlogTracer.setBacklogSize(backlogSize); } + @Override + public int getActivitySize() { + return backlogTracer.getActivitySize(); + } + + @Override + public void setActivitySize(int activitySize) { + backlogTracer.setActivitySize(activitySize); + } + @Override public boolean isRemoveOnDump() { return backlogTracer.isRemoveOnDump(); @@ -236,6 +246,11 @@ public class ManagedBacklogTracer implements ManagedBacklogTracerMBean { return backlogTracer.dumpLatestMessageHistoryAsJSon(); } + @Override + public String dumpActivityAsJSon() { + return backlogTracer.dumpActivityAsJSon(); + } + @Override public void clear() { backlogTracer.clear();
