diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/AggregatingTelemetryLog.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/AggregatingTelemetryLog.cs index 1956d5e0853..8b1326daa8c 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/AggregatingTelemetryLog.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/AggregatingTelemetryLog.cs @@ -51,23 +51,24 @@ public AggregatingTelemetryLog(TelemetryReporter reporter, string name, double[] } /// - /// Adds aggregated information for the metric and value passed in via . The Name/Value properties - /// are used as the metric name and value to record. + /// Adds aggregated information for the and . Method name is tacked onto + /// to the first used for convenience. /// - public void Log(string name, + public void Log( + string histogramKey, int value, - string metricName, string method) { if (!IsEnabled) return; - (var histogram, _, var histogramLock) = ImmutableInterlocked.GetOrAdd(ref _histograms, name, name => + (var histogram, _, var histogramLock) = ImmutableInterlocked.GetOrAdd(ref _histograms, histogramKey, histogramKey => { var telemetryEvent = new TelemetryEvent(_eventName); + TelemetryReporter.AddToProperties(telemetryEvent.Properties, new Property("method", method)); - var histogram = _meter.CreateHistogram(metricName, _histogramConfiguration); + var histogram = _meter.CreateHistogram(histogramKey, _histogramConfiguration); var histogramLock = new object(); return (histogram, telemetryEvent, histogramLock); 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 f7ba0c64b1c..2202ca002eb 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -475,13 +475,13 @@ private void Flush() public void LogRequestTelemetry(string name, string? language, TimeSpan queuedDuration, TimeSpan requestDuration, TelemetryResult result) { LogAggregated("LSP_TimeInQueue", + "TimeInQueue", // All time in queue events use the same histogram, no need for separate keys (int)queuedDuration.TotalMilliseconds, - "TimeInQueue", name); LogAggregated("LSP_RequestDuration", + name, // RequestDuration requests are histogrammed by their unique name (int)requestDuration.TotalMilliseconds, - "RequestDuration", name); _requestCounters.GetOrAdd((name, language), (_) => new Counter()).IncrementCount(result); @@ -503,13 +503,13 @@ private void LogRequestCounters() } private void LogAggregated( - string name, + string managerKey, + string histogramKey, int value, - string metricName, string method) { - var aggregatingLog = _aggregatingManager?.GetLog(name); - aggregatingLog?.Log(name, value, metricName, method); + var aggregatingLog = _aggregatingManager?.GetLog(managerKey); + aggregatingLog?.Log(histogramKey, value, method); } private sealed class Counter 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 f718a5d4c8f..6f803aa5b89 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 @@ -415,6 +415,27 @@ public void ReportHistogram() TimeSpan.FromMilliseconds(300), AspNetCore.Razor.Telemetry.TelemetryResult.Failed); + reporter.ReportRequestTiming( + Methods.TextDocumentCompletionName, + WellKnownLspServerKinds.RazorLspServer.GetContractName(), + TimeSpan.FromMilliseconds(100), + TimeSpan.FromMilliseconds(100), + AspNetCore.Razor.Telemetry.TelemetryResult.Succeeded); + + reporter.ReportRequestTiming( + Methods.TextDocumentCompletionName, + WellKnownLspServerKinds.RazorLspServer.GetContractName(), + TimeSpan.FromMilliseconds(200), + TimeSpan.FromMilliseconds(200), + AspNetCore.Razor.Telemetry.TelemetryResult.Cancelled); + + reporter.ReportRequestTiming( + Methods.TextDocumentCompletionName, + WellKnownLspServerKinds.RazorLspServer.GetContractName(), + TimeSpan.FromMilliseconds(300), + TimeSpan.FromMilliseconds(300), + AspNetCore.Razor.Telemetry.TelemetryResult.Failed); + reporter.Dispose(); // Assert @@ -436,7 +457,7 @@ public void ReportHistogram() static evt => { var histogram = Assert.IsAssignableFrom>(evt.Instrument); - Assert.Equal("RequestDuration", histogram.Name); + Assert.Equal(Methods.TextDocumentCodeActionName, histogram.Name); var telemetryEvent = evt.Event; Assert.Equal("dotnet/razor/lsp_requestduration", telemetryEvent.Name); @@ -446,6 +467,20 @@ public void ReportHistogram() Assert.Equal("dotnet.razor.method", prop.Key); Assert.Equal(Methods.TextDocumentCodeActionName, prop.Value); }); + }, + static evt => + { + var histogram = Assert.IsAssignableFrom>(evt.Instrument); + Assert.Equal(Methods.TextDocumentCompletionName, histogram.Name); + + var telemetryEvent = evt.Event; + Assert.Equal("dotnet/razor/lsp_requestduration", telemetryEvent.Name); + Assert.Collection(telemetryEvent.Properties, + static prop => + { + Assert.Equal("dotnet.razor.method", prop.Key); + Assert.Equal(Methods.TextDocumentCompletionName, prop.Value); + }); }); Assert.Collection(reporter.Events, @@ -473,6 +508,31 @@ public void ReportHistogram() Assert.Equal("dotnet.razor.cancelled", prop.Key); Assert.Equal(1, prop.Value); }); + }, + static evt => + { + Assert.Equal("dotnet/razor/lsp_requestcounter", evt.Name); + Assert.Collection(evt.Properties, + static prop => + { + Assert.Equal("dotnet.razor.method", prop.Key); + Assert.Equal(Methods.TextDocumentCompletionName, prop.Value); + }, + static prop => + { + Assert.Equal("dotnet.razor.successful", prop.Key); + Assert.Equal(1, prop.Value); + }, + static prop => + { + Assert.Equal("dotnet.razor.failed", prop.Key); + Assert.Equal(1, prop.Value); + }, + static prop => + { + Assert.Equal("dotnet.razor.cancelled", prop.Key); + Assert.Equal(1, prop.Value); + }); }); }