@@ -62,6 +62,13 @@ public interface IExecutionContext : IAgentService, IKnobValueContext
6262 void QueueAttachFile ( string type , string name , string filePath ) ;
6363 ITraceWriter GetTraceWriter ( ) ;
6464
65+ // correlation context for enhanced tracing
66+ void SetCorrelationStep ( string stepId ) ;
67+ void ClearCorrelationStep ( ) ;
68+ void SetCorrelationTask ( string taskId ) ;
69+ void ClearCorrelationTask ( ) ;
70+ string BuildCorrelationId ( ) ;
71+
6572 // timeline record update methods
6673 void Start ( string currentOperation = null ) ;
6774 TaskResult Complete ( TaskResult ? result = null , string currentOperation = null , string resultCode = null ) ;
@@ -92,7 +99,7 @@ public interface IExecutionContext : IAgentService, IKnobValueContext
9299 void PublishTaskRunnerTelemetry ( Dictionary < string , string > taskRunnerData ) ;
93100 }
94101
95- public sealed class ExecutionContext : AgentService , IExecutionContext , IDisposable
102+ public sealed class ExecutionContext : AgentService , IExecutionContext , ICorrelationContext , IDisposable
96103 {
97104 private const int _maxIssueCount = 10 ;
98105
@@ -103,6 +110,8 @@ public sealed class ExecutionContext : AgentService, IExecutionContext, IDisposa
103110 private readonly HashSet < string > _outputvariables = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
104111 private readonly List < TaskRestrictions > _restrictions = new List < TaskRestrictions > ( ) ;
105112 private readonly string _buildLogsFolderName = "buildlogs" ;
113+ private readonly AsyncLocal < string > _correlationStep = new AsyncLocal < string > ( ) ;
114+ private readonly AsyncLocal < string > _correlationTask = new AsyncLocal < string > ( ) ;
106115 private IAgentLogPlugin _logPlugin ;
107116 private IPagingLogger _logger ;
108117 private IJobServerQueue _jobServerQueue ;
@@ -200,6 +209,9 @@ public override void Initialize(IHostContext hostContext)
200209 }
201210
202211 _jobServerQueue = HostContext . GetService < IJobServerQueue > ( ) ;
212+
213+ // Register this ExecutionContext for enhanced correlation
214+ HostContext . CorrelationContextManager . SetCurrentExecutionContext ( this ) ;
203215 }
204216
205217 public void CancelToken ( )
@@ -982,8 +994,68 @@ public void PublishTaskRunnerTelemetry(Dictionary<string, string> taskRunnerData
982994 PublishTelemetry ( taskRunnerData , IsAgentTelemetry : true ) ;
983995 }
984996
997+ // Correlation context methods for enhanced tracing
998+ public void SetCorrelationStep ( string stepId )
999+ {
1000+ _correlationStep . Value = stepId ;
1001+ }
1002+
1003+ public void ClearCorrelationStep ( )
1004+ {
1005+ _correlationStep . Value = null ;
1006+ }
1007+
1008+ public void SetCorrelationTask ( string taskId )
1009+ {
1010+ _correlationTask . Value = taskId ;
1011+ }
1012+
1013+ public void ClearCorrelationTask ( )
1014+ {
1015+ _correlationTask . Value = null ;
1016+ }
1017+
1018+ public string BuildCorrelationId ( )
1019+ {
1020+ var step = _correlationStep . Value ;
1021+ var task = _correlationTask . Value ;
1022+
1023+ if ( string . IsNullOrEmpty ( step ) )
1024+ {
1025+ return string . IsNullOrEmpty ( task ) ? string . Empty : $ "TASK-{ ShortenGuid ( task ) } ";
1026+ }
1027+
1028+ return string . IsNullOrEmpty ( task ) ? $ "STEP-{ ShortenGuid ( step ) } " : $ "STEP-{ ShortenGuid ( step ) } |TASK-{ ShortenGuid ( task ) } ";
1029+ }
1030+
1031+ /// <summary>
1032+ /// Shorten a GUID to first 12 characters for more readable logs while maintaining uniqueness
1033+ /// </summary>
1034+ private static string ShortenGuid ( string guid )
1035+ {
1036+ if ( string . IsNullOrEmpty ( guid ) )
1037+ return guid ;
1038+
1039+ // Use first 12 characters total: 8 from first segment + 4 from second segment
1040+ // This ensures consistent output length regardless of input length
1041+ // e.g., "verylongstring-1234..." becomes "verylong1234" (12 chars)
1042+ // e.g., "60cf5508-70a7-..." becomes "60cf550870a7" (12 chars)
1043+ var parts = guid . Split ( '-' ) ;
1044+ if ( parts . Length >= 2 && parts [ 0 ] . Length >= 8 && parts [ 1 ] . Length >= 4 )
1045+ {
1046+ return parts [ 0 ] . Substring ( 0 , 8 ) + parts [ 1 ] . Substring ( 0 , 4 ) ;
1047+ }
1048+
1049+ // Fallback: remove hyphens and take first 12 chars
1050+ var cleaned = guid . Replace ( "-" , "" ) ;
1051+ return cleaned . Length > 12 ? cleaned . Substring ( 0 , 12 ) : cleaned ;
1052+ }
1053+
9851054 public void Dispose ( )
9861055 {
1056+ // Clear the correlation context registration
1057+ HostContext . CorrelationContextManager . ClearCurrentExecutionContext ( ) ;
1058+
9871059 _cancellationTokenSource ? . Dispose ( ) ;
9881060 _forceCompleteCancellationTokenSource ? . Dispose ( ) ;
9891061
0 commit comments