Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
- .NET on iOS: Add experimental EnableAppHangTrackingV2 configuration flag to the options binding SDK ([#3877](https://github.com/getsentry/sentry-dotnet/pull/3877))
- Added `SentryOptions.DisableSentryHttpMessageHandler`. Useful if you're using `OpenTelemetry.Instrumentation.Http` and ending up with duplicate spans. ([#3879](https://github.com/getsentry/sentry-dotnet/pull/3879))

### Fixes

- OTel activities that are marked as not recorded are no longer sent to Sentry ([#3890](https://github.com/getsentry/sentry-dotnet/pull/3890))

## 5.0.1

### Fixes
Expand Down
8 changes: 8 additions & 0 deletions src/Sentry.OpenTelemetry/SentrySpanProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ public override void OnEnd(Activity data)
return;
}

// Skip any activities that are not recorded.
if (data is { Recorded: false, IsAllDataRequested: false })
{
_options?.DiagnosticLogger?.LogDebug($"Ignoring unrecorded Activity {data.SpanId}.");
_map.TryRemove(data.SpanId, out _);
return;
}

// Make a dictionary of the attributes (aka "tags") for faster lookup when used throughout the processor.
var attributes = data.TagObjects.ToDict();

Expand Down
82 changes: 82 additions & 0 deletions test/Sentry.OpenTelemetry.Tests/SentrySpanProcessorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,88 @@ public void OnEnd_FinishesTransaction()
}
}

[Fact]
public void OnEnd_FilteredTransaction_DoesNotFinishTransaction()
{
// Arrange
_fixture.Options.Instrumenter = Instrumenter.OpenTelemetry;
var sut = _fixture.GetSut();

var parent = Tracer.StartActivity("transaction")!;
sut.OnStart(parent);

var data = Tracer.StartActivity("test operation", kind: ActivityKind.Internal)!;
data.DisplayName = "test display name";
sut.OnStart(data);

FilterActivity(parent);

sut._map.TryGetValue(parent.SpanId, out var span);

// Act
sut.OnEnd(data);
sut.OnEnd(parent);

// Assert
if (span is not TransactionTracer transaction)
{
Assert.Fail("Span is not a transaction tracer");
return;
}

using (new AssertionScope())
{
transaction.EndTimestamp.Should().BeNull();
transaction.Status.Should().BeNull();
}
}

[Fact]
public void OnEnd_FilteredSpan_RemovesSpan()
{
// Arrange
_fixture.Options.Instrumenter = Instrumenter.OpenTelemetry;
var sut = _fixture.GetSut();

var parent = Tracer.StartActivity("transaction")!;
sut.OnStart(parent);

var data = Tracer.StartActivity("test operation", kind: ActivityKind.Internal)!;
data.DisplayName = "test display name";
sut.OnStart(data);

FilterActivity(data);

sut._map.TryGetValue(parent.SpanId, out var parentSpan);
sut._map.TryGetValue(data.SpanId, out var childSpan);

// Act
sut.OnEnd(data);
sut.OnEnd(parent);

// Assert
if (parentSpan is not TransactionTracer transaction)
{
Assert.Fail("parentSpan is not a transaction tracer");
return;
}
if (childSpan is not SpanTracer span)
{
Assert.Fail("span is not a span tracer");
return;
}

using (new AssertionScope())
{
span.EndTimestamp.Should().BeNull();
span.Status.Should().BeNull();

transaction.EndTimestamp.Should().NotBeNull();
transaction.Status.Should().Be(SpanStatus.Ok);
transaction.Spans.Should().BeEmpty();
}
}

[Theory]
[InlineData(OtelSemanticConventions.AttributeUrlFull)]
[InlineData(OtelSemanticConventions.AttributeHttpUrl)]
Expand Down
Loading