Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public async Task SetupAsync()
DocumentPullDiagnosticsEndpoint = new DocumentPullDiagnosticsEndpoint(
languageServerFeatureOptions: languageServer.GetRequiredService<LanguageServerFeatureOptions>(),
translateDiagnosticsService: languageServer.GetRequiredService<RazorTranslateDiagnosticsService>(),
languageServer: new ClientNotifierService(BuildDiagnostics(N)));
languageServer: new ClientNotifierService(BuildDiagnostics(N)), null);
var projectRoot = Path.Combine(RepoRoot, "src", "Razor", "test", "testapps", "ComponentApp");
var projectFilePath = Path.Combine(projectRoot, "ComponentApp.csproj");
_filePath = Path.Combine(projectRoot, "Components", "Pages", $"Generated.razor");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public IDisposable BeginBlock(string name, Severity severity, ImmutableDictionar
return NullScope.Instance;
}

public IDisposable TrackLspRequest(string name, string lspMethodName, string lspServerName, Guid correlationId)
{
return NullScope.Instance;
}

private class NullScope : IDisposable
{
public static NullScope Instance { get; } = new NullScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
namespace Microsoft.AspNetCore.Razor.LanguageServer.Protocol;

internal record DelegatedDiagnosticParams(
VersionedTextDocumentIdentifier HostDocument);
VersionedTextDocumentIdentifier HostDocument,
System.Guid CorrelationId);

internal record DelegatedPositionParams(
VersionedTextDocumentIdentifier HostDocument,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.AspNetCore.Razor.LanguageServer.EndpointContracts;
using Microsoft.AspNetCore.Razor.LanguageServer.Protocol;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.AspNetCore.Razor.Telemetry;
using Microsoft.CodeAnalysis.Razor.Workspaces;
using Microsoft.CommonLanguageServerProtocol.Framework;
using Microsoft.VisualStudio.LanguageServer.Protocol;
Expand All @@ -22,15 +23,18 @@ internal class DocumentPullDiagnosticsEndpoint : IRazorRequestHandler<VSInternal
private readonly LanguageServerFeatureOptions _languageServerFeatureOptions;
private readonly ClientNotifierServiceBase _languageServer;
private readonly RazorTranslateDiagnosticsService _translateDiagnosticsService;
private readonly ITelemetryReporter? _telemetryReporter;

public DocumentPullDiagnosticsEndpoint(
LanguageServerFeatureOptions languageServerFeatureOptions,
RazorTranslateDiagnosticsService translateDiagnosticsService,
ClientNotifierServiceBase languageServer)
ClientNotifierServiceBase languageServer,
ITelemetryReporter? telemetryReporter)
{
_languageServerFeatureOptions = languageServerFeatureOptions ?? throw new ArgumentNullException(nameof(languageServerFeatureOptions));
_translateDiagnosticsService = translateDiagnosticsService ?? throw new ArgumentNullException(nameof(translateDiagnosticsService));
_languageServer = languageServer ?? throw new ArgumentNullException(nameof(languageServer));
_telemetryReporter = telemetryReporter;
}

public bool MutatesSolutionState => false;
Expand All @@ -57,11 +61,13 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(VSInternalDocumentDiagno
return default;
}

var correlationId = Guid.NewGuid();
using var __ = _telemetryReporter?.TrackLspRequest("diagnostics", VSInternalMethods.DocumentPullDiagnosticName, RazorLSPConstants.RazorLanguageServerName, correlationId);
var documentContext = context.GetRequiredDocumentContext();

var razorDiagnostics = await GetRazorDiagnosticsAsync(documentContext, cancellationToken).ConfigureAwait(false);

var (csharpDiagnostics, htmlDiagnostics) = await GetHtmlCSharpDiagnosticsAsync(documentContext, cancellationToken).ConfigureAwait(false);
var (csharpDiagnostics, htmlDiagnostics) = await GetHtmlCSharpDiagnosticsAsync(documentContext, correlationId, cancellationToken).ConfigureAwait(false);

