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 <claus.ib...@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) {

Reply via email to