Skip to content

Commit 9bc3092

Browse files
sophiatevSophia Tevosyan
and
Sophia Tevosyan
authored
Distributed Tracing for Entities (In-Process) (#1190)
* added distributed tracing for entities * change in how the distributed trace context is propagated in the case that an entity in WebJobs starts an orchestration * slight style update * some more tiny style things * addressing two more PR comments * forgot to add one annotation * yet another small style change * addressing PR comments * forgot one file * addressing more PR comments * forgot two comments * addressing a few small comments * refactored most of the tracing into this repo to more accurately reflect the end time of activites (like, when the call/signal request to an entity is actually sent, or when an orchestration is actually created by an entity) * fixing spacing * slight change in formatting of the create orchestration trace * addressing PR comments * adding back new lines at the ends of files * trying to fix these line endings * dealing with new lines again * tiny change * missed a null check * reverting to old design * missed some * and missed some more * missed even more * will it ever end * last one i think * moved activity for entity starting an orchestration back into webjobs * as always missed some stuff * added support for an entities enabled flag * added a null check for client span ID when creating the activity for scheduling a suborchestration * getting rid of an extra line * addressing PR comment * addressing a few PR comments * addressing some PR comments, slightly changing the logic of the modified TaskHubClient method --------- Co-authored-by: Sophia Tevosyan <[email protected]>
1 parent a5bee07 commit 9bc3092

File tree

4 files changed

+65
-7
lines changed

4 files changed

+65
-7
lines changed

src/DurableTask.Core/OrchestrationTags.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ public static class OrchestrationTags
3636
/// </remarks>
3737
public const string FireAndForget = "FireAndForget";
3838

39+
/// <summary>
40+
/// The ID of the parent trace that created this orchestration instance (see https://www.w3.org/TR/trace-context/#traceparent-header)
41+
/// </summary>
42+
public const string TraceParent = "MS_Entities_TraceParent";
43+
44+
/// <summary>
45+
/// The trace state of the parent trace that created this orchestration instance (see https://www.w3.org/TR/trace-context/#tracestate-header)
46+
/// </summary>
47+
public const string TraceState = "MS_Entities_TraceState";
48+
3949
/// <summary>
4050
/// Check whether the given tags contain the fire and forget tag
4151
/// </summary>

src/DurableTask.Core/TaskHubClient.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,19 @@ void CreateAndTrackDependencyTelemetry(TraceContextBase? requestTraceContext)
746746
/// <param name="eventName">Name of the event</param>
747747
/// <param name="eventData">Data for the event</param>
748748
public async Task RaiseEventAsync(OrchestrationInstance orchestrationInstance, string eventName, object eventData)
749+
{
750+
await this.RaiseEventAsync(orchestrationInstance, eventName, eventData, emitTraceActivity: true);
751+
}
752+
753+
/// <summary>
754+
/// Raises an event in the specified orchestration instance, which eventually causes the OnEvent() method in the
755+
/// orchestration to fire.
756+
/// </summary>
757+
/// <param name="orchestrationInstance">Instance in which to raise the event</param>
758+
/// <param name="eventName">Name of the event</param>
759+
/// <param name="eventData">Data for the event</param>
760+
/// <param name="emitTraceActivity">Whether or not to emit a trace activity for this event.</param>
761+
public async Task RaiseEventAsync(OrchestrationInstance orchestrationInstance, string eventName, object eventData, bool emitTraceActivity = true)
749762
{
750763

751764
if (string.IsNullOrWhiteSpace(orchestrationInstance.InstanceId))
@@ -757,7 +770,11 @@ public async Task RaiseEventAsync(OrchestrationInstance orchestrationInstance, s
757770

758771
// Distributed Tracing
759772
EventRaisedEvent eventRaisedEvent = new EventRaisedEvent(-1, serializedInput) { Name = eventName };
760-
using Activity? traceActivity = TraceHelper.StartActivityForNewEventRaisedFromClient(eventRaisedEvent, orchestrationInstance);
773+
Activity? traceActivity = null;
774+
if (emitTraceActivity)
775+
{
776+
traceActivity = TraceHelper.StartActivityForNewEventRaisedFromClient(eventRaisedEvent, orchestrationInstance);
777+
}
761778

762779
var taskMessage = new TaskMessage
763780
{
@@ -776,6 +793,10 @@ public async Task RaiseEventAsync(OrchestrationInstance orchestrationInstance, s
776793
TraceHelper.AddErrorDetailsToSpan(traceActivity, e);
777794
throw;
778795
}
796+
finally
797+
{
798+
traceActivity?.Dispose();
799+
}
779800
}
780801

781802
/// <summary>

src/DurableTask.Core/TaskOrchestrationDispatcher.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ public async Task StopAsync(bool forced)
116116
/// </summary>
117117
public bool IncludeParameters { get; set; }
118118

119+
/// <summary>
120+
/// Gets or sets the flag for whether or not entities are enabled
121+
/// </summary>
122+
public bool EntitiesEnabled { get; set; }
123+
119124
/// <summary>
120125
/// Method to get the next work item to process within supplied timeout
121126
/// </summary>
@@ -1143,9 +1148,6 @@ TaskMessage ProcessCreateSubOrchestrationInstanceDecision(
11431148
historyEvent.Input = createSubOrchestrationAction.Input;
11441149
}
11451150

1146-
ActivitySpanId clientSpanId = ActivitySpanId.CreateRandom();
1147-
historyEvent.ClientSpanId = clientSpanId.ToString();
1148-
11491151
runtimeState.AddEvent(historyEvent);
11501152

11511153
var taskMessage = new TaskMessage();
@@ -1169,8 +1171,22 @@ TaskMessage ProcessCreateSubOrchestrationInstanceDecision(
11691171
Version = createSubOrchestrationAction.Version
11701172
};
11711173

1172-
if (parentTraceActivity != null)
1174+
// If a parent trace context was provided via the CreateSubOrchestrationAction.Tags, we will use this as the parent trace context of the suborchestration execution Activity rather than Activity.Current.Context.
1175+
if (createSubOrchestrationAction.Tags != null
1176+
&& createSubOrchestrationAction.Tags.TryGetValue(OrchestrationTags.TraceParent, out string traceParent))
1177+
{
1178+
// If a parent trace context was provided but we fail to parse it, we don't want to attach any parent trace context to the start event since that will incorrectly link the trace corresponding to the orchestration execution
1179+
// as a child of Activity.Current, which is not truly the parent of the request
1180+
if (createSubOrchestrationAction.Tags.TryGetValue(OrchestrationTags.TraceState, out string traceState)
1181+
&& ActivityContext.TryParse(traceParent, traceState, out ActivityContext parentTraceContext))
1182+
{
1183+
startedEvent.SetParentTraceContext(parentTraceContext);
1184+
}
1185+
}
1186+
else if (parentTraceActivity != null)
11731187
{
1188+
ActivitySpanId clientSpanId = ActivitySpanId.CreateRandom();
1189+
historyEvent.ClientSpanId = clientSpanId.ToString();
11741190
ActivityContext activityContext = new ActivityContext(parentTraceActivity.TraceId, clientSpanId, parentTraceActivity.ActivityTraceFlags, parentTraceActivity.TraceStateString);
11751191
startedEvent.SetParentTraceContext(activityContext);
11761192
}
@@ -1204,7 +1220,7 @@ TaskMessage ProcessSendEventDecision(
12041220

12051221
// Distributed Tracing: start a new trace activity derived from the orchestration
12061222
// for an EventRaisedEvent (external event)
1207-
using Activity? traceActivity = TraceHelper.StartTraceActivityForEventRaisedFromWorker(eventRaisedEvent, runtimeState.OrchestrationInstance, sendEventAction.Instance?.InstanceId);
1223+
using Activity? traceActivity = TraceHelper.StartTraceActivityForEventRaisedFromWorker(eventRaisedEvent, runtimeState.OrchestrationInstance, this.EntitiesEnabled, sendEventAction.Instance?.InstanceId);
12081224

12091225
this.logHelper.RaisingEvent(runtimeState.OrchestrationInstance!, historyEvent);
12101226

src/DurableTask.Core/Tracing/TraceHelper.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,10 @@ internal static void EmitTraceActivityForTaskFailed(
284284
return null;
285285
}
286286

287-
activity.SetSpanId(createdEvent.ClientSpanId);
287+
if (!string.IsNullOrEmpty(createdEvent.ClientSpanId))
288+
{
289+
activity.SetSpanId(createdEvent.ClientSpanId);
290+
}
288291

289292
activity.SetTag(Schema.Task.Type, TraceActivityConstants.Orchestration);
290293
activity.SetTag(Schema.Task.Name, createdEvent.Name);
@@ -348,15 +351,23 @@ internal static void EmitTraceActivityForSubOrchestrationFailed(
348351
/// </summary>
349352
/// <param name="eventRaisedEvent">The associated <see cref="EventRaisedEvent"/>.</param>
350353
/// <param name="instance">The associated <see cref="OrchestrationInstance"/>.</param>
354+
/// <param name="entitiesEnabled">Whether or not entities are enabled, meaning this event could possibly correspond to entity.</param>
351355
/// <param name="targetInstanceId">The instance id of the orchestration that will receive the event.</param>
352356
/// <returns>
353357
/// Returns a newly started <see cref="Activity"/> with (task) activity and orchestration-specific metadata.
354358
/// </returns>
355359
internal static Activity? StartTraceActivityForEventRaisedFromWorker(
356360
EventRaisedEvent eventRaisedEvent,
357361
OrchestrationInstance? instance,
362+
bool entitiesEnabled,
358363
string? targetInstanceId)
359364
{
365+
// We don't want to emit tracing for external events when they are related to entities
366+
if (entitiesEnabled && (Entities.IsEntityInstance(targetInstanceId ?? string.Empty) || Entities.IsEntityInstance(instance?.InstanceId ?? string.Empty)))
367+
{
368+
return null;
369+
}
370+
360371
Activity? newActivity = ActivityTraceSource.StartActivity(
361372
CreateSpanName(TraceActivityConstants.OrchestrationEvent, eventRaisedEvent.Name, null),
362373
kind: ActivityKind.Producer,

0 commit comments

Comments
 (0)