-
Notifications
You must be signed in to change notification settings - Fork 784
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add start/stop OpCodes to SdkEventSource ActivityStart/Stop events
Renamed ActivityStarted/Stopped to ActivityStart/Stop Add tests Prevent concurrent execution of EventSource tests
- Loading branch information
Showing
5 changed files
with
132 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
test/OpenTelemetry.Tests/Internal/SdkEventSourceTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
#nullable enable | ||
|
||
using System.Diagnostics; | ||
using System.Diagnostics.Tracing; | ||
using OpenTelemetry.Internal; | ||
using OpenTelemetry.Trace; | ||
using Xunit; | ||
|
||
namespace OpenTelemetry.Tests.Internal; | ||
|
||
[Collection("Uses-OpenTelemetrySdkEventSource")] // Prevent parallel execution with other tests that exercise the SdkEventSource | ||
public class SdkEventSourceTest : IDisposable | ||
{ | ||
private readonly SdkEventListener listener = new(); | ||
|
||
public void Dispose() | ||
{ | ||
this.listener.Dispose(); | ||
} | ||
|
||
[Fact] | ||
public void ActivityStartUsesOpCodeStart() | ||
{ | ||
using (TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() | ||
.AddSource("TestSource") | ||
.Build()) | ||
{ | ||
// Clear any events that were emitted during Build. | ||
this.listener.Events.Clear(); | ||
|
||
const int numActivities = 4; | ||
|
||
using ActivitySource activitySource = new("TestSource"); | ||
for (int i = 0; i < numActivities; i++) | ||
{ | ||
using Activity? activity = activitySource.StartActivity($"Test Activity {i}"); | ||
} | ||
|
||
// There should be 2 events for each activity: ActivityStart and ActivityStop. | ||
Assert.Equal(numActivities * 2, this.listener.Events.Count); | ||
|
||
HashSet<Guid> activityIds = []; | ||
for (int i = 0; i < numActivities; i++) | ||
{ | ||
EventWrittenEventArgs startEvent = this.listener.Events[i * 2]; | ||
EventWrittenEventArgs stopEvent = this.listener.Events[(i * 2) + 1]; | ||
|
||
Assert.Equal(nameof(OpenTelemetrySdkEventSource.ActivityStart), startEvent.EventName); | ||
Assert.Equal(nameof(OpenTelemetrySdkEventSource.ActivityStop), stopEvent.EventName); | ||
|
||
// Start and Stop should be matched on ActivityId. | ||
Assert.Equal(startEvent.ActivityId, stopEvent.ActivityId); | ||
|
||
// ActivityIds should be unique. | ||
Assert.True(activityIds.Add(startEvent.ActivityId)); | ||
} | ||
} | ||
} | ||
|
||
private sealed class SdkEventListener : EventListener | ||
{ | ||
private static readonly string SdkEventSourceName = EventSource.GetName(typeof(OpenTelemetrySdkEventSource)); | ||
private readonly HashSet<EventSource> eventSourcesEnabled = []; | ||
|
||
public List<EventWrittenEventArgs> Events { get; } = []; | ||
|
||
public override void Dispose() | ||
{ | ||
try | ||
{ | ||
foreach (EventSource eventSource in this.eventSourcesEnabled) | ||
{ | ||
this.DisableEvents(eventSource); | ||
} | ||
} | ||
finally | ||
{ | ||
base.Dispose(); | ||
} | ||
} | ||
|
||
protected override void OnEventSourceCreated(EventSource eventSource) | ||
{ | ||
if (eventSource.Name == SdkEventSourceName) | ||
{ | ||
this.eventSourcesEnabled.Add(eventSource); | ||
this.EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All); | ||
} | ||
else if (eventSource.Name == "System.Threading.Tasks.TplEventSource") | ||
{ | ||
// In addition to the OpenTelemetrySdkEventSource we need | ||
// the TPL EventSource to enable activity tracking. When | ||
// enabled and an EventSource writes events with | ||
// EventOpCode.Start/Stop, then the ActivityTracker will | ||
// generate new path-like ActivityIDs. | ||
// Also note that activity tracking requires that the | ||
// Start/Stop events are a matched pair, named like | ||
// "xyzStart" and "xyzStop". ActivityTracker matches the | ||
// stop event with the start event by recognizing those | ||
// exact suffixes. | ||
this.eventSourcesEnabled.Add(eventSource); | ||
const EventKeywords taskFlowActivityIds = (EventKeywords)0x80; | ||
this.EnableEvents(eventSource, EventLevel.Informational, taskFlowActivityIds); | ||
} | ||
|
||
base.OnEventSourceCreated(eventSource); | ||
} | ||
|
||
protected override void OnEventWritten(EventWrittenEventArgs eventData) | ||
{ | ||
if (eventData.EventSource.Name == SdkEventSourceName) | ||
{ | ||
this.Events.Add(eventData); | ||
} | ||
|
||
base.OnEventWritten(eventData); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters