Skip to content

Commit 73bff75

Browse files
Default Sampler update + ParentOrElse fix (#1013)
* Updated default sampler to match the spec. Fixed broken ParentOrElseSampler. * Fixed http-in instrumentation creating Activity objects with invalid parents. Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
1 parent 1758e32 commit 73bff75

File tree

7 files changed

+54
-46
lines changed

7 files changed

+54
-46
lines changed

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

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,25 @@ public override void OnStartActivity(Activity activity, object payload)
6464
// This requires to ignore the current activity and create a new one
6565
// using the context extracted using the format TextFormat supports.
6666
var ctx = this.options.TextFormat.Extract(default, request, HttpRequestHeaderValuesGetter);
67-
68-
// Create a new activity with its parent set from the extracted context.
69-
// This makes the new activity as a "sibling" of the activity created by
70-
// Asp.Net.
71-
Activity newOne = new Activity(ActivityNameByHttpInListener);
72-
newOne.SetParentId(ctx.TraceId, ctx.SpanId, ctx.TraceFlags);
73-
newOne.TraceStateString = ctx.TraceState;
74-
75-
// Starting the new activity make it the Activity.Current one.
76-
newOne.Start();
77-
78-
// Both new activity and old one store the other activity
79-
// inside them. This is required in the Stop step to
80-
// correctly stop and restore Activity.Current.
81-
newOne.SetCustomProperty("ActivityByAspNet", activity);
82-
activity.SetCustomProperty("ActivityByHttpInListener", newOne);
83-
activity = newOne;
67+
if (ctx != default)
68+
{
69+
// Create a new activity with its parent set from the extracted context.
70+
// This makes the new activity as a "sibling" of the activity created by
71+
// Asp.Net.
72+
Activity newOne = new Activity(ActivityNameByHttpInListener);
73+
newOne.SetParentId(ctx.TraceId, ctx.SpanId, ctx.TraceFlags);
74+
newOne.TraceStateString = ctx.TraceState;
75+
76+
// Starting the new activity make it the Activity.Current one.
77+
newOne.Start();
78+
79+
// Both new activity and old one store the other activity
80+
// inside them. This is required in the Stop step to
81+
// correctly stop and restore Activity.Current.
82+
newOne.SetCustomProperty("ActivityByAspNet", activity);
83+
activity.SetCustomProperty("ActivityByHttpInListener", newOne);
84+
activity = newOne;
85+
}
8486
}
8587

8688
// see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,19 @@ public override void OnStartActivity(Activity activity, object payload)
7272
// using the format TextFormat supports.
7373

7474
var ctx = this.options.TextFormat.Extract(default, request, HttpRequestHeaderValuesGetter);
75-
76-
// Create a new activity with its parent set from the extracted context.
77-
// This makes the new activity as a "sibling" of the activity created by
78-
// Asp.Net Core.
79-
Activity newOne = new Activity(ActivityNameByHttpInListener);
80-
newOne.SetParentId(ctx.TraceId, ctx.SpanId, ctx.TraceFlags);
81-
newOne.TraceStateString = ctx.TraceState;
82-
83-
// Starting the new activity make it the Activity.Current one.
84-
newOne.Start();
85-
activity = newOne;
75+
if (ctx != default)
76+
{
77+
// Create a new activity with its parent set from the extracted context.
78+
// This makes the new activity as a "sibling" of the activity created by
79+
// Asp.Net Core.
80+
Activity newOne = new Activity(ActivityNameByHttpInListener);
81+
newOne.SetParentId(ctx.TraceId, ctx.SpanId, ctx.TraceFlags);
82+
newOne.TraceStateString = ctx.TraceState;
83+
84+
// Starting the new activity make it the Activity.Current one.
85+
newOne.Start();
86+
activity = newOne;
87+
}
8688
}
8789

8890
activity.SetKind(ActivityKind.Server);

src/OpenTelemetry/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
disposes the containing exporter.
1313
* `BroadcastActivityProcessor`is disposable and it disposes the processors.
1414
* Samplers now get the actual TraceId of the Activity to be created.
15+
* Default Sampler changed from AlwaysOn to ParentOrElse(AlwaysOn) to match the
16+
spec.
1517

1618
## 0.3.0-beta
1719

src/OpenTelemetry/Sdk.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public static MeterProvider CreateMeterProvider(Action<MeterBuilder> configure)
6464
meterRegistry,
6565
metricProcessor,
6666
metricExporter,
67-
meterBuilder.MetricPushInterval == default(TimeSpan) ? DefaultPushInterval : meterBuilder.MetricPushInterval,
67+
meterBuilder.MetricPushInterval == default ? DefaultPushInterval : meterBuilder.MetricPushInterval,
6868
cancellationTokenSource);
6969

