Skip to content

Commit cb19da9

Browse files
authored
Move JobTelemetry and StepsTelemetry into GlobalContext. (#1680)
* Move JobTelemetry and StepsTelemetry into GlobalContext. * . * .
1 parent d641909 commit cb19da9

10 files changed

+146
-116
lines changed

src/Runner.Worker/ActionCommandManager.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private void ValidateStopToken(IExecutionContext context, string stopToken)
178178
Message = $"Invoked ::stopCommand:: with token: [{stopToken}]",
179179
Type = JobTelemetryType.ActionCommand
180180
};
181-
context.JobTelemetry.Add(telemetry);
181+
context.Global.JobTelemetry.Add(telemetry);
182182
}
183183

184184
if (isTokenInvalid && !allowUnsecureStopCommandTokens)

src/Runner.Worker/ExecutionContext.cs

+54-14
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
using GitHub.DistributedTask.Pipelines.ContextData;
1616
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
1717
using GitHub.DistributedTask.WebApi;
18-
using GitHub.Runner.Common.Util;
1918
using GitHub.Runner.Common;
19+
using GitHub.Runner.Common.Util;
2020
using GitHub.Runner.Sdk;
2121
using GitHub.Runner.Worker.Container;
2222
using GitHub.Services.WebApi;
@@ -52,8 +52,7 @@ public interface IExecutionContext : IRunnerService
5252
Dictionary<string, string> IntraActionState { get; }
5353
Dictionary<string, VariableValue> JobOutputs { get; }
5454
ActionsEnvironmentReference ActionsEnvironment { get; }
55-
List<ActionsStepTelemetry> ActionsStepsTelemetry { get; }
56-
List<JobTelemetry> JobTelemetry { get; }
55+
ActionsStepTelemetry StepTelemetry { get; }
5756
DictionaryContextData ExpressionValues { get; }
5857
IList<IFunctionInfo> ExpressionFunctions { get; }
5958
JobContext JobContext { get; }
@@ -109,6 +108,7 @@ public interface IExecutionContext : IRunnerService
109108
// others
110109
void ForceTaskComplete();
111110
void RegisterPostJobStep(IStep step);
111+
void PublishStepTelemetry();
112112
}
113113

114114
public sealed class ExecutionContext : RunnerService, IExecutionContext
@@ -139,6 +139,7 @@ public sealed class ExecutionContext : RunnerService, IExecutionContext
139139

140140
// only job level ExecutionContext will track throttling delay.
141141
private long _totalThrottlingDelayInMilliseconds = 0;
142+
private bool _stepTelemetryPublished = false;
142143

143144
public Guid Id => _record.Id;
144145
public Guid EmbeddedId { get; private set; }
@@ -152,8 +153,7 @@ public sealed class ExecutionContext : RunnerService, IExecutionContext
152153
public Dictionary<string, VariableValue> JobOutputs { get; private set; }
153154

154155
public ActionsEnvironmentReference ActionsEnvironment { get; private set; }
155-
public List<ActionsStepTelemetry> ActionsStepsTelemetry { get; private set; }
156-
public List<JobTelemetry> JobTelemetry { get; private set; }
156+
public ActionsStepTelemetry StepTelemetry { get; } = new ActionsStepTelemetry();
157157
public DictionaryContextData ExpressionValues { get; } = new DictionaryContextData();
158158
public IList<IFunctionInfo> ExpressionFunctions { get; } = new List<IFunctionInfo>();
159159

@@ -273,9 +273,9 @@ public void RegisterPostJobStep(IStep step)
273273
{
274274
Trace.Info($"'post' of '{actionRunner.DisplayName}' already push to child post step stack.");
275275
}
276-
else
276+
else
277277
{
278-
Root.EmbeddedStepsWithPostRegistered[actionRunner.Action.Id] = actionRunner.Condition;
278+
Root.EmbeddedStepsWithPostRegistered[actionRunner.Action.Id] = actionRunner.Condition;
279279
}
280280
return;
281281
}
@@ -294,7 +294,20 @@ public void RegisterPostJobStep(IStep step)
294294
Root.PostJobSteps.Push(step);
295295
}
296296

