diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 320202b0fea..48fcda3d101 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -41,6 +41,9 @@ ([#5005](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5005)) ([#5034](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5034)) +* Fixed `network.protocol.version` attribute values to match the specification. + ([#5006](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5006)) + ## 1.6.0-beta.2 Released 2023-Oct-26 diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index ffdd952c326..924f260a90e 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -205,7 +205,7 @@ public void OnStartActivity(Activity activity, object payload) } activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri)); - activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version)); + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetProtocolVersionString(request.Version)); if (request.Headers.TryGetValues("User-Agent", out var userAgentValues)) { diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs index 5dc02591204..9b20cbb533e 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs @@ -130,7 +130,7 @@ public void OnStopEventWritten(Activity activity, object payload) tags.Add(new KeyValuePair(SemanticConventions.AttributeServerAddress, request.RequestUri.Host)); tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, request.RequestUri.Scheme)); - tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version))); + tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetProtocolVersionString(request.Version))); if (!request.RequestUri.IsDefaultPort) { diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs index d97ae9bbec0..892f6fa6c5a 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs @@ -78,6 +78,15 @@ public static string GetUriTagValueFromRequestUri(Uri uri) return string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); } + public static string GetProtocolVersionString(Version httpVersion) => (httpVersion.Major, httpVersion.Minor) switch + { + (1, 0) => "1.0", + (1, 1) => "1.1", + (2, 0) => "2", + (3, 0) => "3", + _ => httpVersion.ToString(), + }; + private static string ConvertMethodToOperationName(string method) => $"HTTP {method}"; private static string ConvertHttpMethodToOperationName(HttpMethod method) => $"HTTP {method}"; diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index 67f0204f4e1..3852201fde7 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -173,7 +173,7 @@ private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, A } activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri)); - activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.ProtocolVersion)); + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetProtocolVersionString(request.ProtocolVersion)); } try @@ -531,7 +531,7 @@ private static void ProcessResult(IAsyncResult asyncResult, AsyncCallback asyncC tags.Add(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); tags.Add(SemanticConventions.AttributeUrlScheme, request.RequestUri.Scheme); - tags.Add(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.ProtocolVersion)); + tags.Add(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetProtocolVersionString(request.ProtocolVersion)); if (!request.RequestUri.IsDefaultPort) { tags.Add(SemanticConventions.AttributeServerPort, request.RequestUri.Port); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/InProcServerTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/InProcServerTests.cs deleted file mode 100644 index f92a3ca20dd..00000000000 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/InProcServerTests.cs +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed 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. -// - -using System.Diagnostics; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Logging; -using OpenTelemetry.Trace; -using Xunit; - -namespace OpenTelemetry.Instrumentation.AspNetCore.Tests; - -public sealed class InProcServerTests : IDisposable -{ - private TracerProvider tracerProvider; - private WebApplication app; - private HttpClient client; - private List exportedItems; - - public InProcServerTests() - { - this.exportedItems = new List(); - var builder = WebApplication.CreateBuilder(); - builder.Logging.ClearProviders(); - var app = builder.Build(); - - this.tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAspNetCoreInstrumentation() - .AddInMemoryExporter(this.exportedItems).Build(); - app.MapGet("/", () => "Hello World!"); - app.RunAsync(); - - this.app = app; - this.client = new HttpClient(); - } - - [Fact] - public async void ExampleTest() - { - var res = await this.client.GetStringAsync("http://localhost:5000").ConfigureAwait(false); - Assert.NotNull(res); - - this.tracerProvider.ForceFlush(); - for (var i = 0; i < 10; i++) - { - if (this.exportedItems.Count > 0) - { - break; - } - - // We need to let End callback execute as it is executed AFTER response was returned. - // In unit tests environment there may be a lot of parallel unit tests executed, so - // giving some breezing room for the End callback to complete - await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); - } - - var activity = this.exportedItems[0]; - Assert.Equal(ActivityKind.Server, activity.Kind); - Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeNetHostName)); - Assert.Equal(5000, activity.GetTagValue(SemanticConventions.AttributeNetHostPort)); - Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeHttpMethod)); - Assert.Equal("1.1", activity.GetTagValue(SemanticConventions.AttributeHttpFlavor)); - Assert.Equal(200, activity.GetTagValue(SemanticConventions.AttributeHttpStatusCode)); - Assert.True(activity.Status == ActivityStatusCode.Unset); - Assert.True(activity.StatusDescription is null); - } - - public async void Dispose() - { - this.tracerProvider.Dispose(); - this.client.Dispose(); - await this.app.DisposeAsync().ConfigureAwait(false); - } -}