using var _ = ListPool<VSInternalDiagnosticReport>.GetPooledObject(out var allDiagnostics);
allDiagnostics.SetCapacityIfLarger(
Expand Down Expand Up @@ -131,9 +137,9 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(VSInternalDocumentDiagno
return razorDiagnostics;
}

private async Task<(VSInternalDiagnosticReport[]? CSharpDiagnostics, VSInternalDiagnosticReport[]? HtmlDiagnostics)> GetHtmlCSharpDiagnosticsAsync(VersionedDocumentContext documentContext, CancellationToken cancellationToken)
private async Task<(VSInternalDiagnosticReport[]? CSharpDiagnostics, VSInternalDiagnosticReport[]? HtmlDiagnostics)> GetHtmlCSharpDiagnosticsAsync(VersionedDocumentContext documentContext, Guid correlationId, CancellationToken cancellationToken)
{
var delegatedParams = new DelegatedDiagnosticParams(documentContext.Identifier);
var delegatedParams = new DelegatedDiagnosticParams(documentContext.Identifier, correlationId);
var delegatedResponse = await _languageServer.SendRequestAsync<DelegatedDiagnosticParams, RazorPullDiagnosticResponse?>(
RazorLanguageServerCustomMessageTargets.RazorPullDiagnosticEndpointName,
delegatedParams,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +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;

namespace Microsoft.AspNetCore.Razor.LanguageServer;

internal static class RazorLSPConstants
{
public const string RazorLanguageServerName = "Razor Language Server Client";
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@

using System;
using System.Collections.Immutable;
using System.Xml.Linq;

namespace Microsoft.AspNetCore.Razor.Telemetry;

public interface ITelemetryReporter
{
IDisposable BeginBlock(string name, Severity severity);
IDisposable BeginBlock(string name, Severity severity, ImmutableDictionary<string, object?> values);
IDisposable TrackLspRequest(string name, string lspMethodName, string lspServerName, Guid correlationId);
void ReportEvent(string name, Severity severity);
void ReportEvent(string name, Severity severity, ImmutableDictionary<string, object?> values);
void ReportFault(Exception exception, string? message, params object?[] @params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public IDisposable BeginBlock(string name, Severity severity, ImmutableDictionar
return NullScope.Instance;
}

public IDisposable TrackLspRequest(string name, string lspMethodName, string lspServerName, Guid correlationId)
{
return NullScope.Instance;
}

private class NullScope : IDisposable
{
public static NullScope Instance { get; } = new NullScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,16 @@ public IDisposable BeginBlock(string name, Severity severity, ImmutableDictionar
return new TelemetryScope(this, name, severity, values.ToImmutableDictionary((tuple) => tuple.Key, (tuple) => (object?)tuple.Value));
}

public IDisposable TrackLspRequest(string name, string lspMethodName, string languageServerName, Guid correlationId)
{
return BeginBlock(name, Severity.Normal, ImmutableDictionary.CreateRange(new KeyValuePair<string, object?>[]
{
new("eventscope.method", lspMethodName),
new("eventscope.languageservername", languageServerName),
new("eventscope.correlationid", correlationId),
}));
}

private class TelemetryScope : IDisposable
{
private readonly ITelemetryReporter _telemetryReporter;
Expand Down Expand Up @@ -251,7 +261,7 @@ public void Dispose()

_stopwatch.Stop();
var values = _values.Add("eventscope.ellapsedms", _stopwatch.ElapsedMilliseconds);
_telemetryReporter.ReportEvent(_name, _severity, values);
_telemetryReporter.ReportEvent(_name, _severity, _values);
StopwatchPool.Default.Return(_stopwatch);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ internal class DefaultRazorLanguageServerCustomMessageTarget : RazorLanguageServ
private readonly TrackingLSPDocumentManager _documentManager;
private readonly JoinableTaskFactory _joinableTaskFactory;
private readonly LSPRequestInvoker _requestInvoker;
private readonly ITelemetryReporter _telemetryReporter;
private readonly FormattingOptionsProvider _formattingOptionsProvider;
private readonly IClientSettingsManager _editorSettingsManager;
private readonly LSPDocumentSynchronizer _documentSynchronizer;
Expand Down Expand Up @@ -106,10 +107,11 @@ public DefaultRazorLanguageServerCustomMessageTarget(

_joinableTaskFactory = joinableTaskContext.Factory;

_requestInvoker = new TelemetryReportingLSPRequestInvoker(requestInvoker, telemetryReporter);
_requestInvoker = requestInvoker;
_formattingOptionsProvider = formattingOptionsProvider;
_editorSettingsManager = editorSettingsManager;
_documentSynchronizer = documentSynchronizer;
_telemetryReporter = telemetryReporter;
_outputWindowLogger = outputWindowLogger;
}

Expand Down Expand Up @@ -1117,8 +1119,8 @@ public override Task<ImplementationResult> ImplementationAsync(DelegatedPosition

public override async Task<RazorPullDiagnosticResponse?> DiagnosticsAsync(DelegatedDiagnosticParams request, CancellationToken cancellationToken)
{
var csharpTask = Task.Run(() => GetVirtualDocumentPullDiagnosticsAsync<CSharpVirtualDocumentSnapshot>(request.HostDocument, RazorLSPConstants.RazorCSharpLanguageServerName, cancellationToken), cancellationToken);
var htmlTask = Task.Run(() => GetVirtualDocumentPullDiagnosticsAsync<HtmlVirtualDocumentSnapshot>(request.HostDocument, RazorLSPConstants.HtmlLanguageServerName, cancellationToken), cancellationToken);
var csharpTask = Task.Run(() => GetVirtualDocumentPullDiagnosticsAsync<CSharpVirtualDocumentSnapshot>(request.HostDocument, request.CorrelationId, RazorLSPConstants.RazorCSharpLanguageServerName, cancellationToken), cancellationToken);
var htmlTask = Task.Run(() => GetVirtualDocumentPullDiagnosticsAsync<HtmlVirtualDocumentSnapshot>(request.HostDocument, request.CorrelationId, RazorLSPConstants.HtmlLanguageServerName, cancellationToken), cancellationToken);

try
{
Expand All @@ -1143,7 +1145,7 @@ public override Task<ImplementationResult> ImplementationAsync(DelegatedPosition
return new RazorPullDiagnosticResponse(csharpDiagnostics, htmlDiagnostics);
}

private async Task<VSInternalDiagnosticReport[]?> GetVirtualDocumentPullDiagnosticsAsync<TVirtualDocumentSnapshot>(VersionedTextDocumentIdentifier hostDocument, string delegatedLanguageServerName, CancellationToken cancellationToken)
private async Task<VSInternalDiagnosticReport[]?> GetVirtualDocumentPullDiagnosticsAsync<TVirtualDocumentSnapshot>(VersionedTextDocumentIdentifier hostDocument, Guid correlationId, string delegatedLanguageServerName, CancellationToken cancellationToken)
where TVirtualDocumentSnapshot : VirtualDocumentSnapshot
{
var (synchronized, virtualDocument) = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync<TVirtualDocumentSnapshot>(
Expand All @@ -1162,7 +1164,10 @@ public override Task<ImplementationResult> ImplementationAsync(DelegatedPosition
Uri = virtualDocument.Uri,
},
};
var response = await _requestInvoker.ReinvokeRequestOnServerAsync<VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]?>(

ReinvocationResponse<VSInternalDiagnosticReport[]?>? response;
using var _ = _telemetryReporter.TrackLspRequest(nameof(_requestInvoker.ReinvokeRequestOnServerAsync), VSInternalMethods.DocumentPullDiagnosticName, delegatedLanguageServerName, correlationId);
response = await _requestInvoker.ReinvokeRequestOnServerAsync<VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]?>(
virtualDocument.Snapshot.TextBuffer,
VSInternalMethods.DocumentPullDiagnosticName,
delegatedLanguageServerName,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private async Task ValidateDiagnosticsAsync(string input)
var requestContext = new RazorRequestContext(documentContext, Logger, null!);

var translateDiagnosticsService = new RazorTranslateDiagnosticsService(DocumentMappingService, LoggerFactory);
var diagnosticsEndPoint = new DocumentPullDiagnosticsEndpoint(LanguageServerFeatureOptions, translateDiagnosticsService, LanguageServer);
var diagnosticsEndPoint = new DocumentPullDiagnosticsEndpoint(LanguageServerFeatureOptions, translateDiagnosticsService, LanguageServer, null);

var diagnosticsRequest = new VSInternalDocumentDiagnosticsParams
{
Expand Down