Skip to content

Commit

Permalink
[Instrumentation.AspNetCore, Instrumentation.Http] Fix http.request.m…
Browse files Browse the repository at this point in the history
…ethod_original attribute
  • Loading branch information
Kielek committed Mar 25, 2024
1 parent 49f16e4 commit 41120bf
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 49 deletions.
3 changes: 3 additions & 0 deletions src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
`server.address` when it has default values (`80` for `HTTP` and
`443` for `HTTPS` protocol).
([#5419](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5419))
* Fixed an issue for spans when `http.request.method_original` attribute was not
set for non canonical form of HTTP methods, e.g. for `Options`.
([#5471](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5471))

## 1.7.1

Expand Down
5 changes: 5 additions & 0 deletions src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
`server.address` when it has default values (`80` for `HTTP` and
`443` for `HTTPS` protocol).
([#5419](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5419))
* Fixed an issue for spans when `http.request.method_original` attribute was not
set for non canonical form of HTTP methods, e.g. for `Options`. The attribute
is not set .NET Framework for non canonical form of `Connect`, `GET`, `HEAD`,
`PUT`, and `POST`. HTTP Client is converting these values to canonical form.
([#5471](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5471))

## 1.7.1

Expand Down
14 changes: 6 additions & 8 deletions src/Shared/RequestMethodHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,14 @@ public static string GetNormalizedHttpMethod(string method)
: OtherHttpMethod;
}

public static void SetHttpMethodTag(Activity activity, string method)
public static void SetHttpMethodTag(Activity activity, string originalHttpMethod)
{
if (KnownMethods.TryGetValue(method, out var normalizedMethod))
{
activity?.SetTag(SemanticConventions.AttributeHttpRequestMethod, normalizedMethod);
}
else
var normalizedHttpMethod = GetNormalizedHttpMethod(originalHttpMethod);
activity.SetTag(SemanticConventions.AttributeHttpRequestMethod, normalizedHttpMethod);

if (originalHttpMethod != normalizedHttpMethod)
{
activity?.SetTag(SemanticConventions.AttributeHttpRequestMethod, OtherHttpMethod);
activity?.SetTag(SemanticConventions.AttributeHttpRequestMethodOriginal, method);
activity.SetTag(SemanticConventions.AttributeHttpRequestMethodOriginal, originalHttpMethod);
}
}

Expand Down
38 changes: 14 additions & 24 deletions test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -629,18 +629,18 @@ void ConfigureTestServices(IServiceCollection services)
}

[Theory]
[InlineData("CONNECT", "CONNECT")]
[InlineData("DELETE", "DELETE")]
[InlineData("GET", "GET")]
[InlineData("PUT", "PUT")]
[InlineData("HEAD", "HEAD")]
[InlineData("OPTIONS", "OPTIONS")]
[InlineData("PATCH", "PATCH")]
[InlineData("Get", "GET")]
[InlineData("POST", "POST")]
[InlineData("TRACE", "TRACE")]
[InlineData("CUSTOM", "_OTHER")]
public async Task HttpRequestMethodIsSetAsPerSpec(string originalMethod, string expectedMethod)
[InlineData("CONNECT", "CONNECT", null)]
[InlineData("DELETE", "DELETE", null)]
[InlineData("GET", "GET", null)]
[InlineData("PUT", "PUT", null)]
[InlineData("HEAD", "HEAD", null)]
[InlineData("OPTIONS", "OPTIONS", null)]
[InlineData("PATCH", "PATCH", null)]
[InlineData("Get", "GET", "Get")]
[InlineData("POST", "POST", null)]
[InlineData("TRACE", "TRACE", null)]
[InlineData("CUSTOM", "_OTHER", "CUSTOM")]
public async Task HttpRequestMethodIsSetAsPerSpec(string originalMethod, string expectedMethod, string expectedOriginalMethod)
{
var exportedItems = new List<Activity>();

Expand Down Expand Up @@ -681,18 +681,8 @@ void ConfigureTestServices(IServiceCollection services)

var activity = exportedItems[0];

Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeHttpRequestMethod);

if (originalMethod.Equals(expectedMethod, StringComparison.OrdinalIgnoreCase))
{
Assert.DoesNotContain(activity.TagObjects, t => t.Key == SemanticConventions.AttributeHttpRequestMethodOriginal);
}
else
{
Assert.Equal(originalMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethodOriginal) as string);
}

Assert.Equal(expectedMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod) as string);
Assert.Equal(expectedMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod));
Assert.Equal(expectedOriginalMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethodOriginal));
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,18 +356,34 @@ public async Task ExportsSpansCreatedForRetries()
}

[Theory]
[InlineData("CONNECT", "CONNECT")]
[InlineData("DELETE", "DELETE")]
[InlineData("GET", "GET")]
[InlineData("PUT", "PUT")]
[InlineData("HEAD", "HEAD")]
[InlineData("OPTIONS", "OPTIONS")]
[InlineData("PATCH", "PATCH")]
[InlineData("Get", "GET")]
[InlineData("POST", "POST")]
[InlineData("TRACE", "TRACE")]
[InlineData("CUSTOM", "_OTHER")]
public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMethod, string expectedMethod)
[InlineData("CONNECT", "CONNECT", null)]
[InlineData("DELETE", "DELETE", null)]
[InlineData("GET", "GET", null)]
[InlineData("PUT", "PUT", null)]
[InlineData("HEAD", "HEAD", null)]
[InlineData("OPTIONS", "OPTIONS", null)]
[InlineData("PATCH", "PATCH", null)]
[InlineData("POST", "POST", null)]
[InlineData("TRACE", "TRACE", null)]
[InlineData("Delete", "DELETE", "Delete")]
#if NETFRAMEWORK
[InlineData("Connect", "CONNECT", null)]// HTTP Client converts Connect to its canonical form (Connect). Expected method is null.
[InlineData("Get", "GET", null)] // HTTP Client converts Get to its canonical form (GET). Expected method is null.
[InlineData("Put", "PUT", null)] // HTTP Client converts Put to its canonical form (PUT). Expected method is null.
[InlineData("Head", "HEAD", null)] // HTTP Client converts Head to its canonical form (HEAD). Expected method is null.
[InlineData("Post", "POST", null)] // HTTP Client converts Post to its canonical form (POST). Expected method is null.
#else
[InlineData("Connect", "CONNECT", "Connect")]
[InlineData("Get", "GET", "Get")]
[InlineData("Put", "PUT", "Put")]
[InlineData("Head", "HEAD", "Head")]
[InlineData("Post", "POST", "Post")]
#endif
[InlineData("Options", "OPTIONS", "Options")]
[InlineData("Patch", "PATCH", "Patch")]
[InlineData("Trace", "TRACE", "Trace")]
[InlineData("CUSTOM", "_OTHER", "CUSTOM")]
public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMethod, string expectedMethod, string expectedOriginalMethod)
{
var exportedItems = new List<Activity>();
using var request = new HttpRequestMessage
Expand Down Expand Up @@ -396,20 +412,17 @@ public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMetho

var activity = exportedItems[0];

Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeHttpRequestMethod);

if (originalMethod.Equals(expectedMethod, StringComparison.OrdinalIgnoreCase))
{
Assert.Equal(expectedMethod, activity.DisplayName);
Assert.DoesNotContain(activity.TagObjects, t => t.Key == SemanticConventions.AttributeHttpRequestMethodOriginal);
}
else
{
Assert.Equal("HTTP", activity.DisplayName);
Assert.Equal(originalMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethodOriginal) as string);
}

Assert.Equal(expectedMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod) as string);
Assert.Equal(expectedMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod));
Assert.Equal(expectedOriginalMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethodOriginal));
}

[Theory]
Expand All @@ -423,6 +436,7 @@ public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMetho
[InlineData("Get", "GET")]
[InlineData("POST", "POST")]
[InlineData("TRACE", "TRACE")]
[InlineData("Trace", "TRACE")]
[InlineData("CUSTOM", "_OTHER")]
public async Task HttpRequestMethodIsSetonRequestDurationMetricAsPerSpec(string originalMethod, string expectedMethod)
{
Expand Down

0 comments on commit 41120bf

Please sign in to comment.