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 2022/01/04 15:43:21 UTC

[camel] branch main updated: CAMEL-17420: camel-core - Add flag to turn on|off source loc:line

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


The following commit(s) were added to refs/heads/main by this push:
     new 14709dc  CAMEL-17420: camel-core - Add flag to turn on|off source loc:line
14709dc is described below

commit 14709dcf54bcbf379059ccb077af929d2e518ef1
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 4 16:42:23 2022 +0100

    CAMEL-17420: camel-core - Add flag to turn on|off source loc:line
---
 .../camel/impl/debugger/CamelDebuggerFactory.java  |  2 ++
 .../main/java/org/apache/camel/CamelContext.java   | 18 +++++++++++
 .../camel/impl/engine/AbstractCamelContext.java    | 11 +++++++
 .../camel/impl/ExtendedCamelContextConfigurer.java |  6 ++++
 .../camel/impl/lw/LightweightCamelContext.java     | 10 ++++++
 .../impl/lw/LightweightRuntimeCamelContext.java    | 10 ++++++
 .../apache/camel/model/ProcessorDefinition.java    |  3 +-
 .../org/apache/camel/model/RouteDefinition.java    |  5 ++-
 ....java => LineNumberProcessorDebuggingTest.java} | 37 ++++++++++------------
 .../camel/processor/LineNumberProcessorTest.java   |  2 +-
 ...st.java => LineNumberProcessorTracingTest.java} | 36 ++++++++++-----------
 .../MainConfigurationPropertiesConfigurer.java     |  6 ++++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 +-
 .../camel/main/DefaultConfigurationConfigurer.java |  3 ++
 .../camel/main/DefaultConfigurationProperties.java | 28 ++++++++++++++++
 16 files changed, 133 insertions(+), 48 deletions(-)

