From 1bda7e6bad87e6a8ce44fa1cf37726a824a74e80 Mon Sep 17 00:00:00 2001 From: Joe Schmitt <1146681+schmittjoseph@users.noreply.github.com> Date: Mon, 28 Aug 2023 08:54:46 -0700 Subject: [PATCH] [Parameter Capturing] Add more helpful messages when feature unavailable (#5200) --- .../CaptureParametersOperation.cs | 43 ++++++++++++----- src/Tools/dotnet-monitor/Strings.Designer.cs | 47 +++++++++++++++---- src/Tools/dotnet-monitor/Strings.resx | 18 +++++-- 3 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs b/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs index 2bf58687e65..6f4b79c74b3 100644 --- a/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs +++ b/src/Tools/dotnet-monitor/ParameterCapturing/CaptureParametersOperation.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.Globalization; using System.Threading; using System.Threading.Tasks; @@ -49,35 +50,51 @@ public static bool IsEndpointRuntimeSupported(IEndpointInfo endpointInfo) return endpointInfo.RuntimeVersion != null && endpointInfo.RuntimeVersion.Major >= 7; } - private async Task CanEndpointProcessRequestsAsync(CancellationToken token) + private async Task EnsureEndpointCanProcessRequestsAsync(CancellationToken token) { + static Exception getNotAvailableException(string reason) + { + return new MonitoringException(string.Format( + CultureInfo.InvariantCulture, + Strings.ErrorMessage_ParameterCapturingNotAvailable, + reason)); + } + + if (!IsEndpointRuntimeSupported(_endpointInfo)) + { + throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_UnsupportedRuntime); + } + DiagnosticsClient client = new(_endpointInfo.Endpoint); IDictionary env = await client.GetProcessEnvironmentAsync(token); + const string PreventHostingStartupEnvName = "ASPNETCORE_PREVENTHOSTINGSTARTUP"; + if (env.TryGetValue(PreventHostingStartupEnvName, out string preventHostingStartupEnvValue) && + ToolIdentifiers.IsEnvVarValueEnabled(preventHostingStartupEnvValue)) + { + throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_PreventedHostingStartup); + } + if (!env.TryGetValue(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.ManagedMessaging, out string isManagedMessagingAvailable) || - !env.TryGetValue(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.HostingStartup, out string isHostingStartupAvailable)) + !ToolIdentifiers.IsEnvVarValueEnabled(isManagedMessagingAvailable)) { - return false; + throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_ManagedMessagingDidNotLoad); } - return ToolIdentifiers.IsEnvVarValueEnabled(isManagedMessagingAvailable) && ToolIdentifiers.IsEnvVarValueEnabled(isHostingStartupAvailable); + if (!env.TryGetValue(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.HostingStartup, out string isHostingStartupAvailable) || + !ToolIdentifiers.IsEnvVarValueEnabled(isHostingStartupAvailable)) + { + throw getNotAvailableException(Strings.ParameterCapturingNotAvailable_Reason_HostingStartupDidNotLoad); + } } public async Task ExecuteAsync(CancellationToken token) { try { - if (!IsEndpointRuntimeSupported(_endpointInfo)) - { - throw new MonitoringException(Strings.ErrorMessage_ParameterCapturingRequiresAtLeastNet7); - } - // Check if the endpoint is capable of responding to our requests - if (!await CanEndpointProcessRequestsAsync(token)) - { - throw new MonitoringException(Strings.ErrorMessage_ParameterCapturingNotAvailable); - } + await EnsureEndpointCanProcessRequestsAsync(token); EventParameterCapturingPipelineSettings settings = new() { diff --git a/src/Tools/dotnet-monitor/Strings.Designer.cs b/src/Tools/dotnet-monitor/Strings.Designer.cs index 0d54b6b1517..f51a5f966c4 100644 --- a/src/Tools/dotnet-monitor/Strings.Designer.cs +++ b/src/Tools/dotnet-monitor/Strings.Designer.cs @@ -421,7 +421,7 @@ internal static string ErrorMessage_OperationIsNotStoppable { } /// - /// Looks up a localized string similar to Parameter capturing is not available in the process.. + /// Looks up a localized string similar to Parameter capturing is not available in the process. {0}. /// internal static string ErrorMessage_ParameterCapturingNotAvailable { get { @@ -429,15 +429,6 @@ internal static string ErrorMessage_ParameterCapturingNotAvailable { } } - /// - /// Looks up a localized string similar to Parameter capturing is not available in the process, the process needs to be using .NET 7 or newer.. - /// - internal static string ErrorMessage_ParameterCapturingRequiresAtLeastNet7 { - get { - return ResourceManager.GetString("ErrorMessage_ParameterCapturingRequiresAtLeastNet7", resourceCulture); - } - } - /// /// Looks up a localized string similar to The {0} parameter value '{1}' is not allowed.. /// @@ -1699,6 +1690,42 @@ internal static string Message_ShowSources { } } + /// + /// Looks up a localized string similar to This feature is only available on processes using ASP.NET Core. If the process is using ASP.NET Core and has successfully started, ensure that it has not been configured to prevent hosting startup assemblies from loading.. + /// + internal static string ParameterCapturingNotAvailable_Reason_HostingStartupDidNotLoad { + get { + return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_HostingStartupDidNotLoad", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An internal error occurred that has prevented communication with the process.. + /// + internal static string ParameterCapturingNotAvailable_Reason_ManagedMessagingDidNotLoad { + get { + return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_ManagedMessagingDidNotLoad", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The process has prevented hosting startup assemblies from loading using the ASPNETCORE_PREVENTHOSTINGSTARTUP environment variable.. + /// + internal static string ParameterCapturingNotAvailable_Reason_PreventedHostingStartup { + get { + return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_PreventedHostingStartup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The process needs to be using .NET 7 or newer.. + /// + internal static string ParameterCapturingNotAvailable_Reason_UnsupportedRuntime { + get { + return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_UnsupportedRuntime", resourceCulture); + } + } + /// /// Looks up a localized string similar to :NOT PRESENT:. /// diff --git a/src/Tools/dotnet-monitor/Strings.resx b/src/Tools/dotnet-monitor/Strings.resx index dffb2e9da28..10eb2d719a5 100644 --- a/src/Tools/dotnet-monitor/Strings.resx +++ b/src/Tools/dotnet-monitor/Strings.resx @@ -942,9 +942,21 @@ The shared file '{0}' is different from source file '{1}'. - Parameter capturing is not available in the process. + Parameter capturing is not available in the process. {0} + Gets the format string for parameter capturing not being available +1 Format Parameters: +0. reason: The reason why the feature is unavailable. - - Parameter capturing is not available in the process, the process needs to be using .NET 7 or newer. + + The process has prevented hosting startup assemblies from loading using the ASPNETCORE_PREVENTHOSTINGSTARTUP environment variable. + + + This feature is only available on processes using ASP.NET Core. If the process is using ASP.NET Core and has successfully started, ensure that it has not been configured to prevent hosting startup assemblies from loading. + + + An internal error occurred that has prevented communication with the process. + + + The process needs to be using .NET 7 or newer. \ No newline at end of file