Skip to content

Commit

Permalink
Merge pull request #75402 from dibarbet/lsp_project_telemetry
Browse files Browse the repository at this point in the history
Report LSP loading telemetry
  • Loading branch information
dibarbet authored Oct 15, 2024
2 parents a7492b7 + e53963b commit 97519a7
Show file tree
Hide file tree
Showing 33 changed files with 622 additions and 385 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private async Task InvokeAsync()
{
try
{
using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.SuggestedAction_Application_Summary, $"Total");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.SuggestedAction_Application_Summary, $"Total");

using var token = SourceProvider.OperationListener.BeginAsyncOperation($"{nameof(SuggestedAction)}.{nameof(Invoke)}");
using var context = SourceProvider.UIThreadOperationExecutor.BeginExecute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ private async Task GetSuggestedActionsWorkerAsync(
// then pass it continuously from one priority group to the next.
var lowPriorityAnalyzerData = new SuggestedActionPriorityProvider.LowPriorityAnalyzersAndDiagnosticIds();

using var _2 = TelemetryLogging.LogBlockTimeAggregated(FunctionId.SuggestedAction_Summary, $"Total");
using var _2 = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.SuggestedAction_Summary, $"Total");

// Collectors are in priority order. So just walk them from highest to lowest.
foreach (var collector in collectors)
{
if (TryGetPriority(collector.Priority) is CodeActionRequestPriority priority)
{
using var _3 = TelemetryLogging.LogBlockTimeAggregated(FunctionId.SuggestedAction_Summary, $"Total.Pri{(int)priority}");
using var _3 = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.SuggestedAction_Summary, $"Total.Pri{(int)priority}");

var allSets = GetCodeFixesAndRefactoringsAsync(
state, requestedActionCategories, document,
Expand Down Expand Up @@ -229,7 +229,7 @@ private async IAsyncEnumerable<SuggestedActionSet> GetCodeFixesAndRefactoringsAs

async Task<ImmutableArray<UnifiedSuggestedActionSet>> GetCodeFixesAsync()
{
using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.SuggestedAction_Summary, $"Total.Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetCodeFixesAsync)}");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.SuggestedAction_Summary, $"Total.Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetCodeFixesAsync)}");

if (owner._codeFixService == null ||
!supportsFeatureService.SupportsCodeFixes(target.SubjectBuffer) ||
Expand All @@ -245,7 +245,7 @@ async Task<ImmutableArray<UnifiedSuggestedActionSet>> GetCodeFixesAsync()

async Task<ImmutableArray<UnifiedSuggestedActionSet>> GetRefactoringsAsync()
{
using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.SuggestedAction_Summary, $"Total.Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetRefactoringsAsync)}");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.SuggestedAction_Summary, $"Total.Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetRefactoringsAsync)}");

if (!selection.HasValue)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public async Task<ImmutableArray<CodeRefactoring>> GetRefactoringsAsync(
CodeActionRequestPriority? priority,
CancellationToken cancellationToken)
{
using (TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeRefactoring_Summary, $"Pri{priority.GetPriorityInt()}"))
using (TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.CodeRefactoring_Summary, $"Pri{priority.GetPriorityInt()}"))
using (Logger.LogBlock(FunctionId.Refactoring_CodeRefactoringService_GetRefactoringsAsync, cancellationToken))
{
using var _ = PooledDictionary<CodeRefactoringProvider, int>.GetInstance(out var providerToIndex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.CodeAnalysis.LanguageServer.BrokeredServices.Services;
using Microsoft.CodeAnalysis.LanguageServer.BrokeredServices.Services.Definitions;
using Microsoft.CodeAnalysis.LanguageServer.LanguageServer;
using Microsoft.CodeAnalysis.LanguageServer.Telemetry;
using Microsoft.Extensions.Logging;
using Microsoft.ServiceHub.Framework;
using Roslyn.Utilities;
Expand Down Expand Up @@ -111,6 +112,7 @@ public void OnError(Exception error)
public void OnNext(ProjectInitializationCompletionState value)
{
_logger.LogDebug("Devkit project initialization completed");
VSCodeRequestTelemetryLogger.ReportProjectInitializationComplete();
_ = SendProjectInitializationCompleteNotificationAsync().ReportNonFatalErrorAsync();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServer.Telemetry;
using Microsoft.CodeAnalysis.Remote.ProjectSystem;
using Microsoft.Extensions.Logging;
using Microsoft.ServiceHub.Framework;
Expand Down Expand Up @@ -44,7 +45,7 @@ async Task IExportedBrokeredService.InitializeAsync(CancellationToken cancellati
public async Task<IWorkspaceProject> CreateAndAddProjectAsync(WorkspaceProjectCreationInfo creationInfo, CancellationToken _)
{
_logger.LogInformation(string.Format(LanguageServerResources.Project_0_loaded_by_CSharp_Dev_Kit, creationInfo.FilePath));

VSCodeRequestTelemetryLogger.ReportProjectLoadStarted();
try
{
if (creationInfo.BuildSystemProperties.TryGetValue("SolutionPath", out var solutionPath))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Roslyn.Utilities;
using RoslynLog = Microsoft.CodeAnalysis.Internal.Log;

// Setting the title can fail if the process is run without a window, such
// as when launched detached from nodejs
Expand Down Expand Up @@ -137,6 +138,7 @@ static async Task RunAsync(ServerConfiguration serverConfiguration, Cancellation
server.Start();

logger.LogInformation("Language server initialized");
RoslynLog.Logger.Log(RoslynLog.FunctionId.VSCode_LanguageServer_Started, logLevel: RoslynLog.LogLevel.Information);

try
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Concurrent;
using System.Composition;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.LanguageServer.Handler;
using Microsoft.CodeAnalysis.Telemetry;

namespace Microsoft.CodeAnalysis.LanguageServer.Telemetry;

[ExportCSharpVisualBasicStatelessLspService(typeof(RequestTelemetryLogger), serverKind: WellKnownLspServerKinds.CSharpVisualBasicLspServer), Shared]
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal class VSCodeRequestTelemetryLogger() : RequestTelemetryLogger(WellKnownLspServerKinds.CSharpVisualBasicLspServer.ToTelemetryString())
{
/// <summary>
/// Tracks whether or not the initial project load has completed.
/// </summary>
private static bool s_initialProjectLoadCompleted = false;

public static void ReportProjectInitializationComplete()
{
s_initialProjectLoadCompleted = true;
Logger.Log(FunctionId.VSCode_Projects_Load_Completed, logLevel: LogLevel.Information);
}

public static void ReportProjectLoadStarted()
{
Logger.Log(FunctionId.VSCode_Project_Load_Started, logLevel: LogLevel.Information);
}

protected override void IncreaseFindDocumentCount(string workspaceCountMetricName)
{
TelemetryLogging.LogAggregatedCounter(FunctionId.LSP_FindDocumentInWorkspace, KeyValueLogMessage.Create(m =>
{
var projectsLoaded = s_initialProjectLoadCompleted;
m[TelemetryLogging.KeyName] = ServerTypeName + "." + workspaceCountMetricName + "." + projectsLoaded;
m[TelemetryLogging.KeyValue] = 1L;
m[TelemetryLogging.KeyMetricName] = workspaceCountMetricName;
m["server"] = ServerTypeName;
m["workspace"] = workspaceCountMetricName;
m["projectsLoaded"] = projectsLoaded;
}));
}
}
12 changes: 6 additions & 6 deletions src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ public CodeFixService(
public async Task<CodeFixCollection?> GetMostSevereFixAsync(
TextDocument document, TextSpan range, ICodeActionRequestPriorityProvider priorityProvider, CancellationToken cancellationToken)
{
using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetMostSevereFixAsync)}");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetMostSevereFixAsync)}");

ImmutableArray<DiagnosticData> allDiagnostics;

using (TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetMostSevereFixAsync)}.{nameof(_diagnosticService.GetDiagnosticsForSpanAsync)}"))
using (TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetMostSevereFixAsync)}.{nameof(_diagnosticService.GetDiagnosticsForSpanAsync)}"))
{
allDiagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync(
document, range, GetShouldIncludeDiagnosticPredicate(document, priorityProvider),
Expand Down Expand Up @@ -172,7 +172,7 @@ public async IAsyncEnumerable<CodeFixCollection> StreamFixesAsync(
ICodeActionRequestPriorityProvider priorityProvider,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}");

// We only need to compute suppression/configuration fixes when request priority is
// 'CodeActionPriorityRequest.Lowest' or no priority was provided at all (so all providers should run).
Expand All @@ -190,7 +190,7 @@ public async IAsyncEnumerable<CodeFixCollection> StreamFixesAsync(
// user-invoked diagnostic requests, for example, user invoked Ctrl + Dot operation for lightbulb.
ImmutableArray<DiagnosticData> diagnostics;

using (TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(_diagnosticService.GetDiagnosticsForSpanAsync)}"))
using (TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(_diagnosticService.GetDiagnosticsForSpanAsync)}"))
{
diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync(
document, range, GetShouldIncludeDiagnosticPredicate(document, priorityProvider),
Expand Down Expand Up @@ -286,10 +286,10 @@ private static SortedDictionary<TextSpan, List<DiagnosticData>> ConvertToMap(
{
cancellationToken.ThrowIfCancellationRequested();

using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"{nameof(GetDocumentFixAllForIdInSpanAsync)}");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.CodeFix_Summary, $"{nameof(GetDocumentFixAllForIdInSpanAsync)}");
ImmutableArray<DiagnosticData> diagnostics;

using (TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"{nameof(GetDocumentFixAllForIdInSpanAsync)}.{nameof(_diagnosticService.GetDiagnosticsForSpanAsync)}"))
using (TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.CodeFix_Summary, $"{nameof(GetDocumentFixAllForIdInSpanAsync)}.{nameof(_diagnosticService.GetDiagnosticsForSpanAsync)}"))
{
diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync(
document, range, diagnosticId, includeSuppressedDiagnostics: false, priorityProvider: new DefaultCodeActionRequestPriorityProvider(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ private async Task<ImmutableArray<DiagnosticData>> GetSyntaxDiagnosticsAsync(Dia

if (_lazySyntaxDiagnostics == null)
{
using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.RequestDiagnostics_Summary, $"{nameof(GetSyntaxDiagnosticsAsync)}.{nameof(GetAnalysisResultAsync)}");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.RequestDiagnostics_Summary, $"{nameof(GetSyntaxDiagnosticsAsync)}.{nameof(GetAnalysisResultAsync)}");

var analysisScope = AnalysisScope.WithAnalyzers(_compilationBasedAnalyzersInAnalysisScope);
var syntaxDiagnostics = await GetAnalysisResultAsync(analysisScope, cancellationToken).ConfigureAwait(false);
Expand Down Expand Up @@ -276,7 +276,7 @@ private async Task<ImmutableArray<DiagnosticData>> GetSemanticDiagnosticsAsync(D

if (_lazySemanticDiagnostics == null)
{
using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.RequestDiagnostics_Summary, $"{nameof(GetSemanticDiagnosticsAsync)}.{nameof(GetAnalysisResultAsync)}");
using var _ = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.RequestDiagnostics_Summary, $"{nameof(GetSemanticDiagnosticsAsync)}.{nameof(GetAnalysisResultAsync)}");

var analysisScope = AnalysisScope.WithAnalyzers(_compilationBasedAnalyzersInAnalysisScope);
var semanticDiagnostics = await GetAnalysisResultAsync(analysisScope, cancellationToken).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ public async Task GetAsync(ArrayBuilder<DiagnosticData> list, CancellationToken
using var _2 = ArrayBuilder<AnalyzerWithState>.GetInstance(out var semanticSpanBasedAnalyzers);
using var _3 = ArrayBuilder<AnalyzerWithState>.GetInstance(out var semanticDocumentBasedAnalyzers);

using var _4 = TelemetryLogging.LogBlockTimeAggregated(FunctionId.RequestDiagnostics_Summary, $"Pri{_priorityProvider.Priority.GetPriorityInt()}");
using var _4 = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.RequestDiagnostics_Summary, $"Pri{_priorityProvider.Priority.GetPriorityInt()}");

foreach (var stateSet in _stateSets)
{
Expand Down Expand Up @@ -383,7 +383,7 @@ private async Task ComputeDocumentDiagnosticsAsync(
ImmutableDictionary<DiagnosticAnalyzer, ImmutableArray<DiagnosticData>> diagnosticsMap;
if (incrementalAnalysis)
{
using var _2 = TelemetryLogging.LogBlockTimeAggregated(FunctionId.RequestDiagnostics_Summary, $"Pri{_priorityProvider.Priority.GetPriorityInt()}.Incremental");
using var _2 = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.RequestDiagnostics_Summary, $"Pri{_priorityProvider.Priority.GetPriorityInt()}.Incremental");

diagnosticsMap = await _owner._incrementalMemberEditAnalyzer.ComputeDiagnosticsAsync(
executor,
Expand All @@ -395,7 +395,7 @@ private async Task ComputeDocumentDiagnosticsAsync(
}
else
{
using var _2 = TelemetryLogging.LogBlockTimeAggregated(FunctionId.RequestDiagnostics_Summary, $"Pri{_priorityProvider.Priority.GetPriorityInt()}.Document");
using var _2 = TelemetryLogging.LogBlockTimeAggregatedHistogram(FunctionId.RequestDiagnostics_Summary, $"Pri{_priorityProvider.Priority.GetPriorityInt()}.Document");

diagnosticsMap = await ComputeDocumentDiagnosticsCoreAsync(executor, cancellationToken).ConfigureAwait(false);
}
Expand Down
Loading

0 comments on commit 97519a7

Please sign in to comment.