7070
var meterProviderSdk = new MeterProviderSdk(metricProcessor, meterRegistry, controller, cancellationTokenSource);
@@ -85,7 +85,7 @@ public static TracerProvider CreateTracerProvider(Action<TracerProviderBuilder>
8585
configureTracerProviderBuilder?.Invoke(tracerProviderBuilder);
8686

8787
var tracerProviderSdk = new TracerProviderSdk();
88-
Sampler sampler = tracerProviderBuilder.Sampler ?? new AlwaysOnSampler();
88+
Sampler sampler = tracerProviderBuilder.Sampler ?? new ParentOrElseSampler(new AlwaysOnSampler());
8989

9090
ActivityProcessor activityProcessor;
9191
if (tracerProviderBuilder.ProcessingPipelines == null || !tracerProviderBuilder.ProcessingPipelines.Any())
@@ -165,7 +165,8 @@ internal static ActivityDataRequest ComputeActivityDataRequest(
165165
in ActivityCreationOptions<ActivityContext> options,
166166
Sampler sampler)
167167
{
168-
var isRootSpan = options.Parent.SpanId == default;
168+
var isRootSpan = /*TODO: Put back once AutoGenerateRootContextTraceId is removed.
169+
options.Parent.TraceId == default ||*/ options.Parent.SpanId == default;
169170

170171
// As we set ActivityListener.AutoGenerateRootContextTraceId = true,
171172
// Parent.TraceId will always be the TraceId of the to-be-created Activity,

src/OpenTelemetry/Trace/ActivitySourceAdapter.cs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,20 @@ private void RunGetRequestedData(Activity activity)
7676
ActivityContext parentContext;
7777
if (string.IsNullOrEmpty(activity.ParentId))
7878
{
79-
parentContext = default(ActivityContext);
79+
parentContext = default;
80+
}
81+
else if (activity.Parent != null)
82+
{
83+
parentContext = activity.Parent.Context;
8084
}
8185
else
8286
{
83-
if (activity.Parent != null)
84-
{
85-
parentContext = activity.Parent.Context;
86-
}
87-
else
88-
{
89-
parentContext = new ActivityContext(
90-
activity.TraceId,
91-
activity.ParentSpanId,
92-
activity.ActivityTraceFlags,
93-
activity.TraceStateString,
94-
isRemote: true);
95-
}
87+
parentContext = new ActivityContext(
88+
activity.TraceId,
89+
activity.ParentSpanId,
90+
activity.ActivityTraceFlags,
91+
activity.TraceStateString,
92+
isRemote: true);
9693
}
9794

9895
var samplingParameters = new SamplingParameters(

src/OpenTelemetry/Trace/Samplers/ParentOrElseSampler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public ParentOrElseSampler(Sampler delegateSampler)
4141
public override SamplingResult ShouldSample(in SamplingParameters samplingParameters)
4242
{
4343
var parentContext = samplingParameters.ParentContext;
44-
if (parentContext == default)
44+
if (/* TODO: TraceId is always provided due to AutoGenerateRootContextTraceId. That is being removed in RC1 and this can be put back.
45+
parentContext.TraceId == default ||*/ parentContext.SpanId == default)
4546
{
4647
// If no parent, use the delegate to determine sampling.
4748
return this.delegateSampler.ShouldSample(samplingParameters);

test/OpenTelemetry.Instrumentation.Grpc.Tests/GrpcTests.client.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using Moq;
2222
using OpenTelemetry.Instrumentation.Grpc.Tests.Services;
2323
using OpenTelemetry.Trace;
24+
using OpenTelemetry.Trace.Samplers;
2425
using Xunit;
2526

2627
namespace OpenTelemetry.Instrumentation.Grpc.Tests
@@ -44,6 +45,7 @@ public void GrpcClientCallsAreCollectedSuccessfully(string baseAddress)
4445

4546
using (Sdk.CreateTracerProvider(
4647
(builder) => builder
48+
.SetSampler(new AlwaysOnSampler())
4749
.AddGrpcClientInstrumentation()
4850
.SetResource(expectedResource)
4951
.AddProcessorPipeline(p => p.AddProcessor(n => spanProcessor.Object))))
@@ -95,6 +97,7 @@ public void GrpcAndHttpClientInstrumentationIsInvoked()
9597

9698
using (Sdk.CreateTracerProvider(
9799
(builder) => builder
100+
.SetSampler(new AlwaysOnSampler())
98101
.AddHttpClientInstrumentation()
99102
.AddGrpcClientInstrumentation()
100103
.AddProcessorPipeline(p => p.AddProcessor(n => spanProcessor.Object))))

0 commit comments

Comments
 (0)