From cfad35a3326c0304b79a5dc700357bb6e03aa482 Mon Sep 17 00:00:00 2001 From: Phil Allen Date: Fri, 25 Oct 2024 12:14:28 -0700 Subject: [PATCH] Reduce the amount of telemetry emitted --- .../CodeActions/CodeActionEndpoint.cs | 3 ++- .../Completion/RazorCompletionEndpoint.cs | 3 ++- .../DocumentPullDiagnosticsEndpoint.cs | 7 ++--- .../MapCode/MapCodeEndpoint.cs | 3 ++- .../Semantic/SemanticTokensRangeEndpoint.cs | 3 ++- .../Telemetry/ITelemetryReporter.cs | 4 +-- .../Telemetry/NoOpTelemetryReporter.cs | 4 +-- .../Telemetry/TelemetryScope.cs | 25 +++++++++++------- .../Telemetry/TelemetryThresholds.cs | 26 +++++++++++++++++++ .../RemoteCSharpSemanticTokensProvider.cs | 6 ++++- .../CohostSemanticTokensRangeEndpoint.cs | 3 ++- .../RazorCustomMessageTarget_CodeActions.cs | 3 ++- .../RazorCustomMessageTarget_Completion.cs | 3 ++- .../RazorCustomMessageTarget_Diagnostics.cs | 3 ++- .../RazorCustomMessageTarget_MapCode.cs | 4 ++- ...RazorCustomMessageTarget_SemanticTokens.cs | 4 ++- .../Telemetry/TelemetryReporter.cs | 12 +++------ .../RazorCustomMessageTargetTest.cs | 10 +++---- .../Telemetry/TelemetryReporterTests.cs | 23 +++++----------- 19 files changed, 92 insertions(+), 57 deletions(-) create mode 100644 src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Telemetry/TelemetryThresholds.cs diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs index 2a2c86bcab2..fcfe08bc6ac 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/CodeActionEndpoint.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Razor.Telemetry; using Microsoft.CodeAnalysis.Razor.CodeActions; using Microsoft.CodeAnalysis.Razor.Protocol.CodeActions; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions; @@ -57,7 +58,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(VSCodeActionParams reque } var correlationId = Guid.NewGuid(); - using var __ = _telemetryReporter.TrackLspRequest(LspEndpointName, LanguageServerConstants.RazorLanguageServerName, correlationId); + using var __ = _telemetryReporter.TrackLspRequest(LspEndpointName, LanguageServerConstants.RazorLanguageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.CodeActionRazorTelemetryThresholdMS), correlationId); cancellationToken.ThrowIfCancellationRequested(); return await _codeActionsService.GetCodeActionsAsync(request, documentContext, _supportsCodeActionResolve, correlationId, cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs index 298e83b4bb7..f49976eb7ab 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionEndpoint.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts; using Microsoft.AspNetCore.Razor.Telemetry; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -77,7 +78,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(CompletionParams request } var correlationId = Guid.NewGuid(); - using var _ = _telemetryReporter?.TrackLspRequest(Methods.TextDocumentCompletionName, LanguageServerConstants.RazorLanguageServerName, correlationId); + using var _ = _telemetryReporter?.TrackLspRequest(Methods.TextDocumentCompletionName, LanguageServerConstants.RazorLanguageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.CompletionRazorTelemetryThresholdMS), correlationId); var completionList = await _completionListProvider.GetCompletionListAsync( hostDocumentIndex, completionContext, diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs index ae6dbff95e5..1993c5f4f36 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Diagnostics/DocumentPullDiagnosticsEndpoint.cs @@ -19,6 +19,7 @@ using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Protocol.Diagnostics; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer.Diagnostics; @@ -30,7 +31,7 @@ internal class DocumentPullDiagnosticsEndpoint : IRazorRequestHandler _lastReporedProjectTagHelperCount = ImmutableDictionary.Empty; + private ImmutableDictionary _lastReportedProjectTagHelperCount = ImmutableDictionary.Empty; public DocumentPullDiagnosticsEndpoint( LanguageServerFeatureOptions languageServerFeatureOptions, @@ -71,7 +72,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(VSInternalDocumentDiagno } var correlationId = Guid.NewGuid(); - using var __ = _telemetryReporter?.TrackLspRequest(VSInternalMethods.DocumentPullDiagnosticName, LanguageServerConstants.RazorLanguageServerName, correlationId); + using var __ = _telemetryReporter?.TrackLspRequest(VSInternalMethods.DocumentPullDiagnosticName, LanguageServerConstants.RazorLanguageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.DiagnosticsRazorTelemetryThresholdMS), correlationId); var documentContext = context.DocumentContext; if (documentContext is null) { @@ -202,7 +203,7 @@ private async ValueTask ReportRZ10012TelemetryAsync(DocumentContext documentCont var shouldReport = false; ImmutableInterlocked.AddOrUpdate( - ref _lastReporedProjectTagHelperCount, + ref _lastReportedProjectTagHelperCount, documentContext.Project.Key, (k) => { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs index 029ddb93535..ee1e331f560 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/MapCode/MapCodeEndpoint.cs @@ -21,6 +21,7 @@ using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.LanguageServer.Protocol; using Location = Microsoft.VisualStudio.LanguageServer.Protocol.Location; @@ -70,7 +71,7 @@ public void ApplyCapabilities(VSInternalServerCapabilities serverCapabilities, V } var mapCodeCorrelationId = mapperParams.MapCodeCorrelationId ?? Guid.NewGuid(); - using var ts = _telemetryReporter.TrackLspRequest(VSInternalMethods.WorkspaceMapCodeName, LanguageServerConstants.RazorLanguageServerName, mapCodeCorrelationId); + using var ts = _telemetryReporter.TrackLspRequest(VSInternalMethods.WorkspaceMapCodeName, LanguageServerConstants.RazorLanguageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.MapCodeRazorTelemetryThresholdMS), mapCodeCorrelationId); return await HandleMappingsAsync(mapperParams.Mappings, mapCodeCorrelationId, cancellationToken).ConfigureAwait(false); } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs index c75e1b44112..420c52a522a 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Semantic/SemanticTokensRangeEndpoint.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Razor.Telemetry; using Microsoft.CodeAnalysis.Razor.SemanticTokens; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.AspNetCore.Razor.LanguageServer.Semantic; @@ -49,7 +50,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(SemanticTokensRangeParam var colorBackground = _razorLSPOptionsMonitor.CurrentValue.ColorBackground; var correlationId = Guid.NewGuid(); - using var _ = _telemetryReporter?.TrackLspRequest(Methods.TextDocumentSemanticTokensRangeName, LanguageServerConstants.RazorLanguageServerName, correlationId); + using var _ = _telemetryReporter?.TrackLspRequest(Methods.TextDocumentSemanticTokensRangeName, LanguageServerConstants.RazorLanguageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.SemanticTokensRazorTelemetryThresholdMS), correlationId); var data = await _semanticTokensInfoService.GetSemanticTokensAsync(documentContext, request.Range.ToLinePositionSpan(), colorBackground, correlationId, cancellationToken).ConfigureAwait(false); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs index c10db6823d3..5a2cd8a1c1b 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs @@ -11,9 +11,9 @@ internal interface ITelemetryReporter TelemetryScope BeginBlock(string name, Severity severity, Property property); TelemetryScope BeginBlock(string name, Severity severity, Property property1, Property property2); TelemetryScope BeginBlock(string name, Severity severity, Property property1, Property property2, Property property3); - TelemetryScope BeginBlock(string name, Severity severity, params Property[] properties); + TelemetryScope BeginBlock(string name, Severity severity, TimeSpan minTimeToReport, params Property[] properties); - TelemetryScope TrackLspRequest(string lspMethodName, string lspServerName, Guid correlationId); + TelemetryScope TrackLspRequest(string lspMethodName, string lspServerName, TimeSpan minTimeToReport, Guid correlationId); void ReportEvent(string name, Severity severity); void ReportEvent(string name, Severity severity, Property property); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs index 3ad1fa031b3..7e3758c32bb 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs @@ -25,7 +25,7 @@ public TelemetryScope BeginBlock(string name, Severity severity, Property proper public TelemetryScope BeginBlock(string name, Severity severity, Property property1, Property property2, Property property3) => TelemetryScope.Null; - public TelemetryScope BeginBlock(string name, Severity severity, params Property[] properties) + public TelemetryScope BeginBlock(string name, Severity severity, TimeSpan minTimeToReport, params Property[] properties) => TelemetryScope.Null; public void ReportEvent(string name, Severity severity) @@ -52,7 +52,7 @@ public void ReportFault(Exception exception, string? message, params object?[] @ { } - public TelemetryScope TrackLspRequest(string lspMethodName, string lspServerName, Guid correlationId) + public TelemetryScope TrackLspRequest(string lspMethodName, string lspServerName, TimeSpan minTimeToReport, Guid correlationId) => TelemetryScope.Null; public void ReportRequestTiming(string name, string? language, TimeSpan queuedDuration, TimeSpan requestDuration, TelemetryResult result) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/TelemetryScope.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/TelemetryScope.cs index 641048d44ee..981200faca9 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/TelemetryScope.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/TelemetryScope.cs @@ -16,6 +16,7 @@ internal sealed class TelemetryScope : IDisposable private readonly Severity _severity; private readonly Property[] _properties; private readonly Stopwatch _stopwatch; + private readonly TimeSpan _minTimeToReport; private bool _disposed; private TelemetryScope() @@ -32,6 +33,7 @@ private TelemetryScope() private TelemetryScope( ITelemetryReporter reporter, string name, + TimeSpan minTimeToReport, Severity severity, Property[] properties) { @@ -45,6 +47,7 @@ private TelemetryScope( _properties = properties; _stopwatch = StopwatchPool.Default.Get(); + _minTimeToReport = minTimeToReport; _stopwatch.Restart(); } @@ -59,10 +62,14 @@ public void Dispose() _stopwatch.Stop(); - // We know that we were created with an array of at least length one. - _properties[^1] = new("eventscope.ellapsedms", _stopwatch.ElapsedMilliseconds); + var elapsed = _stopwatch.Elapsed; + if (elapsed >= _minTimeToReport) + { + // We know that we were created with an array of at least length one. + _properties[^1] = new("eventscope.ellapsedms", _stopwatch.ElapsedMilliseconds); - _reporter.ReportEvent(_name, _severity, _properties); + _reporter.ReportEvent(_name, _severity, _properties); + } StopwatchPool.Default.Return(_stopwatch); } @@ -71,7 +78,7 @@ public static TelemetryScope Create(ITelemetryReporter reporter, string name, Se { var array = new Property[1]; - return new(reporter, name, severity, array); + return new(reporter, name, TimeSpan.Zero, severity, array); } public static TelemetryScope Create(ITelemetryReporter reporter, string name, Severity severity, Property property) @@ -79,7 +86,7 @@ public static TelemetryScope Create(ITelemetryReporter reporter, string name, Se var array = new Property[2]; array[0] = property; - return new(reporter, name, severity, array); + return new(reporter, name, TimeSpan.Zero, severity, array); } public static TelemetryScope Create(ITelemetryReporter reporter, string name, Severity severity, Property property1, Property property2) @@ -88,7 +95,7 @@ public static TelemetryScope Create(ITelemetryReporter reporter, string name, Se array[0] = property1; array[1] = property2; - return new(reporter, name, severity, array); + return new(reporter, name, TimeSpan.Zero, severity, array); } public static TelemetryScope Create(ITelemetryReporter reporter, string name, Severity severity, Property property1, Property property2, Property property3) @@ -98,15 +105,15 @@ public static TelemetryScope Create(ITelemetryReporter reporter, string name, Se array[1] = property2; array[2] = property3; - return new(reporter, name, severity, array); + return new(reporter, name, TimeSpan.Zero, severity, array); } - public static TelemetryScope Create(ITelemetryReporter reporter, string name, Severity severity, Property[] properties) + public static TelemetryScope Create(ITelemetryReporter reporter, string name, Severity severity, TimeSpan minTimeToReport, Property[] properties) { var array = new Property[properties.Length + 1]; Array.Copy(properties, array, properties.Length); - return new(reporter, name, severity, array); + return new(reporter, name, minTimeToReport, severity, array); } } diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Telemetry/TelemetryThresholds.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Telemetry/TelemetryThresholds.cs new file mode 100644 index 00000000000..3bbaf21f5b3 --- /dev/null +++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Telemetry/TelemetryThresholds.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; + +/// +/// A set of constants used to reduce the telemetry emitted to the set that help us understand +/// which LSP is taking the most time in the case that the overall call is lengthy. +/// +internal class TelemetryThresholds +{ + internal const int CodeActionRazorTelemetryThresholdMS = 2000; + internal const int CodeActionSubLSPTelemetryThresholdMS = 1000; + + internal const int CompletionRazorTelemetryThresholdMS = 4000; + internal const int CompletionSubLSPTelemetryThresholdMS = 2000; + + internal const int DiagnosticsRazorTelemetryThresholdMS = 4000; + internal const int DiagnosticsSubLSPTelemetryThresholdMS = 2000; + + internal const int MapCodeRazorTelemetryThresholdMS = 2000; + internal const int MapCodeSubLSPTelemetryThresholdMS = 1000; + + internal const int SemanticTokensRazorTelemetryThresholdMS = 2000; + internal const int SemanticTokensSubLSPTelemetryThresholdMS = 1000; +} diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SemanticTokens/RemoteCSharpSemanticTokensProvider.cs b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SemanticTokens/RemoteCSharpSemanticTokensProvider.cs index fd1fe4a78d2..d89862d2b92 100644 --- a/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SemanticTokens/RemoteCSharpSemanticTokensProvider.cs +++ b/src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/SemanticTokens/RemoteCSharpSemanticTokensProvider.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Razor.SemanticTokens; using Microsoft.CodeAnalysis.Razor.Workspaces; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem; using Microsoft.CodeAnalysis.Text; @@ -26,7 +27,10 @@ internal class RemoteCSharpSemanticTokensProvider(IFilePathService filePathServi public async Task GetCSharpSemanticTokensResponseAsync(DocumentContext documentContext, ImmutableArray csharpRanges, Guid correlationId, CancellationToken cancellationToken) { - using var _ = _telemetryReporter.TrackLspRequest(nameof(SemanticTokensRange.GetSemanticTokensAsync), Constants.ExternalAccessServerName, correlationId); + using var _ = _telemetryReporter.TrackLspRequest(nameof(SemanticTokensRange.GetSemanticTokensAsync), + Constants.ExternalAccessServerName, + TimeSpan.FromMilliseconds(TelemetryThresholds.SemanticTokensRazorTelemetryThresholdMS), + correlationId); // We have a razor document, lets find the generated C# document Debug.Assert(documentContext is RemoteDocumentContext, "This method only works on document snapshots created in the OOP process"); diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSemanticTokensRangeEndpoint.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSemanticTokensRangeEndpoint.cs index 811c9ea4b98..7f88bab206c 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSemanticTokensRangeEndpoint.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Cohost/CohostSemanticTokensRangeEndpoint.cs @@ -14,6 +14,7 @@ using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost; using Microsoft.CodeAnalysis.Razor.Remote; using Microsoft.CodeAnalysis.Razor.SemanticTokens; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.Razor.Settings; @@ -79,7 +80,7 @@ public ImmutableArray GetRegistrations(VSInternalClientCapabilitie var colorBackground = _clientSettingsManager.GetClientSettings().AdvancedSettings.ColorBackground; var correlationId = Guid.NewGuid(); - using var _ = _telemetryReporter.TrackLspRequest(Methods.TextDocumentSemanticTokensRangeName, RazorLSPConstants.CohostLanguageServerName, correlationId); + using var _ = _telemetryReporter.TrackLspRequest(Methods.TextDocumentSemanticTokensRangeName, RazorLSPConstants.CohostLanguageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.SemanticTokensRazorTelemetryThresholdMS), correlationId); var tokens = await _remoteServiceInvoker.TryInvokeAsync( razorDocument.Project.Solution, diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs index e8f5cd0af35..886306645c8 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_CodeActions.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Protocol.CodeActions; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.Threading; @@ -56,7 +57,7 @@ internal partial class RazorCustomMessageTarget var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer; var lspMethodName = Methods.TextDocumentCodeActionName; - using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, codeActionParams.CorrelationId); + using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.CodeActionSubLSPTelemetryThresholdMS), codeActionParams.CorrelationId); var requests = _requestInvoker.ReinvokeRequestOnMultipleServersAsync>( textBuffer, lspMethodName, diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs index 8a85d553cdf..7046dc672cb 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Completion.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Protocol.Completion; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.Razor.Snippets; @@ -121,7 +122,7 @@ internal partial class RazorCustomMessageTarget var textBuffer = virtualDocumentSnapshot.Snapshot.TextBuffer; var lspMethodName = Methods.TextDocumentCompletion.Name; ReinvocationResponse? response; - using (_telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, request.CorrelationId)) + using (_telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.CompletionSubLSPTelemetryThresholdMS), request.CorrelationId)) { response = await _requestInvoker.ReinvokeRequestOnServerAsync( textBuffer, diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Diagnostics.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Diagnostics.cs index 3329cf7980e..1f658e47bbf 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Diagnostics.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_Diagnostics.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Protocol.Diagnostics; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.ContainedLanguage; using Microsoft.VisualStudio.LanguageServer.Protocol; using StreamJsonRpc; @@ -78,7 +79,7 @@ internal partial class RazorCustomMessageTarget }; var lspMethodName = VSInternalMethods.DocumentPullDiagnosticName; - using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, delegatedLanguageServerName, correlationId); + using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, delegatedLanguageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.DiagnosticsSubLSPTelemetryThresholdMS), correlationId); var response = await _requestInvoker.ReinvokeRequestOnServerAsync( virtualDocument.Snapshot.TextBuffer, lspMethodName, diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_MapCode.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_MapCode.cs index 6588cdc5d95..90fa1bc7eb7 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_MapCode.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_MapCode.cs @@ -1,9 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. +using System; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Razor.Protocol; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.Protocol; using StreamJsonRpc; @@ -39,7 +41,7 @@ internal partial class RazorCustomMessageTarget var textBuffer = delegationDetails.Value.TextBuffer; var lspMethodName = VSInternalMethods.WorkspaceMapCodeName; var languageServerName = delegationDetails.Value.LanguageServerName; - using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, request.MapCodeCorrelationId); + using var _ = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.MapCodeSubLSPTelemetryThresholdMS), request.MapCodeCorrelationId); var response = await _requestInvoker.ReinvokeRequestOnServerAsync( textBuffer, diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_SemanticTokens.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_SemanticTokens.cs index d21608c4108..2c4b1a21d72 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_SemanticTokens.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LanguageClient/Endpoints/RazorCustomMessageTarget_SemanticTokens.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. +using System; using System.Diagnostics; using System.Linq; using System.Threading; @@ -8,6 +9,7 @@ using Microsoft.CodeAnalysis.Razor.Logging; using Microsoft.CodeAnalysis.Razor.Protocol; using Microsoft.CodeAnalysis.Razor.Workspaces.Protocol.SemanticTokens; +using Microsoft.CodeAnalysis.Razor.Workspaces.Telemetry; using Microsoft.VisualStudio.LanguageServer.Protocol; using StreamJsonRpc; @@ -84,7 +86,7 @@ internal partial class RazorCustomMessageTarget var languageServerName = RazorLSPConstants.RazorCSharpLanguageServerName; SemanticTokens? response; - using (var disposable = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, semanticTokensParams.CorrelationId)) + using (var disposable = _telemetryReporter.TrackLspRequest(lspMethodName, languageServerName, TimeSpan.FromMilliseconds(TelemetryThresholds.SemanticTokensSubLSPTelemetryThresholdMS), semanticTokensParams.CorrelationId)) { try { diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs index a7637298b55..db69d268aa4 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -260,22 +260,18 @@ public TelemetryScope BeginBlock(string name, Severity severity, Property proper public TelemetryScope BeginBlock(string name, Severity severity, Property property1, Property property2, Property property3) => TelemetryScope.Create(this, name, severity, property1, property2, property3); - public TelemetryScope BeginBlock(string name, Severity severity, params Property[] properties) - => TelemetryScope.Create(this, name, severity, properties); + public TelemetryScope BeginBlock(string name, Severity severity, TimeSpan minTimeToReport, params Property[] properties) + => TelemetryScope.Create(this, name, severity, minTimeToReport, properties); - public TelemetryScope TrackLspRequest(string lspMethodName, string languageServerName, Guid correlationId) + public TelemetryScope TrackLspRequest(string lspMethodName, string languageServerName, TimeSpan minTimeToReport, Guid correlationId) { if (correlationId == Guid.Empty) { return TelemetryScope.Null; } - ReportEvent("BeginLspRequest", Severity.Normal, - new("eventscope.method", lspMethodName), - new("eventscope.languageservername", languageServerName), - new("eventscope.correlationid", correlationId)); - return BeginBlock("TrackLspRequest", Severity.Normal, + minTimeToReport, new("eventscope.method", lspMethodName), new("eventscope.languageservername", languageServerName), new("eventscope.correlationid", correlationId)); diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/LanguageClient/RazorCustomMessageTargetTest.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/LanguageClient/RazorCustomMessageTargetTest.cs index 99132c4935c..d3633ab8d1b 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/LanguageClient/RazorCustomMessageTargetTest.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/LanguageClient/RazorCustomMessageTargetTest.cs @@ -266,7 +266,7 @@ async IAsyncEnumerable> var documentSynchronizer = GetDocumentSynchronizer(GetCSharpSnapshot()); var telemetryReporter = new Mock(MockBehavior.Strict); - telemetryReporter.Setup(r => r.TrackLspRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(TelemetryScope.Null); + telemetryReporter.Setup(r => r.TrackLspRequest(It.IsAny(), It.IsAny(), TimeSpan.FromSeconds(1), It.IsAny())).Returns(TelemetryScope.Null); var csharpVirtualDocumentAddListener = new CSharpVirtualDocumentAddListener(LoggerFactory); var target = new RazorCustomMessageTarget( @@ -520,8 +520,8 @@ public async Task ProvideSemanticTokensAsync_ContainsRange_ReturnsSemanticTokens It.IsAny())) .ReturnsAsync(new DefaultLSPDocumentSynchronizer.SynchronizedResult(true, csharpVirtualDocument)); var telemetryReporter = new Mock(MockBehavior.Strict); - telemetryReporter.Setup(r => r.BeginBlock(It.IsAny(), It.IsAny(), It.IsAny())).Returns(TelemetryScope.Null); - telemetryReporter.Setup(r => r.TrackLspRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(TelemetryScope.Null); + telemetryReporter.Setup(r => r.BeginBlock(It.IsAny(), It.IsAny(), TimeSpan.FromSeconds(1), It.IsAny())).Returns(TelemetryScope.Null); + telemetryReporter.Setup(r => r.TrackLspRequest(It.IsAny(), It.IsAny(), TimeSpan.FromSeconds(1), It.IsAny())).Returns(TelemetryScope.Null); var csharpVirtualDocumentAddListener = new CSharpVirtualDocumentAddListener(LoggerFactory); var target = new RazorCustomMessageTarget( @@ -598,8 +598,8 @@ public async Task ProvideSemanticTokensAsync_EmptyRange_ReturnsNoSemanticTokens( It.IsAny())) .ReturnsAsync(new DefaultLSPDocumentSynchronizer.SynchronizedResult(true, csharpVirtualDocument)); var telemetryReporter = new Mock(MockBehavior.Strict); - telemetryReporter.Setup(r => r.BeginBlock(It.IsAny(), It.IsAny(), It.IsAny())).Returns(TelemetryScope.Null); - telemetryReporter.Setup(r => r.TrackLspRequest(It.IsAny(), It.IsAny(), It.IsAny())).Returns(TelemetryScope.Null); + telemetryReporter.Setup(r => r.BeginBlock(It.IsAny(), It.IsAny(), TimeSpan.FromSeconds(1),It.IsAny())).Returns(TelemetryScope.Null); + telemetryReporter.Setup(r => r.TrackLspRequest(It.IsAny(), It.IsAny(), TimeSpan.FromSeconds(1), It.IsAny())).Returns(TelemetryScope.Null); var csharpVirtualDocumentAddListener = new CSharpVirtualDocumentAddListener(LoggerFactory); var target = new RazorCustomMessageTarget( diff --git a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Telemetry/TelemetryReporterTests.cs b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Telemetry/TelemetryReporterTests.cs index 2eeab073a0e..f718a5d4c8f 100644 --- a/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Telemetry/TelemetryReporterTests.cs +++ b/src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Telemetry/TelemetryReporterTests.cs @@ -168,7 +168,7 @@ public void Block_OneArgument() public void Block_TwoArguments() { using var reporter = new TestTelemetryReporter(LoggerFactory); - using (reporter.BeginBlock("EventName", Severity.Normal, new("P1", false), new("P2", "test"))) + using (reporter.BeginBlock("EventName", Severity.Normal, TimeSpan.Zero, new("P1", false), new("P2", "test"))) { } @@ -192,6 +192,7 @@ public void Block_ThreeArguments() var p3Value = Guid.NewGuid(); using (reporter.BeginBlock("EventName", Severity.Normal, + TimeSpan.Zero, new("P1", false), new("P2", "test"), new("P3", p3Value))) @@ -222,6 +223,7 @@ public void Block_FourArguments() var p3Value = Guid.NewGuid(); using (reporter.BeginBlock("EventName", Severity.Normal, + TimeSpan.Zero, new("P1", false), new("P2", "test"), new("P3", p3Value), @@ -296,7 +298,7 @@ public void TrackLspRequest() { using var reporter = new TestTelemetryReporter(LoggerFactory); var correlationId = Guid.NewGuid(); - using (reporter.TrackLspRequest("MethodName", "ServerName", correlationId)) + using (reporter.TrackLspRequest("MethodName", "ServerName", TimeSpan.Zero, correlationId)) { } @@ -304,29 +306,16 @@ public void TrackLspRequest() e1 => { Assert.Equal(TelemetrySeverity.Normal, e1.Severity); - Assert.Equal("dotnet/razor/beginlsprequest", e1.Name); + Assert.Equal("dotnet/razor/tracklsprequest", e1.Name); Assert.True(e1.HasProperties); + Assert.True(e1.Properties["dotnet.razor.eventscope.ellapsedms"] is long); Assert.Equal("MethodName", e1.Properties["dotnet.razor.eventscope.method"]); Assert.Equal("ServerName", e1.Properties["dotnet.razor.eventscope.languageservername"]); var correlationProperty = e1.Properties["dotnet.razor.eventscope.correlationid"] as TelemetryComplexProperty; Assert.NotNull(correlationProperty); Assert.Equal(correlationId, correlationProperty.Value); - }, - e2 => - { - Assert.Equal(TelemetrySeverity.Normal, e2.Severity); - Assert.Equal("dotnet/razor/tracklsprequest", e2.Name); - Assert.True(e2.HasProperties); - - Assert.True(e2.Properties["dotnet.razor.eventscope.ellapsedms"] is long); - Assert.Equal("MethodName", e2.Properties["dotnet.razor.eventscope.method"]); - Assert.Equal("ServerName", e2.Properties["dotnet.razor.eventscope.languageservername"]); - - var correlationProperty = e2.Properties["dotnet.razor.eventscope.correlationid"] as TelemetryComplexProperty; - Assert.NotNull(correlationProperty); - Assert.Equal(correlationId, correlationProperty.Value); }); }