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 2023/10/05 16:57:02 UTC

[camel] 01/03: CAMEL-15625: Add startup recorder dev console and be able to capture these.

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

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

commit 949bee2c079cbe80b2252264fa70bcd933ca4c77
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 5 18:28:53 2023 +0200

    CAMEL-15625: Add startup recorder dev console and be able to capture these.
---
 .../main/java/org/apache/camel/StartupStep.java    |  5 ++
 .../org/apache/camel/spi/StartupStepRecorder.java  |  9 +++
 .../org/apache/camel/dev-console/startup-recorder  |  2 +
 .../impl/console/StartupRecorderDevConsole.java    | 89 ++++++++++++++++++++++
 .../camel-main-configuration-metadata.json         |  2 +-
 core/camel-main/src/main/docs/main.adoc            |  2 +-
 .../org/apache/camel/main/BaseMainSupport.java     |  3 +
 .../camel/main/DefaultConfigurationConfigurer.java |  5 ++
 .../camel/main/DefaultConfigurationProperties.java |  6 +-
 ...corder.java => BacklogStartupStepRecorder.java} | 37 +++++----
 .../camel/support/startup/DefaultStartupStep.java  |  8 +-
 .../startup/DefaultStartupStepRecorder.java        |  5 ++
 .../startup/LoggingStartupStepRecorder.java        | 17 +++--
 .../java/org/apache/camel/main/KameletMain.java    |  1 +
 14 files changed, 163 insertions(+), 28 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/StartupStep.java b/core/camel-api/src/main/java/org/apache/camel/StartupStep.java
index 6da0ac511e3..4f48bdfb6f0 100644
--- a/core/camel-api/src/main/java/org/apache/camel/StartupStep.java
+++ b/core/camel-api/src/main/java/org/apache/camel/StartupStep.java
@@ -62,4 +62,9 @@ public interface StartupStep {
      */
     long getBeginTime();
 
+    /**
+     * Gets the duration the step took (optional)
+     */
+    long getDuration();
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/StartupStepRecorder.java b/core/camel-api/src/main/java/org/apache/camel/spi/StartupStepRecorder.java
index 634dd14af82..0600f494c09 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/StartupStepRecorder.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/StartupStepRecorder.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.spi;
 
+import java.util.stream.Stream;
+
 import org.apache.camel.StartupStep;
 import org.apache.camel.StaticService;
 
@@ -108,4 +110,11 @@ public interface StartupStepRecorder extends StaticService {
      */
     void endStep(StartupStep step);
 
+    /**
+     * Some records will capture all steps which can be accessed on demand.
+     */
+    default Stream<StartupStep> steps() {
+        return Stream.empty();
+    }
+
 }
diff --git a/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/startup-recorder b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/startup-recorder
new file mode 100644
index 00000000000..6a38b3c5ed7
--- /dev/null
+++ b/core/camel-console/src/generated/resources/META-INF/services/org/apache/camel/dev-console/startup-recorder
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.impl.console.StartupRecorderDevConsole
diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/StartupRecorderDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/StartupRecorderDevConsole.java
new file mode 100644
index 00000000000..0f527caa2f5
--- /dev/null
+++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/StartupRecorderDevConsole.java
@@ -0,0 +1,89 @@
+/*
+ * 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.ExtendedCamelContext;
+import org.apache.camel.StartupStep;
+import org.apache.camel.spi.StartupStepRecorder;
+import org.apache.camel.spi.annotations.DevConsole;
+import org.apache.camel.support.console.AbstractDevConsole;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+
+@DevConsole("startup-recorder")
+public class StartupRecorderDevConsole extends AbstractDevConsole {
+
+    public StartupRecorderDevConsole() {
+        super("camel", "startup-recorder", "Startup Recorder", "Display startup recording");
+    }
+
+    @Override
+    protected String doCallText(Map<String, Object> options) {
+        StringBuilder sb = new StringBuilder();
+
+        ExtendedCamelContext ecc = getCamelContext().getCamelContextExtension();
+        StartupStepRecorder recorder = ecc.getStartupStepRecorder();
+        if (recorder != null) {
+            recorder.steps().forEach(s -> {
+                sb.append(logStep(s)).append("\n");
+            });
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    protected Map<String, Object> doCallJson(Map<String, Object> options) {
+        JsonObject root = new JsonObject();
+        JsonArray arr = new JsonArray();
+
+        ExtendedCamelContext ecc = getCamelContext().getCamelContextExtension();
+        StartupStepRecorder recorder = ecc.getStartupStepRecorder();
+        if (recorder != null) {
+            recorder.steps().forEach(s -> {
+                JsonObject jo = new JsonObject();
+                jo.put("id", s.getId());
+                jo.put("parentId", s.getParentId());
+                jo.put("level", s.getLevel());
+                jo.put("name", s.getName());
+                jo.put("type", s.getType());
+                jo.put("description", s.getDescription());
+                jo.put("beginTime", s.getBeginTime());
+                jo.put("duration", s.getDuration());
+                arr.add(jo);
+            });
+        }
+
+        if (!arr.isEmpty()) {
+            root.put("steps", arr);
+        }
+        return root;
+    }
+
+    protected String logStep(StartupStep step) {
+        long delta = step.getDuration();
+        String pad = StringHelper.padString(step.getLevel());
+        String out = String.format("%s", pad + step.getType());
+        String out2 = String.format("%6s ms", delta);
+        String out3 = String.format("%s(%s)", step.getDescription(), step.getName());
+        return String.format("%s : %s - %s", out2, out, out3);
+    }
+
+}
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 237e996e769..de05f6d7933 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
@@ -109,7 +109,7 @@
     { "name": "camel.main.shutdownSuppressLoggingOnTimeout", "description": "Whether Camel should try to suppress logging during shutdown and timeout was triggered, meaning forced shutdown is happening. And during forced shutdown we want to avoid logging errors\/warnings et all in the logs as a side-effect of the forced timeout. Notice the suppress is a best effort as there may still be some logs coming from 3rd party libraries and whatnot, which Camel cannot control. This option is defa [...]
     { "name": "camel.main.shutdownTimeout", "description": "Timeout in seconds to graceful shutdown all the Camel routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 45 },
     { "name": "camel.main.sourceLocationEnabled", "description": "Whether to capture precise source location:line-number for all EIPs in Camel routes. Enabling this will impact parsing Java based routes (also Groovy, Kotlin, etc.) on startup as this uses JDK StackTraceElement to calculate the location from the Camel route, which comes with a performance cost. This only impact startup, not the performance of the routes at runtime.", "sourceType": "org.apache.camel.main.DefaultConfiguratio [...]
-    { "name": "camel.main.startupRecorder", "description": "To use startup recorder for capturing execution time during starting Camel. The recorder can be one of: false (or off), logging, java-flight-recorder (or jfr).", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "enum": [ "false", "off", "java-flight-recorder", "jfr", "logging" ] },
+    { "name": "camel.main.startupRecorder", "description": "To use startup recorder for capturing execution time during starting Camel. The recorder can be one of: false (or off), logging, backlog, java-flight-recorder (or jfr).", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "enum": [ "false", "off", "java-flight-recorder", "jfr", "logging", "backlog" ] },
     { "name": "camel.main.startupRecorderDir", "description": "Directory to store the recording. By default the current directory will be used. Use false to turn off saving recording to disk.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.main.startupRecorderDuration", "description": "How long time to run the startup recorder. Use 0 (default) to keep the recorder running until the JVM is exited. Use -1 to stop the recorder right after Camel has been started (to only focus on potential Camel startup performance bottlenecks) Use a positive value to keep recording for N seconds. When the recorder is stopped then the recording is auto saved to disk (note: save to disk can be disabled by setting startupRec [...]
     { "name": "camel.main.startupRecorderMaxDepth", "description": "To filter our sub steps at a maximum depth. Use -1 for no maximum. Use 0 for no sub steps. Use 1 for max 1 sub step, and so forth. The default is -1.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": -1 },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index aefdf771bcb..cedb4a2b522 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -120,7 +120,7 @@ The camel.main supports 127 options, which are listed below.
 | *camel.main.shutdownSuppress{zwsp}LoggingOnTimeout* | Whether Camel should try to suppress logging during shutdown and timeout was triggered, meaning forced shutdown is happening. And during forced shutdown we want to avoid logging errors/warnings et all in the logs as a side-effect of the forced timeout. Notice the suppress is a best effort as there may still be some logs coming from 3rd party libraries and whatnot, which Camel cannot control. This option is default false. | false | boolean
 | *camel.main.shutdownTimeout* | Timeout in seconds to graceful shutdown all the Camel routes. | 45 | int
 | *camel.main.sourceLocation{zwsp}Enabled* | Whether to capture precise source location:line-number for all EIPs in Camel routes. Enabling this will impact parsing Java based routes (also Groovy, Kotlin, etc.) on startup as this uses JDK StackTraceElement to calculate the location from the Camel route, which comes with a performance cost. This only impact startup, not the performance of the routes at runtime. | false | boolean
-| *camel.main.startupRecorder* | To use startup recorder for capturing execution time during starting Camel. The recorder can be one of: false (or off), logging, java-flight-recorder (or jfr). |  | String
+| *camel.main.startupRecorder* | To use startup recorder for capturing execution time during starting Camel. The recorder can be one of: false (or off), logging, backlog, java-flight-recorder (or jfr). |  | String
 | *camel.main.startupRecorderDir* | Directory to store the recording. By default the current directory will be used. Use false to turn off saving recording to disk. |  | String
 | *camel.main.startupRecorder{zwsp}Duration* | How long time to run the startup recorder. Use 0 (default) to keep the recorder running until the JVM is exited. Use -1 to stop the recorder right after Camel has been started (to only focus on potential Camel startup performance bottlenecks) Use a positive value to keep recording for N seconds. When the recorder is stopped then the recording is auto saved to disk (note: save to disk can be disabled by setting startupRecorderDir to false) |  | long
 | *camel.main.startupRecorderMax{zwsp}Depth* | To filter our sub steps at a maximum depth. Use -1 for no maximum. Use 0 for no sub steps. Use 1 for max 1 sub step, and so forth. The default is -1. | -1 | int
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 b2906c2bda9..b529a16f91f 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
@@ -74,6 +74,7 @@ import org.apache.camel.support.ResourceHelper;
 import org.apache.camel.support.SimpleEventNotifierSupport;
 import org.apache.camel.support.scan.PackageScanHelper;
 import org.apache.camel.support.service.BaseService;
+import org.apache.camel.support.startup.BacklogStartupStepRecorder;
 import org.apache.camel.support.startup.LoggingStartupStepRecorder;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.ObjectHelper;
@@ -518,6 +519,8 @@ public abstract class BaseMainSupport extends BaseService {
             camelContext.getCamelContextExtension().getStartupStepRecorder().setEnabled(false);
         } else if ("logging".equals(mainConfigurationProperties.getStartupRecorder())) {
             camelContext.getCamelContextExtension().setStartupStepRecorder(new LoggingStartupStepRecorder());
+        } else if ("backlog".equals(mainConfigurationProperties.getStartupRecorder())) {
+            camelContext.getCamelContextExtension().setStartupStepRecorder(new BacklogStartupStepRecorder());
         } else if ("jfr".equals(mainConfigurationProperties.getStartupRecorder())
                 || "java-flight-recorder".equals(mainConfigurationProperties.getStartupRecorder())
                 || mainConfigurationProperties.getStartupRecorder() == null) {
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 7b9ebde1703..e66b6a0abf4 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -89,6 +89,7 @@ import org.apache.camel.support.RouteWatcherReloadStrategy;
 import org.apache.camel.support.ShortUuidGenerator;
 import org.apache.camel.support.SimpleUuidGenerator;
 import org.apache.camel.support.jsse.GlobalSSLContextParametersSupplier;
+import org.apache.camel.support.startup.BacklogStartupStepRecorder;
 import org.apache.camel.support.startup.LoggingStartupStepRecorder;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.TimeUtils;
@@ -127,6 +128,10 @@ public final class DefaultConfigurationConfigurer {
                 if (!(ecc.getStartupStepRecorder() instanceof LoggingStartupStepRecorder)) {
                     ecc.setStartupStepRecorder(new LoggingStartupStepRecorder());
                 }
+            } else if ("backlog".equals(config.getStartupRecorder())) {
+                if (!(ecc.getStartupStepRecorder() instanceof BacklogStartupStepRecorder)) {
+                    ecc.setStartupStepRecorder(new BacklogStartupStepRecorder());
+                }
             } else if ("java-flight-recorder".equals(config.getStartupRecorder())) {
                 if (!ecc.getStartupStepRecorder().getClass().getName().startsWith("org.apache.camel.startup.jfr")) {
                     throw new IllegalArgumentException(
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 83af6a7d6e1..0f50e038203 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -152,7 +152,7 @@ public abstract class DefaultConfigurationProperties<T> {
     private double routeControllerBackOffMultiplier;
     private boolean routeControllerUnhealthyOnExhausted;
     // startup recorder
-    @Metadata(enums = "false,off,java-flight-recorder,jfr,logging")
+    @Metadata(enums = "false,off,java-flight-recorder,jfr,logging,backlog")
     private String startupRecorder;
     private int startupRecorderMaxDepth = -1;
     private boolean startupRecorderRecording;
@@ -1661,7 +1661,7 @@ public abstract class DefaultConfigurationProperties<T> {
 
     /**
      * To use startup recorder for capturing execution time during starting Camel. The recorder can be one of: false (or
-     * off), logging, java-flight-recorder (or jfr).
+     * off), logging, backlog, java-flight-recorder (or jfr).
      */
     public void setStartupRecorder(String startupRecorder) {
         this.startupRecorder = startupRecorder;
@@ -2883,7 +2883,7 @@ public abstract class DefaultConfigurationProperties<T> {
 
     /**
      * To use startup recorder for capturing execution time during starting Camel. The recorder can be one of: false (or
-     * off), logging, java-flight-recorder (or jfr).
+     * off), logging, backlog, java-flight-recorder (or jfr).
      *
      * The default is false.
      */
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/startup/LoggingStartupStepRecorder.java b/core/camel-support/src/main/java/org/apache/camel/support/startup/BacklogStartupStepRecorder.java
similarity index 55%
copy from core/camel-support/src/main/java/org/apache/camel/support/startup/LoggingStartupStepRecorder.java
copy to core/camel-support/src/main/java/org/apache/camel/support/startup/BacklogStartupStepRecorder.java
index 6febde386e5..4ff2412136b 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/startup/LoggingStartupStepRecorder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/startup/BacklogStartupStepRecorder.java
@@ -16,36 +16,41 @@
  */
 package org.apache.camel.support.startup;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
 import org.apache.camel.StartupStep;
-import org.apache.camel.util.StringHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
- * Logging {@link org.apache.camel.spi.StartupStepRecorder} that outputs to log.
+ * {@link org.apache.camel.spi.StartupStepRecorder} that captures each step event.
  */
-public class LoggingStartupStepRecorder extends DefaultStartupStepRecorder {
+public class BacklogStartupStepRecorder extends DefaultStartupStepRecorder {
 
-    private static final Logger LOG = LoggerFactory.getLogger(LoggingStartupStepRecorder.class);
+    private final List<StartupStep> steps = new ArrayList<>();
 
-    public LoggingStartupStepRecorder() {
+    public BacklogStartupStepRecorder() {
         setEnabled(true);
     }
 
     @Override
     protected void onEndStep(StartupStep step) {
-        if (LOG.isInfoEnabled()) {
-            long delta = System.currentTimeMillis() - step.getBeginTime();
-            String pad = StringHelper.padString(step.getLevel());
-            String out = String.format("%s", pad + step.getType());
-            String out2 = String.format("%6s ms", delta);
-            String out3 = String.format("%s(%s)", step.getDescription(), step.getName());
-            LOG.info("{} : {} - {}", out2, out, out3);
-        }
+        steps.add(step);
+    }
+
+    @Override
+    public Stream<StartupStep> steps() {
+        return steps.stream();
+    }
+
+    @Override
+    public void doStop() throws Exception {
+        super.doStop();
+        steps.clear();
     }
 
     @Override
     public String toString() {
-        return "logging";
+        return "backlog";
     }
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStep.java b/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStep.java
index 1c0a6eae989..f601fb878bc 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStep.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStep.java
@@ -27,6 +27,7 @@ public class DefaultStartupStep implements StartupStep {
     private final int parentId;
     private final int level;
     private final long time;
+    private long duration;
 
     public DefaultStartupStep(String type, String name, String description, int id, int parentId, int level, long time) {
         this.type = type;
@@ -73,9 +74,14 @@ public class DefaultStartupStep implements StartupStep {
         return time;
     }
 
+    @Override
+    public long getDuration() {
+        return duration;
+    }
+
     @Override
     public void endStep() {
-        // noop
+        this.duration = System.currentTimeMillis() - time;
     }
 
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStepRecorder.java b/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStepRecorder.java
index ee210766f0f..7b7f38ac279 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStepRecorder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/startup/DefaultStartupStepRecorder.java
@@ -65,6 +65,11 @@ public class DefaultStartupStepRecorder extends ServiceSupport implements Startu
             return 0;
         }
 
+        @Override
+        public long getDuration() {
+            return 0;
+        }
+
         @Override
         public void endStep() {
             // noop
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/startup/LoggingStartupStepRecorder.java b/core/camel-support/src/main/java/org/apache/camel/support/startup/LoggingStartupStepRecorder.java
index 6febde386e5..bed3f27691a 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/startup/LoggingStartupStepRecorder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/startup/LoggingStartupStepRecorder.java
@@ -35,15 +35,20 @@ public class LoggingStartupStepRecorder extends DefaultStartupStepRecorder {
     @Override
     protected void onEndStep(StartupStep step) {
         if (LOG.isInfoEnabled()) {
-            long delta = System.currentTimeMillis() - step.getBeginTime();
-            String pad = StringHelper.padString(step.getLevel());
-            String out = String.format("%s", pad + step.getType());
-            String out2 = String.format("%6s ms", delta);
-            String out3 = String.format("%s(%s)", step.getDescription(), step.getName());
-            LOG.info("{} : {} - {}", out2, out, out3);
+            String msg = logStep(step);
+            LOG.info(msg);
         }
     }
 
+    protected String logStep(StartupStep step) {
+        long delta = step.getDuration();
+        String pad = StringHelper.padString(step.getLevel());
+        String out = String.format("%s", pad + step.getType());
+        String out2 = String.format("%6s ms", delta);
+        String out3 = String.format("%s(%s)", step.getDescription(), step.getName());
+        return String.format("%s : %s - %s", out2, out, out3);
+    }
+
     @Override
     public String toString() {
         return "logging";
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index dea6dedee95..6bdbf41ceab 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -444,6 +444,7 @@ public class KameletMain extends MainCommandLineSupport {
         configure().withJmxManagementStatisticsLevel(ManagementStatisticsLevel.Extended);
         configure().withShutdownLogInflightExchangesOnTimeout(false);
         configure().withShutdownTimeout(10);
+        configure().withStartupRecorder("backlog");
 
         boolean tracing = "true".equals(getInitialProperties().get("camel.jbang.backlogTracing"));
         if (tracing) {