Skip to content

Commit 18ccd87

Browse files
ngrusoncijothomasCodeBlanchalanwest
authored
Only create a sibling activity when trace id, span id or trace state differ (#5136)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com> Co-authored-by: Mikel Blanchard <mblanchard@macrosssoftware.com> Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com>
1 parent 6d88762 commit 18ccd87

File tree

6 files changed

+59
-3
lines changed

6 files changed

+59
-3
lines changed

src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void OnStartActivity(Activity activity, object payload)
105105
// By this time, samplers have already run and
106106
// activity.IsAllDataRequested populated accordingly.
107107

108-
HttpContext context = payload as HttpContext;
108+
var context = payload as HttpContext;
109109
if (context == null)
110110
{
111111
AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName);
@@ -118,9 +118,10 @@ public void OnStartActivity(Activity activity, object payload)
118118
if (textMapPropagator is not TraceContextPropagator)
119119
{
120120
var ctx = textMapPropagator.Extract(default, request, HttpRequestHeaderValuesGetter);
121-
122121
if (ctx.ActivityContext.IsValid()
123-
&& ctx.ActivityContext != new ActivityContext(activity.TraceId, activity.ParentSpanId, activity.ActivityTraceFlags, activity.TraceStateString, true))
122+
&& !((ctx.ActivityContext.TraceId == activity.TraceId)
123+
&& (ctx.ActivityContext.SpanId == activity.ParentSpanId)
124+
&& (ctx.ActivityContext.TraceState == activity.TraceStateString)))
124125
{
125126
// Create a new activity with its parent set from the extracted context.
126127
// This makes the new activity as a "sibling" of the activity created by

src/OpenTelemetry/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
upgrading. For details see:
1010
[#5169](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5169)
1111

12+
* Fixed an issue where the created activity from ASP.NET Core was replaced
13+
with a new one. This replacement should only happen when the activity context
14+
from the used propagator has a different trace id, parent span id or trace
15+
state compared to the current activity. For details see:
16+
[#5136](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5136)
17+
1218
## 1.7.0
1319

1420
Released 2023-Dec-08

test/Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
<PackageVersion Update="System.Text.Json" Version="7.0.1" />
55
<PackageVersion Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
66
<PackageVersion Include="Microsoft.Coyote" Version="1.7.10" />
7+
<PackageVersion Include="Microsoft.Extensions.Features" Version="8.0.0" />
78
</ItemGroup>
89
</Project>

test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,43 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan
10241024
Assert.True(exceptionHandled);
10251025
}
10261026

1027+
#if NET6_0_OR_GREATER
1028+
[Fact]
1029+
public async Task NoSiblingActivityCreatedWhenTraceFlagsNone()
1030+
{
1031+
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
1032+
.SetSampler(new AlwaysOnSampler())
1033+
.AddAspNetCoreInstrumentation()
1034+
.Build();
1035+
1036+
using var testFactory = this.factory
1037+
.WithWebHostBuilder(builder =>
1038+
{
1039+
builder.ConfigureTestServices(services =>
1040+
{
1041+
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
1042+
.AddAspNetCoreInstrumentation()
1043+
.Build();
1044+
});
1045+
1046+
builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders());
1047+
});
1048+
using var client = testFactory.CreateClient();
1049+
var request = new HttpRequestMessage(HttpMethod.Get, "/api/GetActivityEquality");
1050+
var traceId = ActivityTraceId.CreateRandom();
1051+
var spanId = ActivitySpanId.CreateRandom();
1052+
request.Headers.Add("traceparent", $"00-{traceId}-{spanId}-00");
1053+
1054+
var response = await client.SendAsync(request);
1055+
var result = bool.Parse(await response.Content.ReadAsStringAsync());
1056+
1057+
Assert.True(response.IsSuccessStatusCode);
1058+
1059+
// Confirm that Activity.Current and IHttpActivityFeature activity are same
1060+
Assert.True(result);
1061+
}
1062+
#endif
1063+
10271064
public void Dispose()
10281065
{
10291066
this.tracerProvider?.Dispose();

test/TestApp.AspNetCore/Controllers/ChildActivityController.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
using System.Diagnostics;
5+
using Microsoft.AspNetCore.Http.Features;
56
using Microsoft.AspNetCore.Mvc;
67
using OpenTelemetry;
78

@@ -34,4 +35,13 @@ public IReadOnlyDictionary<string, string> GetChildActivityBaggageContext()
3435
var result = Baggage.Current.GetBaggage();
3536
return result;
3637
}
38+
39+
[HttpGet]
40+
[Route("api/GetActivityEquality")]
41+
public bool GetActivityEquality()
42+
{
43+
var activity = this.HttpContext.Features.GetRequiredFeature<IHttpActivityFeature>().Activity;
44+
var equal = Activity.Current == activity;
45+
return equal;
46+
}
3747
}

test/TestApp.AspNetCore/TestApp.AspNetCore.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8+
<PackageReference Include="Microsoft.Extensions.Features" />
89
<PackageReference Include="Swashbuckle.AspNetCore" />
910
</ItemGroup>
1011

0 commit comments

Comments
 (0)