Skip to content

Add compiler telemetry - #84725

Open
jjonescz wants to merge 5 commits into
dotnet:mainfrom
jjonescz:compiler-telemetry
Open

Add compiler telemetry#84725
jjonescz wants to merge 5 commits into
dotnet:mainfrom
jjonescz:compiler-telemetry

Conversation

@jjonescz

@jjonescz jjonescz commented Jul 31, 2026

Copy link
Copy Markdown
Member

SDK counterpart: dotnet/sdk#55572

Microsoft Reviewers: Open in CodeFlow

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a generic telemetry transport from the compiler server back to the MSBuild Csc/Vbc tasks, and wires up the compilation output cache to emit a structured roslyn/compilercache event that the task forwards to the host via IBuildEngine5.LogTelemetry.

Changes:

  • Extend the compiler server build protocol to include a list of telemetry events on CompletedBuildResponse.
  • Add compiler-server-side telemetry infrastructure and emit compilation-cache metrics for C# and VB server compilations.
  • Forward server-produced telemetry from ManagedCompiler to MSBuild hosts and add unit coverage + design doc updates.

Reviewed changes

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

Show a summary per file
File Description
src/Compilers/Shared/BuildProtocol.cs Adds BuildTelemetryEvent and serializes/deserializes telemetry on CompletedBuildResponse.
src/Compilers/Server/VBCSCompilerTests/CompilationCacheTests.cs Adds tests for cache store result enums + telemetry mapping behavior.
src/Compilers/Server/VBCSCompilerTests/BuildProtocolTest.cs Adds protocol round-trip test coverage for completed responses with telemetry.
src/Compilers/Server/VBCSCompiler/VisualBasicCompilerServer.cs Implements telemetry provider and emits cache telemetry for VB server compiles.
src/Compilers/Server/VBCSCompiler/VBCSCompilerCommandLine.projitems Includes new CompilerServerTelemetry.cs in the build.
src/Compilers/Server/VBCSCompiler/CSharpCompilerServer.cs Implements telemetry provider and emits cache telemetry for C# server compiles.
src/Compilers/Server/VBCSCompiler/CompilerServerTelemetry.cs Introduces telemetry provider interface + cache telemetry model/enums.
src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs Attaches telemetry events to CompletedBuildResponse.
src/Compilers/Server/VBCSCompiler/CompilationCacheUtilities.cs Captures key/restore/store timings and cache status/store-result for telemetry.
src/Compilers/Server/VBCSCompiler/CompilationCache.cs Changes cache store API to return a CompilationCacheStoreResult.
src/Compilers/Core/MSBuildTaskTests/ManagedCompilerTelemetryTests.cs Adds unit tests validating telemetry forwarding behavior in the MSBuild task.
src/Compilers/Core/MSBuildTask/ManagedCompiler.cs Forwards server telemetry events to the host via IBuildEngine5.LogTelemetry.
docs/compilers/Design/compiler-output-cache-experiment.md Documents the new roslyn/compilercache telemetry event and its properties.
Suppressed comments (1)

src/Compilers/Shared/BuildProtocol.cs:443

  • CompletedBuildResponse.Create unconditionally reads TelemetryCount and assumes it is non-negative. If the response body is truncated/corrupt (or comes from an older writer that doesn't include telemetry), this will throw and force a tool fallback. Consider making this parse tolerant by treating missing/negative counts as 0.
            var returnCode = reader.ReadInt32();
            var utf8Output = reader.ReadBoolean();
            var output = ReadLengthPrefixedString(reader);

            var telemetryCount = reader.ReadInt32();
            IReadOnlyList<BuildTelemetryEvent> telemetryEvents = telemetryCount == 0
                ? []
                : readTelemetryEvents(reader, telemetryCount);

Comment thread src/Compilers/Shared/BuildProtocol.cs
Comment thread src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs
@jjonescz
jjonescz marked this pull request as ready for review August 3, 2026 13:44
@jjonescz
jjonescz requested a review from a team as a code owner August 3, 2026 13:44
Copilot AI review requested due to automatic review settings August 3, 2026 13:44
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/Compilers/Server/VBCSCompilerTests/CompilationCacheTests.cs:480

  • Using a hard-coded absolute path ("/nonexistent/path/Util.dll") to simulate a missing assembly is brittle across platforms/environments (rooted path semantics differ on Windows, and the path could theoretically exist). Prefer constructing a guaranteed-missing path under a temp directory created for the test.
            var outputFiles = new CompilationOutputFiles { AssemblyPath = "/nonexistent/path/Util.dll" };

            Assert.Equal(CompilationCacheStoreResult.Failed, cache.TryStoreResult("Util.dll", "hash", outputFiles, "key", _logger));

Copilot AI review requested due to automatic review settings August 3, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/Compilers/Shared/BuildProtocol.cs:409

  • The response-body field list in this doc comment is now out of sync with the actual serialization: CompletedBuildResponse reads/writes a Utf8Output boolean between ReturnCode and Output, but the table doesn’t mention it. This makes the protocol documentation misleading for future maintainers.
    ///  Length             UInteger        4
    ///  ReturnCode         Integer         4
    ///  Output             String          Variable
    ///  TelemetryCount     Integer         4
    ///  TelemetryEvents    Variable        Variable

@jjonescz
jjonescz requested a review from baronfel August 5, 2026 09:55
@jjonescz

jjonescz commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

@dotnet/roslyn-compiler for reviews, thanks

Comment on lines +187 to +189
| `cachestatus` | `hit` or `miss` |
| `storeresult` | `none`, `stored`, `skippedrace`, `skippedexists`, or `failed` |
| `language` | the compiler language (`C#` / `Visual Basic`) |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are these optional or always present?

Comment on lines +70 to +71
/// generic <see cref="BuildTelemetryEvent"/>. This is the first contributor to the compiler
/// server telemetry channel; additional contributors can be added independently.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
/// generic <see cref="BuildTelemetryEvent"/>. This is the first contributor to the compiler
/// server telemetry channel; additional contributors can be added independently.
/// generic <see cref="BuildTelemetryEvent"/>.

namespace Microsoft.CodeAnalysis.CompilerServer
{
/// <summary>
/// Implemented by server compilers that can produce telemetry for a build request. The request

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Existing wording is awkward, maybe this?

Suggested change
/// Implemented by server compilers that can produce telemetry for a build request. The request
/// Implemented by compiler hosts that can produce telemetry for a build request. The request

Comment on lines +18 to +22
/// <remarks>
/// This is intentionally generic: the transport (protocol + task) has no knowledge of any
/// particular event, so new server-side telemetry can be added by producing additional
/// <see cref="BuildTelemetryEvent"/> instances without changing the protocol or the task.
/// </remarks>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This remark seems like noise.

{
private readonly Func<string, MetadataReferenceProperties, PortableExecutableReference> _metadataProvider;
private readonly CompilationCache? _cache;
private readonly CompilationCacheTelemetry _cacheTelemetry = new();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please don't use target-typed new in the compiler codebase.

{
private readonly Func<string, MetadataReferenceProperties, PortableExecutableReference> _metadataProvider;
private readonly CompilationCache? _cache;
private readonly CompilationCacheTelemetry _cacheTelemetry = new();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same comment.


var dllName = arguments.OutputFileName;
var outputTimestampUtc = DateTime.UtcNow;
var keyStopwatch = Stopwatch.StartNew();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rather than having the telemetry type manage one timer, and this method manage another, consider just having the telemetry object manage both timers, and share the timer between them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants