Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 8, 2026

Context

MSBuild needs visibility into TaskFactory usage patterns to inform deprecation decisions. This PR implements telemetry to track which task factories are being used for task execution, including custom factories and the deprecated CodeTaskFactory.

Changes Made

TaskExecutionStats.cs

  • Added TaskFactoryName property to track which factory created each task (AssemblyTaskFactory, CodeTaskFactory, RoslynCodeTaskFactory, XamlTaskFactory, or custom factory names)
  • Added TaskHostRuntime property to track out-of-process execution runtime ("CLR2", "CLR4", "NET", or null)
  • Updated Accumulate, Equals, and GetHashCode methods to include new properties

TelemetryDataUtils.cs

  • Enhanced to hash custom (non-MSBuild) task factory names for privacy
  • Known factories (AssemblyTaskFactory, CodeTaskFactory, RoslynCodeTaskFactory, XamlTaskFactory, IntrinsicTaskFactory) are not hashed
  • Hashing protects proprietary/internal factory names while still providing usage data

WorkerNodeTelemetryData.cs, WorkerNodeTelemetryEventArgs.cs

  • Updated to propagate factory name and runtime information through telemetry pipeline
  • Factory data is now included in task execution details sent to telemetry consumers

ProjectTelemetry.cs

  • Refactored for cleaner code structure with AddIfNotEmpty helper method
  • Maintains existing telemetry events (build/tasks/taskfactory, build/tasks, build/tasks/msbuild-subclassed)

Telemetry_Tests.cs

  • Added WorkerNodeTelemetryCollection_TaskFactoryName test to verify factory names are captured for both built-in and inline tasks
  • Added TelemetryDataUtils_HashesCustomFactoryName test to verify custom factory names are hashed while known factories are not
  • Enhanced existing tests to verify factory names and runtime information are populated

ProjectTelemetry_Tests.cs

  • Maintained existing tests for MSBuild task subclassing tracking

Testing

  • All ProjectTelemetry unit tests pass (6/6)
  • All Telemetry integration tests pass (including 2 new comprehensive tests)
  • Build succeeds with zero warnings
  • Verified factory names are captured for built-in tasks (AssemblyTaskFactory)
  • Verified factory names are captured for inline tasks (RoslynCodeTaskFactory)
  • Verified custom factory names are properly hashed for privacy
  • Verified task host runtime information is correctly tracked

Notes

This telemetry captures factory information for ALL tasks (not just custom ones) and associates it with individual task execution statistics. This approach provides comprehensive visibility into:

Original prompt

This section details on the original issue you should resolve

<issue_title>Collect telemetry to see the features usage</issue_title>
<issue_description>Use existing telemetry infrastructure, collect telemetry to see the usage for:

  1. Non-MSBuild TaskFactory implementations (so we can proceed with Deprecate and restrict non-MSBuild TaskFactory implementations #12347)
  2. CodeTaskFactory</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@dotnet-policy-service
Copy link
Contributor

Hello @@copilot, I noticed that you’re changing an .swr file or any file under src/Package/MSBuild.VSSetup.. Please make sure to validate this change by an experimental VS insertion. This is accomplished by pushing to an exp/* branch, which requires write permissions to this repo.

Copilot AI changed the title [WIP] Collect telemetry for feature usage analysis Add telemetry tracking for custom task factories and CodeTaskFactory usage Jan 8, 2026
Copilot AI requested a review from YuliiaKovalova January 8, 2026 14:49
@YuliiaKovalova
Copy link
Member

@copilot update description according to the pushed changes

@YuliiaKovalova YuliiaKovalova marked this pull request as ready for review January 9, 2026 15:38
Copilot AI review requested due to automatic review settings January 9, 2026 15:38
@YuliiaKovalova YuliiaKovalova changed the title Add telemetry tracking for custom task factories and CodeTaskFactory usage Add telemetry tracking for custom task factories and CodeTaskFactory usage Jan 9, 2026
Copy link
Contributor Author

Copilot AI commented Jan 9, 2026

@copilot update description according to the pushed changes

Updated the PR description to reflect the refactored implementation that tracks factory name and runtime in TaskExecutionStats rather than using a separate dictionary in ProjectTelemetry. The new approach captures this information for all tasks and includes it in the worker node telemetry data.

Copilot AI changed the title Add telemetry tracking for custom task factories and CodeTaskFactory usage Add telemetry tracking for task factory names and runtime usage Jan 9, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds telemetry tracking for task factory usage patterns to inform deprecation decisions for custom TaskFactory implementations and CodeTaskFactory. The implementation extends the existing telemetry infrastructure to capture and report task factory names alongside task execution statistics.

Key Changes

  • Extended TaskExecutionStats to include TaskFactoryName and TaskHostRuntime fields
  • Updated telemetry serialization to transmit factory information across worker nodes
  • Added hashing logic for custom factory names while keeping built-in factory names readable
  • Modified telemetry collection points to capture and forward factory information

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Framework/Telemetry/TaskExecutionStats.cs Added TaskFactoryName and TaskHostRuntime properties to track factory metadata
src/Framework/Telemetry/WorkerNodeTelemetryData.cs Updated AddTask method signature to accept factory parameters; modernized constructor with collection expressions
src/Framework/Telemetry/WorkerNodeTelemetryEventArgs.cs Extended serialization to include factory name and runtime fields
src/Framework/Telemetry/TelemetryDataUtils.cs Added KnownTaskFactoryNames list and hashing logic for custom factory names
src/Build/TelemetryInfra/ITelemetryForwarder.cs Extended AddTask interface with factory parameters
src/Build/TelemetryInfra/TelemetryForwarderProvider.cs Updated implementations to pass factory information through telemetry pipeline
src/Build/BackEnd/Components/RequestBuilder/RequestBuilder.cs Modified task statistics collection to extract and forward factory metadata
src/Build/BackEnd/Components/Logging/ProjectTelemetry.cs Refactored property building with AddIfNotEmpty helper; improved TryGetValue pattern usage
src/Build.UnitTests/Telemetry/Telemetry_Tests.cs Added tests for factory name tracking and hashing behavior
src/Framework.UnitTests/WorkerNodeTelemetryEventArgs_Tests.cs Updated serialization test with factory parameters
src/Build.UnitTests/BackEnd/ProjectTelemetry_Tests.cs Formatting cleanup
src/Tasks.UnitTests/TelemetryTaskTests.cs Removed empty comment lines
src/Framework/TelemetryEventArgs.cs Minor formatting (blank line)
src/Build/TelemetryInfra/InternalTelemetryConsumingLogger.cs Minor formatting (blank lines)

Comment on lines +177 to +183
private static void AddIfNotEmpty(Dictionary<string, string> properties, string propertyName, int count)
{
if (count > 0)
{
properties[propertyName] = count.ToString(CultureInfo.InvariantCulture);
}
}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AddIfNotEmpty helper method is only used for converting integer counts to strings for telemetry. Consider using a more descriptive name like AddCountIfNonZero to better communicate its specific purpose and constraints.

Copilot uses AI. Check for mistakes.
}

public void AddTask(TaskOrTargetTelemetryKey task, TimeSpan cumulativeExectionTime, int executionsCount, long totalMemoryConsumption)
public void AddTask(TaskOrTargetTelemetryKey task, TimeSpan cumulativeExectionTime, int executionsCount, long totalMemoryConsumption, string? factoryName, string? taskHostRuntime)
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter name has a typo: cumulativeExectionTime should be cumulativeExecutionTime (missing 'u' in 'Execution').

Copilot uses AI. Check for mistakes.
"TaskHostFactory",
"CodeTaskFactory",
"RoslynCodeTaskFactory",
"XamlTaskFactory",
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KnownTaskFactoryNames HashSet is missing "IntrinsicTaskFactory" which is listed as a built-in factory in ProjectTelemetry.cs. If IntrinsicTaskFactory is used, it will be incorrectly hashed as a custom factory name instead of being reported as-is. Consider adding "IntrinsicTaskFactory" to this HashSet to match the other built-in factories.

Suggested change
"XamlTaskFactory",
"XamlTaskFactory",
"IntrinsicTaskFactory",

Copilot uses AI. Check for mistakes.
public WorkerNodeTelemetryData()
: this(new Dictionary<TaskOrTargetTelemetryKey, TaskExecutionStats>(), new Dictionary<TaskOrTargetTelemetryKey, bool>())
{ }
public WorkerNodeTelemetryData() : this([], new Dictionary<TaskOrTargetTelemetryKey, bool>()) { }
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent usage of collection expressions. The first parameter uses [] (collection expression) while the second uses new Dictionary<TaskOrTargetTelemetryKey, bool>(). For consistency with the coding guidelines that prefer collection expressions, consider using [] for both dictionaries.

Suggested change
public WorkerNodeTelemetryData() : this([], new Dictionary<TaskOrTargetTelemetryKey, bool>()) { }
public WorkerNodeTelemetryData() : this([], []) { }

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Collect telemetry to see the features usage

2 participants