297-
public IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, ActionRunStage stage, Dictionary<string, string> intraActionState = null, int? recordOrder = null, IPagingLogger logger = null, bool isEmbedded = false, CancellationTokenSource cancellationTokenSource = null, Guid embeddedId = default(Guid), string siblingScopeName = null)
297+
public IExecutionContext CreateChild(
298+
Guid recordId,
299+
string displayName,
300+
string refName,
301+
string scopeName,
302+
string contextName,
303+
ActionRunStage stage,
304+
Dictionary<string, string> intraActionState = null,
305+
int? recordOrder = null,
306+
IPagingLogger logger = null,
307+
bool isEmbedded = false,
308+
CancellationTokenSource cancellationTokenSource = null,
309+
Guid embeddedId = default(Guid),
310+
string siblingScopeName = null)
298311
{
299312
Trace.Entering();
300313

@@ -306,7 +319,6 @@ public void RegisterPostJobStep(IStep step)
306319
child.Stage = stage;
307320
child.EmbeddedId = embeddedId;
308321
child.SiblingScopeName = siblingScopeName;
309-
child.JobTelemetry = JobTelemetry;
310322
if (intraActionState == null)
311323
{
312324
child.IntraActionState = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
@@ -354,7 +366,13 @@ public void RegisterPostJobStep(IStep step)
354366
/// An embedded execution context shares the same record ID, record name, logger,
355367
/// and a linked cancellation token.
356368
/// </summary>
357-
public IExecutionContext CreateEmbeddedChild(string scopeName, string contextName, Guid embeddedId, ActionRunStage stage, Dictionary<string, string> intraActionState = null, string siblingScopeName = null)
369+
public IExecutionContext CreateEmbeddedChild(
370+
string scopeName,
371+
string contextName,
372+
Guid embeddedId,
373+
ActionRunStage stage,
374+
Dictionary<string, string> intraActionState = null,
375+
string siblingScopeName = null)
358376
{
359377
return Root.CreateChild(_record.Id, _record.Name, _record.Id.ToString("N"), scopeName, contextName, stage, logger: _logger, isEmbedded: true, cancellationTokenSource: CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token), intraActionState: intraActionState, embeddedId: embeddedId, siblingScopeName: siblingScopeName);
360378
}
@@ -404,6 +422,8 @@ public TaskResult Complete(TaskResult? result = null, string currentOperation =
404422
}
405423
}
406424

425+
PublishStepTelemetry();
426+
407427
if (Root != this)
408428
{
409429
// only dispose TokenSource for step level ExecutionContext
@@ -654,16 +674,18 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation
654674
// Job defaults shared across all actions
655675
Global.JobDefaults = new Dictionary<string, IDictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
656676

677+
// Job Telemetry
678+
Global.JobTelemetry = new List<JobTelemetry>();
679+
680+
// ActionsStepTelemetry for entire job
681+
Global.StepsTelemetry = new List<ActionsStepTelemetry>();
682+
657683
// Job Outputs
658684
JobOutputs = new Dictionary<string, VariableValue>(StringComparer.OrdinalIgnoreCase);
659685

660686
// Actions environment
661687
ActionsEnvironment = message.ActionsEnvironment;
662688

663-
// ActionsStepTelemetry
664-
ActionsStepsTelemetry = new List<ActionsStepTelemetry>();
665-
666-
JobTelemetry = new List<JobTelemetry>();
667689

668690
// Service container info
669691
Global.ServiceContainers = new List<ContainerInfo>();
@@ -895,6 +917,24 @@ public IEnumerable<IssueMatcherConfig> GetMatchers()
895917
return Root._matchers ?? Array.Empty<IssueMatcherConfig>();
896918
}
897919

