diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index 13f7475cdd..01cfbd3994 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -84,6 +84,7 @@ private void OnStartActivity(Activity activity, HttpContext context) var url = request.Url; activity.SetTag(SemanticConventions.AttributeServerAddress, url.Host); activity.SetTag(SemanticConventions.AttributeServerPort, url.Port); + activity.SetTag(SemanticConventions.AttributeUrlScheme, url.Scheme); var originalHttpMethod = request.HttpMethod; var normalizedHttpMethod = this.requestMethodHelper.GetNormalizedHttpMethod(originalHttpMethod); diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index a347358654..27d072b4bb 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -20,24 +20,25 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; public class HttpInListenerTests { [Theory] - [InlineData("http://localhost/", "http://localhost/", "/", "localhost", 80, "GET", "GET", null, 0, null)] - [InlineData("http://localhost/", "http://localhost/", "/", "localhost", 80, "POST", "POST", null, 0, null, true)] - [InlineData("https://localhost/", "https://localhost/", "/", "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null)] - [InlineData("https://localhost/", "https://user:pass@localhost/", "/", "localhost", 443, "GET", "GET", null, 0, null)] // Test URL sanitization - [InlineData("http://localhost:443/", "http://localhost:443/", "/", "localhost", 443, "GET", "GET", null, 0, null)] // Test http over 443 - [InlineData("https://localhost:80/", "https://localhost:80/", "/", "localhost", 80, "GET", "GET", null, 0, null)] // Test https over 80 - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "/Home/Index.htm", "localhost", 80, "GET", "GET", null, 0, null)] // Test complex URL - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "/Home/Index.htm", "localhost", 80, "GET", "GET", null, 0, null)] // Test complex URL sanitization - [InlineData("http://localhost:80/Index", "http://localhost:80/Index", "/Index", "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}")] - [InlineData("https://localhost:443/about_attr_route/10", "https://localhost:443/about_attr_route/10", "/about_attr_route/10", "localhost", 443, "GET", "GET", null, 2, "about_attr_route/{customerId}")] - [InlineData("http://localhost:1880/api/weatherforecast", "http://localhost:1880/api/weatherforecast", "/api/weatherforecast", "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}")] - [InlineData("https://localhost:1843/subroute/10", "https://localhost:1843/subroute/10", "/subroute/10", "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}")] - [InlineData("http://localhost/api/value", "http://localhost/api/value", "/api/value", "localhost", 80, "GET", "GET", null, 0, null, false, "/api/value")] // Request will be filtered - [InlineData("http://localhost/api/value", "http://localhost/api/value", "/api/value", "localhost", 80, "GET", "GET", null, 0, null, false, "{ThrowException}")] // Filter user code will throw an exception - [InlineData("http://localhost/", "http://localhost/", "/", "localhost", 80, "GET", "GET", null, 0, null, false, null, true)] // Test RecordException option + [InlineData("http://localhost/", "http://localhost/", "http", "/", "localhost", 80, "GET", "GET", null, 0, null)] + [InlineData("http://localhost/", "http://localhost/", "http", "/", "localhost", 80, "POST", "POST", null, 0, null, true)] + [InlineData("https://localhost/", "https://localhost/", "https", "/", "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null)] + [InlineData("https://localhost/", "https://user:pass@localhost/", "https", "/", "localhost", 443, "GET", "GET", null, 0, null)] // Test URL sanitization + [InlineData("http://localhost:443/", "http://localhost:443/", "http", "/", "localhost", 443, "GET", "GET", null, 0, null)] // Test http over 443 + [InlineData("https://localhost:80/", "https://localhost:80/", "https", "/", "localhost", 80, "GET", "GET", null, 0, null)] // Test https over 80 + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "localhost", 80, "GET", "GET", null, 0, null)] // Test complex URL + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "localhost", 80, "GET", "GET", null, 0, null)] // Test complex URL sanitization + [InlineData("http://localhost:80/Index", "http://localhost:80/Index", "http", "/Index", "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}")] + [InlineData("https://localhost:443/about_attr_route/10", "https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", "localhost", 443, "GET", "GET", null, 2, "about_attr_route/{customerId}")] + [InlineData("http://localhost:1880/api/weatherforecast", "http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}")] + [InlineData("https://localhost:1843/subroute/10", "https://localhost:1843/subroute/10", "https", "/subroute/10", "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}")] + [InlineData("http://localhost/api/value", "http://localhost/api/value", "http", "/api/value", "localhost", 80, "GET", "GET", null, 0, null, false, "/api/value")] // Request will be filtered + [InlineData("http://localhost/api/value", "http://localhost/api/value", "http", "/api/value", "localhost", 80, "GET", "GET", null, 0, null, false, "{ThrowException}")] // Filter user code will throw an exception + [InlineData("http://localhost/", "http://localhost/", "http", "/", "localhost", 80, "GET", "GET", null, 0, null, false, null, true)] // Test RecordException option public void AspNetRequestsAreCollectedSuccessfully( string expectedUrl, string url, + string expectedUrlScheme, string expectedUrlPath, string expectedHost, int expectedPort, @@ -143,6 +144,7 @@ public void AspNetRequestsAreCollectedSuccessfully( Assert.Equal(expectedOriginalRequestMethod, span.GetTagValue("http.request.method_original")); Assert.Equal(expectedUrlPath, span.GetTagValue("url.path")); + Assert.Equal(expectedUrlScheme, span.GetTagValue("url.scheme")); Assert.Equal("Custom User Agent v1.2.3", span.GetTagValue("user_agent.original")); if (recordException)