From 7d3c5b9b8f964e9c9ce5f9987624b8934aa2c060 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Tue, 24 Sep 2024 16:36:36 -0700 Subject: [PATCH 1/9] Add a filter for type names when reporting telemetry to not bucket common usages together --- .../Telemetry/TelemetryReporter.cs | 125 ++++++++++++++---- 1 file changed, 100 insertions(+), 25 deletions(-) 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 f6de565c009..0e23b3bda8d 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -7,8 +7,9 @@ using System.Diagnostics; using Microsoft.VisualStudio.Telemetry; using Microsoft.AspNetCore.Razor.Telemetry; +using System.Collections.Frozen; -#if DEBUG +#if !DEBUG using System.Linq; #endif @@ -16,6 +17,15 @@ namespace Microsoft.VisualStudio.Razor.Telemetry; internal abstract class TelemetryReporter : ITelemetryReporter { + private const string CodeAnalysisNamespace = nameof(Microsoft) + "." + nameof(CodeAnalysis); + private const string AspNetCoreNamespace = nameof(Microsoft) + "." + nameof(AspNetCore); + + // Types that will not contribute to fault bucketing. Fully qualified name is + // required in order to match correctly. + private static readonly FrozenSet s_faultIgnoredTypeNames = new string[] { + "Microsoft.AspNetCore.Razor.NullableExtensions" + }.ToFrozenSet(); + protected ImmutableArray TelemetrySessions { get; set; } protected TelemetryReporter(ImmutableArray telemetrySessions = default) @@ -163,6 +173,11 @@ public void ReportFault(Exception exception, string? message, params object?[] @ return 0; }); + var (moduleName, methodName) = GetModifiedMethodNameFaultNames(exception); + faultEvent.SetFailureParameters( + failureParameter1: moduleName, + failureParameter2: methodName); + Report(faultEvent); } catch (Exception) @@ -170,11 +185,87 @@ public void ReportFault(Exception exception, string? message, params object?[] @ } } + private static (string?, string?) GetModifiedMethodNameFaultNames(Exception exception) + { + var frame = WalkStack(exception, frame => + { + var method = frame?.GetMethod(); + var methodName = method?.Name; + if (methodName is null) + { + return false; + } + + var declaringTypeName = method?.DeclaringType?.FullName; + if (declaringTypeName == null) + { + return false; + } + + if (!declaringTypeName.StartsWith(CodeAnalysisNamespace) && + !declaringTypeName.StartsWith(AspNetCoreNamespace)) + { + return false; + } + + if (s_faultIgnoredTypeNames.Contains(declaringTypeName)) + { + return false; + } + + return true; + }); + + var method = frame?.GetMethod(); + if (method is null) + { + return (null, null); + } + + return (method.Module.Name, method.Name); + } + private static string GetExceptionDetails(Exception exception) { - const string CodeAnalysisNamespace = nameof(Microsoft) + "." + nameof(CodeAnalysis); - const string AspNetCoreNamespace = nameof(Microsoft) + "." + nameof(AspNetCore); + var frame = WalkStack(exception, frame => + { + var method = frame?.GetMethod(); + var methodName = method?.Name; + if (methodName is null) + { + return false; + } + + var declaringTypeName = method?.DeclaringType?.FullName; + if (declaringTypeName == null) + { + return false; + } + + if (!declaringTypeName.StartsWith(CodeAnalysisNamespace) && + !declaringTypeName.StartsWith(AspNetCoreNamespace)) + { + return false; + } + return true; + }); + + var method = frame?.GetMethod(); + + var declaringTypeName = method?.DeclaringType?.FullName; + var methodName = method?.Name; + + if (declaringTypeName is null || methodName is null) + { + return exception.Message; + } + + return declaringTypeName + "." + methodName; + } + + private static StackFrame? WalkStack(Exception exception, Func predicate) + { // Be resilient to failing here. If we can't get a suitable name, just fall back to the standard name we // used to report. try @@ -188,42 +279,26 @@ private static string GetExceptionDetails(Exception exception) { foreach (var frame in frames) { - var method = frame?.GetMethod(); - var methodName = method?.Name; - if (methodName is null) + if (predicate(frame)) { - continue; + return frame; } - - var declaringTypeName = method?.DeclaringType?.FullName; - if (declaringTypeName == null) - { - continue; - } - - if (!declaringTypeName.StartsWith(CodeAnalysisNamespace) && - !declaringTypeName.StartsWith(AspNetCoreNamespace)) - { - continue; - } - - return declaringTypeName + "." + methodName; } } + + return null; } catch { + return null; } - - // If we couldn't get a stack, do this - return exception.Message; } protected virtual void Report(TelemetryEvent telemetryEvent) { try { -#if !DEBUG +#if DEBUG foreach (var session in TelemetrySessions) { session.PostEvent(telemetryEvent); From 9ab93ee20e23d62485d40ec104d851f795ec3683 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Tue, 24 Sep 2024 16:39:24 -0700 Subject: [PATCH 2/9] Update method name and add small description --- .../Telemetry/TelemetryReporter.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 0e23b3bda8d..4a8b681a526 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -173,7 +173,7 @@ public void ReportFault(Exception exception, string? message, params object?[] @ return 0; }); - var (moduleName, methodName) = GetModifiedMethodNameFaultNames(exception); + var (moduleName, methodName) = GetModifiedFaultParameters(exception); faultEvent.SetFailureParameters( failureParameter1: moduleName, failureParameter2: methodName); @@ -185,7 +185,11 @@ public void ReportFault(Exception exception, string? message, params object?[] @ } } - private static (string?, string?) GetModifiedMethodNameFaultNames(Exception exception) + /// + /// Returns values that should be set to (failureParameter1, failureParameter2) when reporting a fault. + /// Those values represent the blamed stackframe module and method name. + /// + private static (string?, string?) GetModifiedFaultParameters(Exception exception) { var frame = WalkStack(exception, frame => { From 8bc1f54732d90b5cb5231630bf6eae303b3307ac Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Tue, 24 Sep 2024 16:42:59 -0700 Subject: [PATCH 3/9] Fix the pragma --- .../Telemetry/TelemetryReporter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 4a8b681a526..6b72c26e3bf 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Razor.Telemetry; using System.Collections.Frozen; -#if !DEBUG +#if DEBUG using System.Linq; #endif @@ -302,7 +302,7 @@ protected virtual void Report(TelemetryEvent telemetryEvent) { try { -#if DEBUG +#if !DEBUG foreach (var session in TelemetrySessions) { session.PostEvent(telemetryEvent); From 1676a547a517314e891d9e03f980192ff193e266 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 25 Sep 2024 12:06:10 -0700 Subject: [PATCH 4/9] Usings --- .../Telemetry/TelemetryReporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6b72c26e3bf..3130e72b2ab 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -5,9 +5,9 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Collections.Frozen; using Microsoft.VisualStudio.Telemetry; using Microsoft.AspNetCore.Razor.Telemetry; -using System.Collections.Frozen; #if DEBUG using System.Linq; From 43b885d265879ab92b553b7fcc222de167e17f35 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 25 Sep 2024 12:18:53 -0700 Subject: [PATCH 5/9] Actual usings fix --- .../Telemetry/TelemetryReporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3130e72b2ab..ae999521854 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -2,10 +2,10 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; -using System.Collections.Frozen; using Microsoft.VisualStudio.Telemetry; using Microsoft.AspNetCore.Razor.Telemetry; From 275cbfd4aff8ae7a9e53d65ec23ae1edcaed8be7 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 25 Sep 2024 13:28:28 -0700 Subject: [PATCH 6/9] Feedback and add test --- .../Telemetry/TelemetryReporter.cs | 234 +++++++++--------- .../Telemetry/TelemetryReporterTests.cs | 21 ++ 2 files changed, 142 insertions(+), 113 deletions(-) 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 ae999521854..b917e1c904d 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -8,6 +8,8 @@ using System.Diagnostics; using Microsoft.VisualStudio.Telemetry; using Microsoft.AspNetCore.Razor.Telemetry; +using Microsoft.AspNetCore.Razor; + #if DEBUG using System.Linq; @@ -19,6 +21,7 @@ internal abstract class TelemetryReporter : ITelemetryReporter { private const string CodeAnalysisNamespace = nameof(Microsoft) + "." + nameof(CodeAnalysis); private const string AspNetCoreNamespace = nameof(Microsoft) + "." + nameof(AspNetCore); + private const string MicrosoftVSRazorNamespace = $"{nameof(Microsoft)}.{nameof(VisualStudio)}.{nameof(Razor)}"; // Types that will not contribute to fault bucketing. Fully qualified name is // required in order to match correctly. @@ -185,119 +188,6 @@ public void ReportFault(Exception exception, string? message, params object?[] @ } } - /// - /// Returns values that should be set to (failureParameter1, failureParameter2) when reporting a fault. - /// Those values represent the blamed stackframe module and method name. - /// - private static (string?, string?) GetModifiedFaultParameters(Exception exception) - { - var frame = WalkStack(exception, frame => - { - var method = frame?.GetMethod(); - var methodName = method?.Name; - if (methodName is null) - { - return false; - } - - var declaringTypeName = method?.DeclaringType?.FullName; - if (declaringTypeName == null) - { - return false; - } - - if (!declaringTypeName.StartsWith(CodeAnalysisNamespace) && - !declaringTypeName.StartsWith(AspNetCoreNamespace)) - { - return false; - } - - if (s_faultIgnoredTypeNames.Contains(declaringTypeName)) - { - return false; - } - - return true; - }); - - var method = frame?.GetMethod(); - if (method is null) - { - return (null, null); - } - - return (method.Module.Name, method.Name); - } - - private static string GetExceptionDetails(Exception exception) - { - var frame = WalkStack(exception, frame => - { - var method = frame?.GetMethod(); - var methodName = method?.Name; - if (methodName is null) - { - return false; - } - - var declaringTypeName = method?.DeclaringType?.FullName; - if (declaringTypeName == null) - { - return false; - } - - if (!declaringTypeName.StartsWith(CodeAnalysisNamespace) && - !declaringTypeName.StartsWith(AspNetCoreNamespace)) - { - return false; - } - - return true; - }); - - var method = frame?.GetMethod(); - - var declaringTypeName = method?.DeclaringType?.FullName; - var methodName = method?.Name; - - if (declaringTypeName is null || methodName is null) - { - return exception.Message; - } - - return declaringTypeName + "." + methodName; - } - - private static StackFrame? WalkStack(Exception exception, Func predicate) - { - // Be resilient to failing here. If we can't get a suitable name, just fall back to the standard name we - // used to report. - try - { - // walk up the stack looking for the first call from a type that isn't in the ErrorReporting namespace. - var frames = new StackTrace(exception).GetFrames(); - - // On the .NET Framework, GetFrames() can return null even though it's not documented as such. - // At least one case here is if the exception's stack trace itself is null. - if (frames != null) - { - foreach (var frame in frames) - { - if (predicate(frame)) - { - return frame; - } - } - } - - return null; - } - catch - { - return null; - } - } - protected virtual void Report(TelemetryEvent telemetryEvent) { try @@ -376,4 +266,122 @@ public TelemetryScope TrackLspRequest(string lspMethodName, string languageServe new("eventscope.languageservername", languageServerName), new("eventscope.correlationid", correlationId)); } + + + /// + /// Returns values that should be set to (failureParameter1, failureParameter2) when reporting a fault. + /// Those values represent the blamed stackframe module and method name. + /// + internal static (string?, string?) GetModifiedFaultParameters(Exception exception) + { + var frame = FindFirstRazorStackFrame(exception, static (declaringTypeName, _) => + { + if (s_faultIgnoredTypeNames.Contains(declaringTypeName)) + { + return false; + } + + return true; + }); + + var method = frame?.GetMethod(); + if (method is null) + { + return (null, null); + } + + return (method.Module.Name, method.Name); + } + + private static string GetExceptionDetails(Exception exception) + { + var frame = FindFirstRazorStackFrame(exception); + + if (frame is null) + { + return exception.Message; + } + + var method = frame.GetMethod(); + + // These are checked in FindFirstRazorStackFrame + method.AssumeNotNull(); + method.DeclaringType.AssumeNotNull(); + + var declaringTypeName = method.DeclaringType.FullName; + var methodName = method.Name; + + return declaringTypeName + "." + methodName; + } + + /// + /// Finds the first stack frame in exception stack that originates from razor code based on namespace + /// + /// The exception to get the stack from + /// Optional predicate to filter by declaringTypeName and methodName + /// + private static StackFrame? FindFirstRazorStackFrame( + Exception exception, + Func? predicate = null) + { + // Be resilient to failing here. If we can't get a suitable name, just fall back to the standard name we + // used to report. + try + { + // walk up the stack looking for the first call from a type that isn't in the ErrorReporting namespace. + var frames = new StackTrace(exception).GetFrames(); + + // On the .NET Framework, GetFrames() can return null even though it's not documented as such. + // At least one case here is if the exception's stack trace itself is null. + if (frames != null) + { + foreach (var frame in frames) + { + if (frame is null) + { + continue; + } + + var method = frame.GetMethod(); + var methodName = method?.Name; + if (methodName is null) + { + continue; + } + + var declaringTypeName = method?.DeclaringType?.FullName; + if (declaringTypeName == null) + { + continue; + } + + if (!IsInOwnedNamespace(declaringTypeName)) + { + continue; + } + + if (predicate is null) + { + return frame; + } + + if (predicate(declaringTypeName, methodName)) + { + return frame; + } + } + } + + return null; + } + catch + { + return null; + } + } + + private static bool IsInOwnedNamespace(string declaringTypeName) + => declaringTypeName.StartsWith(CodeAnalysisNamespace) || + declaringTypeName.StartsWith(AspNetCoreNamespace) || + declaringTypeName.StartsWith(MicrosoftVSRazorNamespace); } 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 50fa4623eba..39a12e83b78 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 @@ -2,7 +2,9 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Telemetry; using Microsoft.AspNetCore.Razor.Test.Common; using Microsoft.VisualStudio.Editor.Razor.Test.Shared; @@ -392,4 +394,23 @@ public void ReportFault_InnerMostExceptionIsOperationCanceledException_SkipsFaul // Assert Assert.Empty(reporter.Events); } + + [Theory, MemberData(nameof(s_throwFunctions))] + public void GetModifiedFaultParameters_FiltersCorrectly(Func throwAction) + { + try + { + throwAction(); + } + catch (Exception ex) + { + var (param1, param2) = TestTelemetryReporter.GetModifiedFaultParameters(ex); + Assert.Equal("Microsoft.VisualStudio.LanguageServices.Razor.Test.dll", param1); + Assert.Equal("<.cctor>b__20_0", param2); + } + } + + public static readonly IEnumerable s_throwFunctions = [ + [() => ((object?)null).AssumeNotNull()] + ]; } From 3ac3268e192e66e7cdc0b8911928ce02d023ca74 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 25 Sep 2024 14:35:04 -0700 Subject: [PATCH 7/9] Modify the test to be resilient to valid values --- .../Telemetry/TelemetryReporterTests.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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 39a12e83b78..ec9b8dc6962 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 @@ -405,8 +405,21 @@ public void GetModifiedFaultParameters_FiltersCorrectly(Func throwAction catch (Exception ex) { var (param1, param2) = TestTelemetryReporter.GetModifiedFaultParameters(ex); + Assert.Equal("Microsoft.VisualStudio.LanguageServices.Razor.Test.dll", param1); - Assert.Equal("<.cctor>b__20_0", param2); + Assert.NotNull(param2); + + // Depending on compilation the stack can contain a constructor or + // a call to this method. We expect one or the other and both + // are valid + if (param2.StartsWith("GetModifiedFaultParameters")) + { + Assert.Equal("GetModifiedFaultParameters_FiltersCorrect", param2); + } + else + { + Assert.StartsWith("<.cctor>", param2); + } } } From 9d98bc709c4d20be78b40ff7184893b948f4dbbc Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 25 Sep 2024 15:46:29 -0700 Subject: [PATCH 8/9] Module should be without file extension --- .../Telemetry/TelemetryReporter.cs | 5 ++++- .../Telemetry/TelemetryReporterTests.cs | 17 +++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) 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 b917e1c904d..fafad026813 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -9,6 +9,8 @@ using Microsoft.VisualStudio.Telemetry; using Microsoft.AspNetCore.Razor.Telemetry; using Microsoft.AspNetCore.Razor; +using System.IO; + #if DEBUG @@ -290,7 +292,8 @@ internal static (string?, string?) GetModifiedFaultParameters(Exception exceptio return (null, null); } - return (method.Module.Name, method.Name); + var moduleName = Path.GetFileNameWithoutExtension(method.Module.Name); + return (moduleName, method.Name); } private static string GetExceptionDetails(Exception exception) 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 ec9b8dc6962..0f269a51b9a 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 @@ -406,20 +406,17 @@ public void GetModifiedFaultParameters_FiltersCorrectly(Func throwAction { var (param1, param2) = TestTelemetryReporter.GetModifiedFaultParameters(ex); - Assert.Equal("Microsoft.VisualStudio.LanguageServices.Razor.Test.dll", param1); + Assert.Equal("Microsoft.VisualStudio.LanguageServices.Razor.Test", param1); Assert.NotNull(param2); - // Depending on compilation the stack can contain a constructor or + // Depending on debug/release the stack can contain a constructor or // a call to this method. We expect one or the other and both // are valid - if (param2.StartsWith("GetModifiedFaultParameters")) - { - Assert.Equal("GetModifiedFaultParameters_FiltersCorrect", param2); - } - else - { - Assert.StartsWith("<.cctor>", param2); - } +#if DEBUG + Assert.StartsWith("<.cctor>", param2); +#else + Assert.Equal("GetModifiedFaultParameters_FiltersCorrectly", param2); +#endif } } From 1f4b057de5889aac1b3277911882870c1a7e5385 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 25 Sep 2024 16:35:44 -0700 Subject: [PATCH 9/9] Apply suggestions from code review --- .../Telemetry/TelemetryReporter.cs | 1 - 1 file changed, 1 deletion(-) 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 fafad026813..8b268f4b9ec 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -12,7 +12,6 @@ using System.IO; - #if DEBUG using System.Linq; #endif