920+
public void PublishStepTelemetry()
921+
{
922+
if (!_stepTelemetryPublished)
923+
{
924+
// Add to the global steps telemetry only if we have something to log.
925+
if (!string.IsNullOrEmpty(StepTelemetry?.Type))
926+
{
927+
Trace.Info($"Publish step telemetry for current step {StringUtil.ConvertToJson(StepTelemetry)}.");
928+
Global.StepsTelemetry.Add(StepTelemetry);
929+
_stepTelemetryPublished = true;
930+
}
931+
}
932+
else
933+
{
934+
Trace.Info($"Step telemetry has already been published.");
935+
}
936+
}
937+
898938
private void InitializeTimelineRecord(Guid timelineId, Guid timelineRecordId, Guid? parentTimelineRecordId, string recordType, string displayName, string refName, int? order)
899939
{
900940
_mainTimelineId = timelineId;

src/Runner.Worker/GlobalContext.cs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public sealed class GlobalContext
1414
public PlanFeatures Features { get; set; }
1515
public IList<String> FileTable { get; set; }
1616
public IDictionary<String, IDictionary<String, String>> JobDefaults { get; set; }
17+
public List<ActionsStepTelemetry> StepsTelemetry { get; set; }
18+
public List<JobTelemetry> JobTelemetry { get; set; }
1719
public TaskOrchestrationPlanReference Plan { get; set; }
1820
public List<string> PrependPath { get; set; }
1921
public List<ContainerInfo> ServiceContainers { get; set; }

src/Runner.Worker/Handlers/CompositeActionHandler.cs

+17-19
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public async Task RunAsync(ActionRunStage stage)
4242
{
4343
ArgUtil.NotNull(Data.PreSteps, nameof(Data.PreSteps));
4444
steps = Data.PreSteps;
45-
}
45+
}
4646
else if (stage == ActionRunStage.Post)
4747
{
4848
ArgUtil.NotNull(Data.PostSteps, nameof(Data.PostSteps));
@@ -60,7 +60,7 @@ public async Task RunAsync(ActionRunStage stage)
6060
Trace.Info($"Skipping executing post step id: {step.Id}, name: ${step.DisplayName}");
6161
}
6262
}
63-
}
63+
}
6464
else
6565
{
6666
ArgUtil.NotNull(Data.Steps, nameof(Data.Steps));
@@ -83,20 +83,17 @@ public async Task RunAsync(ActionRunStage stage)
8383
hasUsesStep = true;
8484
}
8585
}
86-
var pathReference = Action as Pipelines.RepositoryPathReference;
87-
var telemetry = new ActionsStepTelemetry {
88-
Ref = GetActionRef(),
89-
HasPreStep = Data.HasPre,
90-
HasPostStep = Data.HasPost,
91-
IsEmbedded = ExecutionContext.IsEmbedded,
92-
Type = "composite",
93-
HasRunsStep = hasRunsStep,
94-
HasUsesStep = hasUsesStep,
95-
StepCount = steps.Count
96-
};
97-
ExecutionContext.Root.ActionsStepsTelemetry.Add(telemetry);
86+
87+
ExecutionContext.StepTelemetry.Ref = GetActionRef();
88+
ExecutionContext.StepTelemetry.HasPreStep = Data.HasPre;
89+
ExecutionContext.StepTelemetry.HasPostStep = Data.HasPost;
90+
ExecutionContext.StepTelemetry.IsEmbedded = ExecutionContext.IsEmbedded;
91+
ExecutionContext.StepTelemetry.Type = "composite";
92+
ExecutionContext.StepTelemetry.HasRunsStep = hasRunsStep;
93+
ExecutionContext.StepTelemetry.HasUsesStep = hasUsesStep;
94+
ExecutionContext.StepTelemetry.StepCount = steps.Count;
9895
}
99-
96+
10097
try
10198
{
10299
// Inputs of the composite step
@@ -117,7 +114,7 @@ public async Task RunAsync(ActionRunStage stage)
117114
// Create embedded steps
118115
var embeddedSteps = new List<IStep>();
119116

120-
// If we need to setup containers beforehand, do it
117+
// If we need to setup containers beforehand, do it
121118
// only relevant for local composite actions that need to JIT download/setup containers
122119
if (LocalActionContainerSetupSteps != null && LocalActionContainerSetupSteps.Count > 0)
123120
{
@@ -152,7 +149,7 @@ public async Task RunAsync(ActionRunStage stage)
152149
}
153150
else
154151
{
155-
step.ExecutionContext.ExpressionValues["steps"] = ExecutionContext.Global.StepsContext.GetScope(childScopeName);
152+
step.ExecutionContext.ExpressionValues["steps"] = ExecutionContext.Global.StepsContext.GetScope(childScopeName);
156153
}
157154

158155
// Shallow copy github context
@@ -309,7 +306,7 @@ private async Task RunStepsAsync(List<IStep> embeddedSteps, ActionRunStage stage
309306
// Mark job as cancelled
310307
ExecutionContext.Root.Result = TaskResult.Canceled;
311308
ExecutionContext.Root.JobContext.Status = ExecutionContext.Root.Result?.ToActionResult();
312-
309+
313310
step.ExecutionContext.Debug($"Re-evaluate condition on job cancellation for step: '{step.DisplayName}'.");
314311
var conditionReTestTraceWriter = new ConditionTraceWriter(Trace, null); // host tracing only
315312
var conditionReTestResult = false;
@@ -393,7 +390,7 @@ private async Task RunStepsAsync(List<IStep> embeddedSteps, ActionRunStage stage
393390
{
394391
await RunStepAsync(step);
395392
}
396-
393+
397394
}
398395
finally
399396
{
@@ -458,6 +455,7 @@ private async Task RunStepAsync(IStep step)
458455

459456
Trace.Info($"Step result: {step.ExecutionContext.Result}");
460457
step.ExecutionContext.Debug($"Finished: {step.DisplayName}");
458+
step.ExecutionContext.PublishStepTelemetry();
461459
}
462460

463461
private void SetStepConclusion(IStep step, TaskResult result)

src/Runner.Worker/Handlers/ContainerActionHandler.cs

+12-15
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.IO;
4+
using System.Linq;
35
using System.Threading.Tasks;
4-
using System;
5-
using GitHub.Runner.Worker.Container;
6-
using Pipelines = GitHub.DistributedTask.Pipelines;
6+
using GitHub.DistributedTask.Pipelines.ContextData;
7+
using GitHub.DistributedTask.WebApi;
78
using GitHub.Runner.Common;
89
using GitHub.Runner.Sdk;
9-
using GitHub.DistributedTask.WebApi;
10-
using GitHub.DistributedTask.Pipelines.ContextData;
11-
using System.Linq;
10+
using GitHub.Runner.Worker.Container;
11+
using Pipelines = GitHub.DistributedTask.Pipelines;
1212

1313
namespace GitHub.Runner.Worker.Handlers
1414
{
@@ -73,14 +73,11 @@ public async Task RunAsync(ActionRunStage stage)
7373
// Add Telemetry to JobContext to send with JobCompleteMessage
7474
if (stage == ActionRunStage.Main)
7575
{
76-
var telemetry = new ActionsStepTelemetry {
77-
Ref = GetActionRef(),
78-
HasPreStep = Data.HasPre,
79-
HasPostStep = Data.HasPost,
80-
IsEmbedded = ExecutionContext.IsEmbedded,
81-
Type = type
82-
};
83-
ExecutionContext.Root.ActionsStepsTelemetry.Add(telemetry);
76+
ExecutionContext.StepTelemetry.Ref = GetActionRef();
77+
ExecutionContext.StepTelemetry.HasPreStep = Data.HasPre;
78+
ExecutionContext.StepTelemetry.HasPostStep = Data.HasPost;
79+
ExecutionContext.StepTelemetry.IsEmbedded = ExecutionContext.IsEmbedded;
80+
ExecutionContext.StepTelemetry.Type = type;
8481
}
8582

8683
// run container

0 commit comments

Comments
 (0)