Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,10 @@ public class OrchestrationCompleteOrchestratorAction : OrchestratorAction
/// Gets a list of events that should be carried over when continuing an orchestration as new.
/// </summary>
public IList<HistoryEvent> CarryoverEvents { get; } = new List<HistoryEvent>();

/// <summary>
/// Gets a collection of tags associated with the completion action.
/// </summary>
public IDictionary<string, string> Tags { get; } = new Dictionary<string, string>();
}
}
2 changes: 2 additions & 0 deletions src/DurableTask.Core/Logging/EventIds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,7 @@ static class EventIds
public const int RenewOrchestrationWorkItemFailed = 72;

public const int OrchestrationDebugTrace = 73;

public const int OrchestrationCompletedWithWarning = 74;
}
}
48 changes: 48 additions & 0 deletions src/DurableTask.Core/Logging/LogEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,54 @@ void IEventSourceEvent.WriteEventSource() =>
}
#nullable disable

/// <summary>
/// Log event representing a warning associated with an orchestration completing.
/// </summary>
internal class OrchestrationCompletedWithWarning : StructuredLogEvent, IEventSourceEvent
{

public OrchestrationCompletedWithWarning(
OrchestrationInstance instance,
string orchestrationStatus,
string warningMessage)
{
this.InstanceId = instance.InstanceId;
this.ExecutionId = instance.ExecutionId;
this.RuntimeStatus = orchestrationStatus;
this.Details = warningMessage;
}

[StructuredLogField]
public string InstanceId { get; }

[StructuredLogField]
public string ExecutionId { get; }

[StructuredLogField]
public string RuntimeStatus { get; }

[StructuredLogField]
public string Details { get; }

public override EventId EventId => new EventId(
EventIds.OrchestrationCompletedWithWarning,
nameof(EventIds.OrchestrationCompletedWithWarning));

public override LogLevel Level => LogLevel.Warning;

protected override string CreateLogMessage() =>
$"{this.InstanceId}: Orchestration completed with warning: {this.Details}";

void IEventSourceEvent.WriteEventSource() =>
StructuredEventSource.Log.OrchestrationCompletedWithWarning(
this.InstanceId,
this.ExecutionId,
this.RuntimeStatus,
this.Details,
Utils.AppName,
Utils.PackageVersion);
}

/// <summary>
/// Log event representing an orchestration aborted event, which can happen if the host is shutting down.
/// </summary>
Expand Down
17 changes: 17 additions & 0 deletions src/DurableTask.Core/Logging/LogHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,23 @@ internal void OrchestrationCompleted(
}
}

/// <summary>
/// Logs a warning associated with an orchestration completing.
/// </summary>
/// <param name="instance">The orchestration instance of the orchestration.</param>
/// <param name="orchestrationStatus">The status of the completed orchestration.</param>
/// <param name="warningMessage">The warning message to log.</param>
internal void OrchestrationCompletedWithWarning(
OrchestrationInstance instance,
OrchestrationStatus orchestrationStatus,
string warningMessage)
{
if (this.IsStructuredLoggingEnabled)
{
this.WriteStructuredLog(new LogEvents.OrchestrationCompletedWithWarning(instance, orchestrationStatus.ToString(), warningMessage));
}
}

/// <summary>
/// Logs that an orchestration execution was aborted.
/// </summary>
Expand Down
23 changes: 23 additions & 0 deletions src/DurableTask.Core/Logging/StructuredEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,29 @@ internal void OrchestrationCompleted(
}
}

[Event(EventIds.OrchestrationCompletedWithWarning, Level = EventLevel.Warning, Version = 1)]
internal void OrchestrationCompletedWithWarning(
string InstanceId,
string ExecutionId,
string RuntimeStatus,
string Details,
string AppName,
string ExtensionVersion)
{
if (this.IsEnabled(EventLevel.Warning))
{
// TODO: Use WriteEventCore for better performance
this.WriteEvent(
EventIds.OrchestrationCompletedWithWarning,
InstanceId,
ExecutionId,
RuntimeStatus,
Details,
AppName,
ExtensionVersion);
}
}

[Event(EventIds.OrchestrationAborted, Level = EventLevel.Warning, Version = 1)]
internal void OrchestrationAborted(
string InstanceId,
Expand Down
5 changes: 5 additions & 0 deletions src/DurableTask.Core/OrchestrationTags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public static class OrchestrationTags
/// </summary>
public const string CreateTraceForNewOrchestration = "MS_CreateTrace";

/// <summary>
/// The warning logged when an orchestration completes, if any.
/// </summary>
public const string CompleteOrchestrationLogWarning = "MS_CompleteOrchestrationLogWarning";

/// <summary>
/// Check whether the given tags contain the fire and forget tag
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/DurableTask.Core/TaskOrchestrationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,12 @@ public void CompleteOrchestration(string result, string details, OrchestrationSt
completedOrchestratorAction.Details = details;
completedOrchestratorAction.OrchestrationStatus = orchestrationStatus;
completedOrchestratorAction.FailureDetails = failureDetails;

if (this.continueAsNew != null && orchestrationStatus == OrchestrationStatus.Failed)
{
completedOrchestratorAction.Tags[OrchestrationTags.CompleteOrchestrationLogWarning] =
"Continue as new called for a failed orchestration, orchestration will complete.";
}
}

completedOrchestratorAction.Id = id;
Expand Down
4 changes: 4 additions & 0 deletions src/DurableTask.Core/TaskOrchestrationDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,10 @@ internal static bool ReconcileMessagesWithState(TaskOrchestrationWorkItem workIt

runtimeState.AddEvent(executionCompletedEvent);

if (completeOrchestratorAction.Tags.TryGetValue(OrchestrationTags.CompleteOrchestrationLogWarning, out string warningMessage))
{
this.logHelper.OrchestrationCompletedWithWarning(runtimeState.OrchestrationInstance!, completeOrchestratorAction.OrchestrationStatus, warningMessage);
}
this.logHelper.OrchestrationCompleted(runtimeState, completeOrchestratorAction);
TraceHelper.TraceInstance(
runtimeState.OrchestrationStatus == OrchestrationStatus.Failed ? TraceEventType.Warning : TraceEventType.Information,
Expand Down
Loading