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

gnodet pushed a commit to branch backport/28867-to-camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 77aa3d2c7925009874bf7f675306de8be72104be
Author: Guillaume Nodet <[email protected]>
AuthorDate: Mon Nov 2 22:13:19 2026 +0000

    [backport camel-4.18.x] CAMEL-26490: camel-telemetry, camel-tracing - 
present the http.url, url.path and server.address span attributes like camel.uri
---
 .../decorators/AbstractHttpSpanDecorator.java      | 41 ++++++++--
 .../decorators/AbstractSpanDecorator.java          | 21 ++++-
 .../decorators/AbstractHttpSpanDecoratorTest.java  | 95 ++++++++++++++++++++--
 .../decorators/AbstractSpanDecoratorTest.java      | 56 +++++++++++++
 .../decorators/AbstractHttpSpanDecorator.java      | 41 ++++++++--
 .../tracing/decorators/AbstractSpanDecorator.java  | 21 ++++-
 .../decorators/AbstractHttpSpanDecoratorTest.java  | 95 ++++++++++++++++++++--
 .../decorators/AbstractSpanDecoratorTest.java      | 56 +++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_18.adoc    | 17 ++++
 9 files changed, 411 insertions(+), 32 deletions(-)

diff --git 
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
 
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
index 24a1216e796c..0e3029674ab5 100644
--- 
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
+++ 
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecorator.java
@@ -19,9 +19,12 @@ package org.apache.camel.telemetry.decorators;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.telemetry.Op;
 import org.apache.camel.telemetry.Span;
 import org.apache.camel.telemetry.TagConstants;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.URISupport;
 
 public abstract class AbstractHttpSpanDecorator extends AbstractSpanDecorator {
 
@@ -76,22 +79,46 @@ public abstract class AbstractHttpSpanDecorator extends 
AbstractSpanDecorator {
     }
 
     protected String getHttpURL(Exchange exchange, Endpoint endpoint) {
+        // the url is presented the same way as the camel.uri tag
         Object url = exchange.getIn().getHeader(Exchange.HTTP_URL);
         if (url instanceof String str) {
-            return str;
+            return URISupport.sanitizeUri(str);
         } else {
             Object uri = exchange.getIn().getHeader(Exchange.HTTP_URI);
             if (uri instanceof String str) {
-                return str;
+                return URISupport.sanitizeUri(str);
             } else {
                 // Try to obtain from endpoint
-                int index = endpoint.getEndpointUri().lastIndexOf("http:");
-                if (index != -1) {
-                    return endpoint.getEndpointUri().substring(index);
-                }
+                return URISupport.sanitizeUri(getHttpAddress(endpoint));
+            }
+        }
+    }
+
+    /**
+     * The HTTP address the endpoint sends to, without the endpoint options.
+     */
+    private static String getHttpAddress(Endpoint endpoint) {
+        // the service url of an HTTP endpoint is its HTTP address with the 
query parameters that are sent
+        if (endpoint instanceof EndpointServiceLocation esl) {
+            String url = esl.getServiceUrl();
+            if (isHttpAddress(url)) {
+                return url;
             }
         }
-        return null;
+        // otherwise take the endpoint uri, without the component scheme in 
front of the HTTP address
+        // (such as netty-http:http://host or vertx-http://https://host) and 
without the endpoint options
+        String uri = endpoint.getEndpointUri();
+        if (!isHttpAddress(uri)) {
+            uri = StringHelper.after(uri, ":");
+            if (uri != null && uri.startsWith("//")) {
+                uri = uri.substring(2);
+            }
+        }
+        return isHttpAddress(uri) ? URISupport.stripQuery(uri) : null;
+    }
+
+    private static boolean isHttpAddress(String uri) {
+        return uri != null && (uri.startsWith("http://";) || 
uri.startsWith("https://";));
     }
 
     @Override
diff --git 
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
 
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
index 352b3974fd4c..4cba91594b27 100644
--- 
a/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
+++ 
b/components/camel-telemetry/src/main/java/org/apache/camel/telemetry/decorators/AbstractSpanDecorator.java
@@ -89,6 +89,22 @@ public abstract class AbstractSpanDecorator implements 
SpanDecorator {
         return Collections.emptyMap();
     }
 
+    /**
+     * The path of the endpoint URI without the scheme, the user info in front 
of the host and the options.
+     */
+    private static String getUrlPath(Endpoint endpoint) {
+        String path = stripSchemeAndOptions(endpoint);
+        // the user info ends at the last @ before the first /
+        int colon = path.indexOf(':');
+        int slash = path.indexOf('/');
+        int at = slash == -1 ? path.lastIndexOf('@') : path.lastIndexOf('@', 
slash);
+        if (colon != -1 && colon < at) {
+            path = path.substring(at + 1);
+        }
+        // presented the same way as the camel.uri tag, for a path that is 
another uri (such as netty-http:http://host)
+        return URISupport.sanitizeUri(path);
+    }
+
     private static String getComponentName(Endpoint endpoint) {
         String answer = endpoint.getComponent() != null ? 
endpoint.getComponent().getDefaultName() : null;
         if (answer == null) {
@@ -123,7 +139,7 @@ public abstract class AbstractSpanDecorator implements 
SpanDecorator {
         // have been provided, for subsequent analysis
         String uri = endpoint.toString(); // toString will sanitize
         span.setTag("camel.uri", uri);
-        span.setTag(TagConstants.URL_PATH, stripSchemeAndOptions(endpoint));
+        span.setTag(TagConstants.URL_PATH, getUrlPath(endpoint));
         String query = URISupport.extractQuery(uri);
         if (query != null) {
             span.setTag(TagConstants.URL_QUERY, query);
@@ -133,7 +149,8 @@ public abstract class AbstractSpanDecorator implements 
SpanDecorator {
         if (endpoint instanceof EndpointServiceLocation ela) {
             String adr = ela.getServiceUrl();
             if (adr != null) {
-                span.setTag(TagConstants.SERVER_ADDRESS, adr);
+                // the address is presented the same way as the camel.uri tag
+                span.setTag(TagConstants.SERVER_ADDRESS, 
URISupport.sanitizeUri(adr));
             }
             String ap = ela.getServiceProtocol();
             if (ap != null) {
diff --git 
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
 
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
index 9e7314b4e255..6b05fed0994c 100644
--- 
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
+++ 
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractHttpSpanDecoratorTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.telemetry.decorators;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.telemetry.TagConstants;
 import org.apache.camel.telemetry.mock.MockSpanAdapter;
 import org.junit.jupiter.api.BeforeEach;
@@ -150,9 +151,9 @@ public class AbstractHttpSpanDecoratorTest {
         Exchange exchange = Mockito.mock(Exchange.class);
         Message message = Mockito.mock(Message.class);
 
-        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint";);
         Mockito.when(exchange.getIn()).thenReturn(message);
-        Mockito.when(message.getHeader(Exchange.HTTP_URI, 
String.class)).thenReturn(TEST_URI);
+        
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
 
         MockSpanAdapter span = new MockSpanAdapter();
 
@@ -168,10 +169,10 @@ public class AbstractHttpSpanDecoratorTest {
         Exchange exchange = Mockito.mock(Exchange.class);
         Message message = Mockito.mock(Message.class);
 
-        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint";);
         Mockito.when(exchange.getIn()).thenReturn(message);
-        Mockito.when(message.getHeader(Exchange.HTTP_URI, 
String.class)).thenReturn("Another URL");
-        Mockito.when(message.getHeader(Exchange.HTTP_URL, 
String.class)).thenReturn(TEST_URI);
+        Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn("Another 
URL");
+        
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn(TEST_URI);
 
         assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
     }
@@ -182,13 +183,26 @@ public class AbstractHttpSpanDecoratorTest {
         Exchange exchange = Mockito.mock(Exchange.class);
         Message message = Mockito.mock(Message.class);
 
-        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint";);
         Mockito.when(exchange.getIn()).thenReturn(message);
-        Mockito.when(message.getHeader(Exchange.HTTP_URI, 
String.class)).thenReturn(TEST_URI);
+        
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
 
         assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
     }
 
+    @Test
+    public void testGetHttpURLFromHeaderUrlPresentedLikeCamelUri() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+        
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn("http://scott:tiger@localhost:8080/test";);
+
+        assertEquals("http://scott:xxxxxx@localhost:8080/test";, 
decorator.getHttpURL(exchange, endpoint));
+    }
+
     @Test
     public void testGetHttpURLFromEndpointUri() {
         Endpoint endpoint = Mockito.mock(Endpoint.class);
@@ -213,6 +227,73 @@ public class AbstractHttpSpanDecoratorTest {
         assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
     }
 
+    @Test
+    public void testGetHttpURLFromEndpointUriWithoutEndpointOptions() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI + 
"?connectTimeout=5000&throwExceptionOnFailure=false");
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void 
testGetHttpURLFromEndpointUriWithComponentSchemeAndHttpsAddress() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("vertx-http://https://localhost:8443/test?connectTimeout=5000";);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals("https://localhost:8443/test";, 
decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void testGetHttpURLFromServiceUrl() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?q=1&connectTimeout=5000";);
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test?q=1";);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals("https://localhost:8443/test?q=1";, 
decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void testGetHttpURLFromEndpointUriWhenServiceUrlIsNotHttpAddress() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn("netty-http:" + 
TEST_URI);
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("http:localhost:8080");
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void testPreHttpsEndpoint() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?connectTimeout=5000";);
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test";);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        MockSpanAdapter span = new MockSpanAdapter();
+
+        decorator.beforeTracingEvent(span, exchange, endpoint);
+
+        assertEquals("https://localhost:8443/test";, 
span.tags().get(TagConstants.HTTP_URL));
+    }
+
     @Test
     public void testPostResponseCode() {
         Exchange exchange = Mockito.mock(Exchange.class);
diff --git 
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
 
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
index 5bcf53a26b91..5fb9154abbc5 100644
--- 
a/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
+++ 
b/components/camel-telemetry/src/test/java/org/apache/camel/telemetry/decorators/AbstractSpanDecoratorTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.telemetry.decorators;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.telemetry.SpanDecorator;
 import org.apache.camel.telemetry.TagConstants;
 import org.apache.camel.telemetry.mock.MockSpanAdapter;
@@ -85,6 +86,61 @@ public class AbstractSpanDecoratorTest {
         assertEquals("myRouteId", span.tags().get(TagConstants.ROUTE_ID));
     }
 
+    @Test
+    public void testPreUrlPathWithoutUserInfo() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("ftp://scott:tiger@localhost:2121/inbox?binary=true";);
+        
Mockito.when(endpoint.toString()).thenReturn("ftp://scott:xxxxxx@localhost:2121/inbox?binary=true";);
+
+        SpanDecorator decorator = new AbstractSpanDecorator() {
+            @Override
+            public String getComponent() {
+                return null;
+            }
+
+            @Override
+            public String getComponentClassName() {
+                return null;
+            }
+        };
+
+        MockSpanAdapter span = new MockSpanAdapter();
+
+        decorator.beforeTracingEvent(span, exchange, endpoint);
+
+        assertEquals("localhost:2121/inbox", 
span.tags().get(TagConstants.URL_PATH));
+        assertEquals("binary=true", span.tags().get(TagConstants.URL_QUERY));
+    }
+
+    @Test
+    public void testPreServerAddressPresentedLikeCamelUri() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn("amqp:queue:foo");
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("amqp://scott:tiger@localhost:5672");
+
+        SpanDecorator decorator = new AbstractSpanDecorator() {
+            @Override
+            public String getComponent() {
+                return null;
+            }
+
+            @Override
+            public String getComponentClassName() {
+                return null;
+            }
+        };
+
+        MockSpanAdapter span = new MockSpanAdapter();
+
+        decorator.beforeTracingEvent(span, exchange, endpoint);
+
+        assertEquals("amqp://scott:xxxxxx@localhost:5672", 
span.tags().get(TagConstants.SERVER_ADDRESS));
+    }
+
     @Test
     public void testPostExchangeFailed() {
         Exchange exchange = Mockito.mock(Exchange.class);
diff --git 
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
 
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
index 058c4e660b69..b56f669b15db 100644
--- 
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
+++ 
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecorator.java
@@ -19,8 +19,11 @@ package org.apache.camel.tracing.decorators;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.tracing.SpanAdapter;
 import org.apache.camel.tracing.TagConstants;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.URISupport;
 
 public abstract class AbstractHttpSpanDecorator extends AbstractSpanDecorator {
 
@@ -75,22 +78,46 @@ public abstract class AbstractHttpSpanDecorator extends 
AbstractSpanDecorator {
     }
 
     protected String getHttpURL(Exchange exchange, Endpoint endpoint) {
+        // the url is presented the same way as the camel.uri tag
         Object url = exchange.getIn().getHeader(Exchange.HTTP_URL);
         if (url instanceof String) {
-            return (String) url;
+            return URISupport.sanitizeUri((String) url);
         } else {
             Object uri = exchange.getIn().getHeader(Exchange.HTTP_URI);
             if (uri instanceof String) {
-                return (String) uri;
+                return URISupport.sanitizeUri((String) uri);
             } else {
                 // Try to obtain from endpoint
-                int index = endpoint.getEndpointUri().lastIndexOf("http:");
-                if (index != -1) {
-                    return endpoint.getEndpointUri().substring(index);
-                }
+                return URISupport.sanitizeUri(getHttpAddress(endpoint));
             }
         }
-        return null;
+    }
+
+    /**
+     * The HTTP address the endpoint sends to, without the endpoint options.
+     */
+    private static String getHttpAddress(Endpoint endpoint) {
+        // the service url of an HTTP endpoint is its HTTP address with the 
query parameters that are sent
+        if (endpoint instanceof EndpointServiceLocation esl) {
+            String url = esl.getServiceUrl();
+            if (isHttpAddress(url)) {
+                return url;
+            }
+        }
+        // otherwise take the endpoint uri, without the component scheme in 
front of the HTTP address
+        // (such as netty-http:http://host or vertx-http://https://host) and 
without the endpoint options
+        String uri = endpoint.getEndpointUri();
+        if (!isHttpAddress(uri)) {
+            uri = StringHelper.after(uri, ":");
+            if (uri != null && uri.startsWith("//")) {
+                uri = uri.substring(2);
+            }
+        }
+        return isHttpAddress(uri) ? URISupport.stripQuery(uri) : null;
+    }
+
+    private static boolean isHttpAddress(String uri) {
+        return uri != null && (uri.startsWith("http://";) || 
uri.startsWith("https://";));
     }
 
     @Override
diff --git 
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
 
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
index cefb3445f8d8..f3670c375490 100644
--- 
a/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
+++ 
b/components/camel-tracing/src/main/java/org/apache/camel/tracing/decorators/AbstractSpanDecorator.java
@@ -87,6 +87,22 @@ public abstract class AbstractSpanDecorator implements 
SpanDecorator {
         return Collections.emptyMap();
     }
 
+    /**
+     * The path of the endpoint URI without the scheme, the user info in front 
of the host and the options.
+     */
+    private static String getUrlPath(Endpoint endpoint) {
+        String path = stripSchemeAndOptions(endpoint);
+        // the user info ends at the last @ before the first /
+        int colon = path.indexOf(':');
+        int slash = path.indexOf('/');
+        int at = slash == -1 ? path.lastIndexOf('@') : path.lastIndexOf('@', 
slash);
+        if (colon != -1 && colon < at) {
+            path = path.substring(at + 1);
+        }
+        // presented the same way as the camel.uri tag, for a path that is 
another uri (such as netty-http:http://host)
+        return URISupport.sanitizeUri(path);
+    }
+
     private static String getComponentName(Endpoint endpoint) {
         String answer = endpoint.getComponent() != null ? 
endpoint.getComponent().getDefaultName() : null;
         if (answer == null) {
@@ -128,7 +144,7 @@ public abstract class AbstractSpanDecorator implements 
SpanDecorator {
         // have been provided, for subsequent analysis
         String uri = endpoint.toString(); // toString will sanitize
         span.setTag("camel.uri", uri);
-        span.setTag(TagConstants.URL_PATH, stripSchemeAndOptions(endpoint));
+        span.setTag(TagConstants.URL_PATH, getUrlPath(endpoint));
         String query = URISupport.extractQuery(uri);
         if (query != null) {
             span.setTag(TagConstants.URL_QUERY, query);
@@ -138,7 +154,8 @@ public abstract class AbstractSpanDecorator implements 
SpanDecorator {
         if (endpoint instanceof EndpointServiceLocation ela) {
             String adr = ela.getServiceUrl();
             if (adr != null) {
-                span.setTag(TagConstants.SERVER_ADDRESS, adr);
+                // the address is presented the same way as the camel.uri tag
+                span.setTag(TagConstants.SERVER_ADDRESS, 
URISupport.sanitizeUri(adr));
             }
             String ap = ela.getServiceProtocol();
             if (ap != null) {
diff --git 
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
 
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
index c48d8751f28f..fe97b5f8affa 100644
--- 
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
+++ 
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractHttpSpanDecoratorTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.tracing.decorators;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.tracing.MockSpanAdapter;
 import org.apache.camel.tracing.TagConstants;
 import org.junit.jupiter.api.BeforeEach;
@@ -152,9 +153,9 @@ public class AbstractHttpSpanDecoratorTest {
         Exchange exchange = Mockito.mock(Exchange.class);
         Message message = Mockito.mock(Message.class);
 
-        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint";);
         Mockito.when(exchange.getIn()).thenReturn(message);
-        Mockito.when(message.getHeader(Exchange.HTTP_URI, 
String.class)).thenReturn(TEST_URI);
+        
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
 
         MockSpanAdapter span = new MockSpanAdapter();
 
@@ -170,10 +171,10 @@ public class AbstractHttpSpanDecoratorTest {
         Exchange exchange = Mockito.mock(Exchange.class);
         Message message = Mockito.mock(Message.class);
 
-        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint";);
         Mockito.when(exchange.getIn()).thenReturn(message);
-        Mockito.when(message.getHeader(Exchange.HTTP_URI, 
String.class)).thenReturn("Another URL");
-        Mockito.when(message.getHeader(Exchange.HTTP_URL, 
String.class)).thenReturn(TEST_URI);
+        Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn("Another 
URL");
+        
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn(TEST_URI);
 
         assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
     }
@@ -184,13 +185,26 @@ public class AbstractHttpSpanDecoratorTest {
         Exchange exchange = Mockito.mock(Exchange.class);
         Message message = Mockito.mock(Message.class);
 
-        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("http://localhost:8080/endpoint";);
         Mockito.when(exchange.getIn()).thenReturn(message);
-        Mockito.when(message.getHeader(Exchange.HTTP_URI, 
String.class)).thenReturn(TEST_URI);
+        
Mockito.when(message.getHeader(Exchange.HTTP_URI)).thenReturn(TEST_URI);
 
         assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
     }
 
+    @Test
+    public void testGetHttpURLFromHeaderUrlPresentedLikeCamelUri() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+        
Mockito.when(message.getHeader(Exchange.HTTP_URL)).thenReturn("http://scott:tiger@localhost:8080/test";);
+
+        assertEquals("http://scott:xxxxxx@localhost:8080/test";, 
decorator.getHttpURL(exchange, endpoint));
+    }
+
     @Test
     public void testGetHttpURLFromEndpointUri() {
         Endpoint endpoint = Mockito.mock(Endpoint.class);
@@ -215,6 +229,73 @@ public class AbstractHttpSpanDecoratorTest {
         assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
     }
 
+    @Test
+    public void testGetHttpURLFromEndpointUriWithoutEndpointOptions() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn(TEST_URI + 
"?connectTimeout=5000&throwExceptionOnFailure=false");
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void 
testGetHttpURLFromEndpointUriWithComponentSchemeAndHttpsAddress() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("vertx-http://https://localhost:8443/test?connectTimeout=5000";);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals("https://localhost:8443/test";, 
decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void testGetHttpURLFromServiceUrl() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?q=1&connectTimeout=5000";);
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test?q=1";);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals("https://localhost:8443/test?q=1";, 
decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void testGetHttpURLFromEndpointUriWhenServiceUrlIsNotHttpAddress() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn("netty-http:" + 
TEST_URI);
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("http:localhost:8080");
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        assertEquals(TEST_URI, decorator.getHttpURL(exchange, endpoint));
+    }
+
+    @Test
+    public void testPreHttpsEndpoint() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+        Message message = Mockito.mock(Message.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("https://localhost:8443/test?connectTimeout=5000";);
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("https://localhost:8443/test";);
+        Mockito.when(exchange.getIn()).thenReturn(message);
+
+        MockSpanAdapter span = new MockSpanAdapter();
+
+        decorator.pre(span, exchange, endpoint);
+
+        assertEquals("https://localhost:8443/test";, 
span.tags().get(TagConstants.HTTP_URL));
+    }
+
     @Test
     public void testPostResponseCode() {
         Exchange exchange = Mockito.mock(Exchange.class);
diff --git 
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
 
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
index 616ad491b23e..06f923418ac3 100644
--- 
a/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
+++ 
b/components/camel-tracing/src/test/java/org/apache/camel/tracing/decorators/AbstractSpanDecoratorTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.tracing.decorators;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.tracing.MockSpanAdapter;
 import org.apache.camel.tracing.SpanDecorator;
 import org.apache.camel.tracing.TagConstants;
@@ -86,6 +87,61 @@ public class AbstractSpanDecoratorTest {
         assertEquals("myRouteId", span.tags().get(TagConstants.ROUTE_ID));
     }
 
+    @Test
+    public void testPreUrlPathWithoutUserInfo() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class);
+        Exchange exchange = Mockito.mock(Exchange.class);
+
+        
Mockito.when(endpoint.getEndpointUri()).thenReturn("ftp://scott:tiger@localhost:2121/inbox?binary=true";);
+        
Mockito.when(endpoint.toString()).thenReturn("ftp://scott:xxxxxx@localhost:2121/inbox?binary=true";);
+
+        SpanDecorator decorator = new AbstractSpanDecorator() {
+            @Override
+            public String getComponent() {
+                return null;
+            }
+
+            @Override
+            public String getComponentClassName() {
+                return null;
+            }
+        };
+
+        MockSpanAdapter span = new MockSpanAdapter();
+
+        decorator.pre(span, exchange, endpoint);
+
+        assertEquals("localhost:2121/inbox", 
span.tags().get(TagConstants.URL_PATH));
+        assertEquals("binary=true", span.tags().get(TagConstants.URL_QUERY));
+    }
+
+    @Test
+    public void testPreServerAddressPresentedLikeCamelUri() {
+        Endpoint endpoint = Mockito.mock(Endpoint.class, 
Mockito.withSettings().extraInterfaces(EndpointServiceLocation.class));
+        Exchange exchange = Mockito.mock(Exchange.class);
+
+        Mockito.when(endpoint.getEndpointUri()).thenReturn("amqp:queue:foo");
+        Mockito.when(((EndpointServiceLocation) 
endpoint).getServiceUrl()).thenReturn("amqp://scott:tiger@localhost:5672");
+
+        SpanDecorator decorator = new AbstractSpanDecorator() {
+            @Override
+            public String getComponent() {
+                return null;
+            }
+
+            @Override
+            public String getComponentClassName() {
+                return null;
+            }
+        };
+
+        MockSpanAdapter span = new MockSpanAdapter();
+
+        decorator.pre(span, exchange, endpoint);
+
+        assertEquals("amqp://scott:xxxxxx@localhost:5672", 
span.tags().get(TagConstants.SERVER_ADDRESS));
+    }
+
     @Test
     public void testPostExchangeFailed() {
         Exchange exchange = Mockito.mock(Exchange.class);
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
index ae0e79663274..a9727cfadb38 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
@@ -2012,3 +2012,20 @@ The producer now discards that session, so the next 
exchange opens a fresh one.
 
 The default behaviour is unchanged: `disconnectOnNoReply` defaults to `true`, 
which already closed the session on a
 timeout. Setting `disconnectOnNoReply=false` no longer keeps the producer 
session open after a timeout.
+
+=== camel-telemetry, camel-tracing - the http.url, url.path and server.address 
span attributes are presented like camel.uri
+
+This applies to `camel-opentelemetry2`, `camel-micrometer-observability`, 
`camel-telemetry-dev`, `camel-opentelemetry`
+and `camel-observation`. The `http.url`, `url.path` and `server.address` 
attributes of a span are now presented the same
+way as the `camel.uri` attribute, which shows the endpoint URI as 
`Endpoint.toString()` does:
+
+* `http.url`, when the message has neither a `CamelHttpUrl` nor a 
`CamelHttpUri` header, is now the HTTP address the
+  endpoint sends to, with the query parameters it sends but without the Camel 
endpoint options. Before, it was the
+  endpoint URI from the last `http:` onwards, with all the endpoint options. A 
`camel-http` endpoint with an `https`
+  address now sets the attribute as well, and for a `camel-vertx-http` 
endpoint with an `https` address the value no
+  longer starts with `http://https://`.
+* `url.path` no longer includes the user info in front of the host of the 
endpoint URI.
+* `server.address`, and `http.url` taken from the `CamelHttpUrl` or 
`CamelHttpUri` header, are presented as `camel.uri`
+  is.
+
+Dashboards or queries that use the old values may need a change.

Reply via email to