diff --git a/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java b/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java
index 5bd2f54..b2ea55d 100644
--- a/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java
+++ b/components/camel-debug/src/main/java/org/apache/camel/impl/debugger/CamelDebuggerFactory.java
@@ -30,6 +30,8 @@ public class CamelDebuggerFactory implements DebuggerFactory {
     public Debugger createDebugger(CamelContext camelContext) throws Exception {
         // must enable message history for debugger to capture more details
         camelContext.setMessageHistory(true);
+        // must enable source location so debugger tooling knows to map breakpoints to source code
+        camelContext.setSourceLocationEnabled(true);
 
         BacklogDebugger backlog = BacklogDebugger.createDebugger(camelContext);
         // we need to enable debugger after context is started
diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
index 74138f6..749a16a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
@@ -1187,6 +1187,24 @@ public interface CamelContext extends CamelContextLifecycle, RuntimeConfiguratio
     void setLoadHealthChecks(Boolean loadHealthChecks);
 
     /**
+     * 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
+     * {@link 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.
+     */
+    Boolean isSourceLocationEnabled();
+
+    /**
+     * 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
+     * {@link 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.
+     */
+    void setSourceLocationEnabled(Boolean sourceLocationEnabled);
+
+    /**
      * Whether or not type converter statistics is enabled.
      * <p/>
      * By default the type converter utilization statistics is disabled. <b>Notice:</b> If enabled then there is a
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index de9eea0..30e7215 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -261,6 +261,7 @@ public abstract class AbstractCamelContext extends BaseService
     private Boolean disableJMX = Boolean.FALSE;
     private Boolean loadTypeConverters = Boolean.FALSE;
     private Boolean loadHealthChecks = Boolean.FALSE;
+    private Boolean sourceLocationEnabled = Boolean.FALSE;
     private Boolean typeConverterStatisticsEnabled = Boolean.FALSE;
     private Boolean dumpRoutes = Boolean.FALSE;
     private Boolean useMDCLogging = Boolean.FALSE;
@@ -4208,6 +4209,16 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     @Override
+    public Boolean isSourceLocationEnabled() {
+        return sourceLocationEnabled;
+    }
+
+    @Override
+    public void setSourceLocationEnabled(Boolean sourceLocationEnabled) {
+        this.sourceLocationEnabled = sourceLocationEnabled;
+    }
+
+    @Override
     public void setTypeConverterStatisticsEnabled(Boolean typeConverterStatisticsEnabled) {
         this.typeConverterStatisticsEnabled = typeConverterStatisticsEnabled;
     }
diff --git a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
index 54bc4a1..a6e90dd 100644
--- a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
+++ b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
@@ -163,6 +163,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "ShutdownRunningTask": target.setShutdownRunningTask(property(camelContext, org.apache.camel.ShutdownRunningTask.class, value)); return true;
         case "shutdownstrategy":
         case "ShutdownStrategy": target.setShutdownStrategy(property(camelContext, org.apache.camel.spi.ShutdownStrategy.class, value)); return true;
+        case "sourcelocationenabled":
+        case "SourceLocationEnabled": target.setSourceLocationEnabled(property(camelContext, java.lang.Boolean.class, value)); return true;
         case "startupsteprecorder":
         case "StartupStepRecorder": target.setStartupStepRecorder(property(camelContext, org.apache.camel.spi.StartupStepRecorder.class, value)); return true;
         case "startupsummarylevel":
@@ -346,6 +348,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "ShutdownRunningTask": return org.apache.camel.ShutdownRunningTask.class;
         case "shutdownstrategy":
         case "ShutdownStrategy": return org.apache.camel.spi.ShutdownStrategy.class;
+        case "sourcelocationenabled":
+        case "SourceLocationEnabled": return java.lang.Boolean.class;
         case "startupsteprecorder":
         case "StartupStepRecorder": return org.apache.camel.spi.StartupStepRecorder.class;
         case "startupsummarylevel":
@@ -530,6 +534,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "ShutdownRunningTask": return target.getShutdownRunningTask();
         case "shutdownstrategy":
         case "ShutdownStrategy": return target.getShutdownStrategy();
+        case "sourcelocationenabled":
+        case "SourceLocationEnabled": return target.isSourceLocationEnabled();
         case "startupsteprecorder":
         case "StartupStepRecorder": return target.getStartupStepRecorder();
         case "startupsummarylevel":
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
index 8fc20d9..7d61d65 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
@@ -900,6 +900,16 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam
     }
 
     @Override
+    public Boolean isSourceLocationEnabled() {
+        return delegate.isSourceLocationEnabled();
+    }
+
+    @Override
+    public void setSourceLocationEnabled(Boolean sourceLocationEnabled) {
+        delegate.setSourceLocationEnabled(sourceLocationEnabled);
+    }
+
+    @Override
     public Boolean isDumpRoutes() {
         return delegate.isDumpRoutes();
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
index 55d7836..04726e4 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
@@ -1193,6 +1193,16 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
     }
 
     @Override
+    public Boolean isSourceLocationEnabled() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setSourceLocationEnabled(Boolean sourceLocationEnabled) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public Boolean isTypeConverterStatisticsEnabled() {
         throw new UnsupportedOperationException();
     }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index cfcc6d7..4822689 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -177,9 +177,8 @@ public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>
                 }
             }
         }
-        if (context != null && (context.isDebugging() || context.isTracing())) {
+        if (context != null && (context.isSourceLocationEnabled() || context.isDebugging() || context.isTracing())) {
             // we want to capture source location:line for every output
-            // (this is an expensive operation, so only do this if debugging or tracing is enabled)
             ProcessorDefinitionHelper.prepareSourceLocation(output);
             if (log.isDebugEnabled()) {
                 log.debug("{} located in {}:{}", output.getShortName(), output.getLocation(),
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
index 1fabdf4..adfb691 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
@@ -733,10 +733,9 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> implement
         // does not have a <from> as it is implied to be the rest endpoint
         this.input = input;
 
-        if (getCamelContext() != null
-                && (getCamelContext().isDebugging() || getCamelContext().isTracing())) {
+        if (getCamelContext() != null && (getCamelContext().isSourceLocationEnabled() || getCamelContext().isDebugging()
+                || getCamelContext().isTracing())) {
             // we want to capture source location:line for every output
-            // (this is an expensive operation, so only do this if debugging or tracing is enabled)
             ProcessorDefinitionHelper.prepareSourceLocation(input);
             if (log.isDebugEnabled()) {
                 log.debug("{} located in {}:{}", input.getShortName(), input.getLocation(),
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorDebuggingTest.java
similarity index 71%
copy from core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java
copy to core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorDebuggingTest.java
index 3713b68..53dc719 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorDebuggingTest.java
@@ -17,41 +17,36 @@
 package org.apache.camel.processor;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.LineNumberAware;
 import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class LineNumberProcessorTest extends ContextTestSupport {
-
-    @Override
-    protected CamelContext createCamelContext() throws Exception {
-        CamelContext context = super.createCamelContext();
-        context.setTracing(true); // enables line numbering
-        return context;
-    }
+public class LineNumberProcessorDebuggingTest {
 
     @Test
     public void testLineNumber() throws Exception {
-        getMockEndpoint("mock:result").expectedBodiesReceived("org.apache.camel.processor.LineNumberProcessorTest$1:51");
-
-        template.sendBody("direct:start", "Hello World");
-
-        assertMockEndpointsSatisfied();
-    }
+        CamelContext context = new DefaultCamelContext();
+        context.setDebugging(true);
 
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
+        context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
                 from("direct:start")
-                        .process(new MyProcessor())
-                        .to("mock:result");
+                        .process(new MyProcessor());
             }
-        };
+        });
+
+        context.start();
+
+        ProducerTemplate template = context.createProducerTemplate();
+
+        Object out = template.requestBody("direct:start", "Hello World");
+        Assertions.assertEquals("org.apache.camel.processor.LineNumberProcessorDebuggingTest$1:40", out);
     }
 
     private static class MyProcessor implements Processor, LineNumberAware {
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java
index 3713b68..268ddc5 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java
@@ -29,7 +29,7 @@ public class LineNumberProcessorTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.setTracing(true); // enables line numbering
+        context.setSourceLocationEnabled(true);
         return context;
     }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTracingTest.java
similarity index 73%
copy from core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java
copy to core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTracingTest.java
index 3713b68..a3422ea 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/LineNumberProcessorTracingTest.java
@@ -21,37 +21,33 @@ import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.LineNumberAware;
 import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class LineNumberProcessorTest extends ContextTestSupport {
-
-    @Override
-    protected CamelContext createCamelContext() throws Exception {
-        CamelContext context = super.createCamelContext();
-        context.setTracing(true); // enables line numbering
-        return context;
-    }
+public class LineNumberProcessorTracingTest extends ContextTestSupport {
 
     @Test
     public void testLineNumber() throws Exception {
-        getMockEndpoint("mock:result").expectedBodiesReceived("org.apache.camel.processor.LineNumberProcessorTest$1:51");
-
-        template.sendBody("direct:start", "Hello World");
-
-        assertMockEndpointsSatisfied();
-    }
+        CamelContext context = new DefaultCamelContext();
+        context.setTracing(true);
 
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
+        context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
                 from("direct:start")
-                        .process(new MyProcessor())
-                        .to("mock:result");
+                        .process(new LineNumberProcessorTracingTest.MyProcessor());
             }
-        };
+        });
+
+        context.start();
+
+        ProducerTemplate template = context.createProducerTemplate();
+
+        Object out = template.requestBody("direct:start", "Hello World");
+        Assertions.assertEquals("org.apache.camel.processor.LineNumberProcessorTracingTest$1:41", out);
     }
 
     private static class MyProcessor implements Processor, LineNumberAware {
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index 4025964..76e1a7c 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -179,6 +179,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "ShutdownSuppressLoggingOnTimeout": target.setShutdownSuppressLoggingOnTimeout(property(camelContext, boolean.class, value)); return true;
         case "shutdowntimeout":
         case "ShutdownTimeout": target.setShutdownTimeout(property(camelContext, int.class, value)); return true;
+        case "sourcelocationenabled":
+        case "SourceLocationEnabled": target.setSourceLocationEnabled(property(camelContext, boolean.class, value)); return true;
         case "startuprecorder":
         case "StartupRecorder": target.setStartupRecorder(property(camelContext, java.lang.String.class, value)); return true;
         case "startuprecorderdir":
@@ -394,6 +396,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "ShutdownSuppressLoggingOnTimeout": return boolean.class;
         case "shutdowntimeout":
         case "ShutdownTimeout": return int.class;
+        case "sourcelocationenabled":
+        case "SourceLocationEnabled": return boolean.class;
         case "startuprecorder":
         case "StartupRecorder": return java.lang.String.class;
         case "startuprecorderdir":
@@ -610,6 +614,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "ShutdownSuppressLoggingOnTimeout": return target.isShutdownSuppressLoggingOnTimeout();
         case "shutdowntimeout":
         case "ShutdownTimeout": return target.getShutdownTimeout();
+        case "sourcelocationenabled":
+        case "SourceLocationEnabled": return target.isSourceLocationEnabled();
         case "startuprecorder":
         case "StartupRecorder": return target.getStartupRecorder();
         case "startuprecorderdir":
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 6cdd85c..668fe14 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
@@ -89,6 +89,7 @@
     { "name": "camel.main.shutdownRoutesInReverseOrder", "description": "Sets whether routes should be shutdown in reverse or the same order as they were started.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "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 Camel.", "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.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 [...]
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index f9df45a..5d8124f 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -21,7 +21,7 @@ The following tables lists all the options:
 
 // main options: START
 === Camel Main configurations
-The camel.main supports 104 options, which are listed below.
+The camel.main supports 105 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -105,6 +105,7 @@ The camel.main supports 104 options, which are listed below.
 | *camel.main.shutdownRoutesIn{zwsp}ReverseOrder* | Sets whether routes should be shutdown in reverse or the same order as they were started. | true | boolean
 | *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 Camel. | 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.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
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 2476d46..1933e4c 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
@@ -266,6 +266,9 @@ public final class DefaultConfigurationConfigurer {
         if (config.isMessageHistory()) {
             camelContext.setMessageHistory(true);
         }
+        if (config.isSourceLocationEnabled()) {
+            camelContext.setSourceLocationEnabled(true);
+        }
 
         camelContext.setBacklogTracing(config.isBacklogTracing());
         camelContext.setTracing(config.isTracing());
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 0b6e0b2..6b13ed7 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
@@ -69,6 +69,7 @@ public abstract class DefaultConfigurationProperties<T> {
     private boolean tracing;
     private boolean tracingStandby;
     private String tracingPattern;
+    private boolean sourceLocationEnabled;
     private boolean messageHistory;
     private boolean logMask;
     private boolean logExhaustedMessageBody;
@@ -588,6 +589,21 @@ public abstract class DefaultConfigurationProperties<T> {
         this.messageHistory = messageHistory;
     }
 
+    public boolean isSourceLocationEnabled() {
+        return sourceLocationEnabled;
+    }
+
+    /**
+     * 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.
+     */
+    public void setSourceLocationEnabled(boolean sourceLocationEnabled) {
+        this.sourceLocationEnabled = sourceLocationEnabled;
+    }
+
     public boolean isLogMask() {
         return logMask;
     }
@@ -1729,6 +1745,18 @@ public abstract class DefaultConfigurationProperties<T> {
     }
 
     /**
+     * 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.
+     */
+    public T withSourceLocationEnabled(boolean sourceLocationEnabled) {
+        this.sourceLocationEnabled = sourceLocationEnabled;
+        return (T) this;
+    }
+
+    /**
      * Sets whether log mask is enabled or not.
      *
      * Default is false.