using System.Diagnostics; using Elsa.OpenTelemetry.Helpers; using Elsa.Workflows; using Elsa.Workflows.Contracts; using Elsa.Workflows.Pipelines.WorkflowExecution; using JetBrains.Annotations; using Activity = System.Diagnostics.Activity; using ActivityKind = System.Diagnostics.ActivityKind; namespace Elsa.OpenTelemetry.Middleware; /// /// Middleware that traces workflow execution using OpenTelemetry. /// [UsedImplicitly] public class OpenTelemetryTracingWorkflowExecutionMiddleware(WorkflowMiddlewareDelegate next) : WorkflowExecutionMiddleware(next) { /// public override async ValueTask InvokeAsync(WorkflowExecutionContext context) { var workflowInstanceId = context.Id; var workflow = context.Workflow; using var activity = ElsaOpenTelemetry.ActivitySource.StartActivity($"WorkflowExecution {workflow.WorkflowMetadata.Name}", ActivityKind.Internal, Activity.Current?.Context ?? default); if(!string.IsNullOrWhiteSpace(context.CorrelationId)) activity?.AddTag("correlationId", context.CorrelationId); activity?.AddTag("workflowInstance.id", workflowInstanceId); activity?.AddTag("workflowDefinition.definitionId", workflow.Identity.DefinitionId); activity?.AddTag("workflowDefinition.version", workflow.Identity.Version); activity?.AddTag("workflowInstance.originalStatus", context.Status.ToString()); activity?.AddTag("workflowInstance.originalSubStatus", context.SubStatus.ToString()); activity?.AddEvent(new ActivityEvent("Executing")); await Next(context); activity?.AddEvent(new ActivityEvent("Executed")); activity?.AddTag("workflowInstance.newStatus", context.Status.ToString()); activity?.AddTag("workflowInstance.newSubStatus", context.SubStatus.ToString()); } } /// /// Contains extension methods for . /// [UsedImplicitly] public static class OpenTelemetryWorkflowExecutionMiddlewareExtensions { /// Installs the component in the workflow execution pipeline. public static IWorkflowExecutionPipelineBuilder UseWorkflowExecutionTracing(this IWorkflowExecutionPipelineBuilder pipelineBuilder) => pipelineBuilder.Insert(0); }