This commit is contained in:
Claudiu Guiman 2024-05-31 13:47:41 -04:00 коммит произвёл GitHub
Родитель 2f5379b377
Коммит 3bd2c0f9d1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
41 изменённых файлов: 41 добавлений и 601 удалений

Просмотреть файл

@ -131,8 +131,6 @@ Content-Type: application/x-ndjson
- The target application must use ASP.NET Core.
- The target application cannot have [Hot Reload](https://learn.microsoft.com/visualstudio/debugger/hot-reload) enabled.
- `dotnet-monitor` must be set to `Listen` mode, and the target application must start suspended. See [diagnostic port configuration](../configuration/diagnostic-port-configuration.md) for information on how to do this.
- The target application must have [`ILogger`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger) available via [ASP.NET Core's dependency injection](https://learn.microsoft.com/aspnet/core/fundamentals/dependency-injection).
- This feature relies on a hosting startup assembly. If the target application [disabled automatic loading](https://learn.microsoft.com/aspnet/core/fundamentals/host/platform-specific-configuration#disable-automatic-loading-of-hosting-startup-assemblies) of these, this feature will not be available.
- This feature relies on a [ICorProfilerCallback](https://docs.microsoft.com/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-interface) implementation. If the target application is already using an `ICorProfiler` that isn't notify-only, this feature will not be available.
- If a target application is using .NET 7 then the `dotnet-monitor` startup hook must be configured. This is automatically done in .NET 8+.

Просмотреть файл

@ -70,10 +70,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Monit
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{D3FEE1C0-E1E7-4796-A217-B46E3B6CCCCD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Monitoring.HostingStartup", "src\Microsoft.Diagnostics.Monitoring.HostingStartup\Microsoft.Diagnostics.Monitoring.HostingStartup.csproj", "{86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests", "src\Tests\Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests\Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests.csproj", "{B9216DD7-F216-490A-A388-BBE0EC946EF2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -188,14 +184,6 @@ Global
{E7EA323B-0CFE-4D42-9844-4C322A3BC54A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7EA323B-0CFE-4D42-9844-4C322A3BC54A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7EA323B-0CFE-4D42-9844-4C322A3BC54A}.Release|Any CPU.Build.0 = Release|Any CPU
{86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86BDA5CD-6A18-4EC2-9F13-F1A2723DD864}.Release|Any CPU.Build.0 = Release|Any CPU
{B9216DD7-F216-490A-A388-BBE0EC946EF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B9216DD7-F216-490A-A388-BBE0EC946EF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9216DD7-F216-490A-A388-BBE0EC946EF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9216DD7-F216-490A-A388-BBE0EC946EF2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -231,8 +219,6 @@ Global
{72EC615C-E1BE-4D27-A0FC-C0FEE483D3D2} = {19FAB78C-3351-4911-8F0C-8C6056401740}
{E7EA323B-0CFE-4D42-9844-4C322A3BC54A} = {C7568468-1C79-4944-8136-18812A7F9EA7}
{D3FEE1C0-E1E7-4796-A217-B46E3B6CCCCD} = {19FAB78C-3351-4911-8F0C-8C6056401740}
{86BDA5CD-6A18-4EC2-9F13-F1A2723DD864} = {19FAB78C-3351-4911-8F0C-8C6056401740}
{B9216DD7-F216-490A-A388-BBE0EC946EF2} = {C7568468-1C79-4944-8136-18812A7F9EA7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46465737-C938-44FC-BE1A-4CE139EBB5E0}

Просмотреть файл

@ -3,7 +3,6 @@
<Import Project="$(RepoRoot)src\archives\dotnet-monitor-base\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\archives\AzureBlobStorage\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\archives\S3Storage\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\Microsoft.Diagnostics.Monitoring.HostingStartup\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\Microsoft.Diagnostics.Monitoring.StartupHook\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\singlefile\dotnet-monitor\ProjectsToPublish.props" />

Просмотреть файл

@ -1,31 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.AspNetCore.Hosting;
using Microsoft.Diagnostics.Monitoring.HostingStartup;
using Microsoft.Diagnostics.Tools.Monitor;
using Microsoft.Diagnostics.Tools.Monitor.HostingStartup;
using System.Threading;
[assembly: HostingStartup(typeof(HostingStartup))]
namespace Microsoft.Diagnostics.Monitoring.HostingStartup
{
internal sealed class HostingStartup : IHostingStartup
{
public static int InvocationCount;
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Keep track of how many times this hosting startup has been invoked for easy
// validation in tests.
Interlocked.Increment(ref InvocationCount);
// TODO: remove the HostingStartup project.
});
ToolIdentifiers.EnableEnvVar(InProcessFeaturesIdentifiers.EnvironmentVariables.AvailableInfrastructure.HostingStartup);
}
}
}

Просмотреть файл

@ -1,45 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Intentionally pinned. This feature is supported in projects targeting 6.0 or newer. -->
<TargetFramework>net6.0</TargetFramework>
<IsShippingAssembly>true</IsShippingAssembly>
<OutputType>Library</OutputType>
<DefineConstants>$(DefineConstants);HOSTINGSTARTUP</DefineConstants>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Tools\dotnet-monitor\ParameterCapturing\ParameterCapturingEvents.cs" Link="ParameterCapturing\Eventing\ParameterCapturingEvents.cs" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.UnitTestApp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Diagnostics.Monitoring.StartupHook\Microsoft.Diagnostics.Monitoring.StartupHook.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="ParameterCapturing\ParameterCapturingStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ParameterCapturingStrings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="ParameterCapturing\ParameterCapturingStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ParameterCapturingStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

Просмотреть файл

@ -1,15 +0,0 @@
<Project>
<PropertyGroup>
<HostingStartupTargetFramework>net6.0</HostingStartupTargetFramework>
<HostingStartupLibraryName>Microsoft.Diagnostics.Monitoring.HostingStartup</HostingStartupLibraryName>
<HostingStartupPublishPath>$(ArtifactsDir)pub\$(HostingStartupLibraryName)\$(Configuration)\$(HostingStartupTargetFramework)\</HostingStartupPublishPath>
<HostingStartupLibraryPath>$(HostingStartupPublishPath)$(HostingStartupLibraryName).dll</HostingStartupLibraryPath>
<HostingStartupSymbolsPath>$(HostingStartupPublishPath)$(HostingStartupLibraryName).pdb</HostingStartupSymbolsPath>
</PropertyGroup>
<ItemGroup Condition="'$(SkipPlatformNeutralPublish)' != 'true'">
<ProjectToPublish Include="$(MSBuildThisFileDirectory)Microsoft.Diagnostics.Monitoring.HostingStartup.csproj">
<!-- The RuntimeIdentifier is intentionally left blank to get a platform-neutral publish output. -->
<AdditionalProperties>TargetFramework=$(HostingStartupTargetFramework);RuntimeIdentifier=;PublishDir=$(HostingStartupPublishPath)</AdditionalProperties>
</ProjectToPublish>
</ItemGroup>
</Project>

Просмотреть файл

@ -3,7 +3,7 @@
using System.Text.Json.Serialization;
#if STARTUPHOOK || HOSTINGSTARTUP
#if STARTUPHOOK
namespace Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models
#else
namespace Microsoft.Diagnostics.Monitoring.Options

Просмотреть файл

@ -1,69 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
namespace Microsoft.Diagnostics.Monitoring.StartupHook
{
internal sealed class AspNetHostingStartupLoader : IDisposable
{
private readonly string _filePath;
private readonly string _simpleAssemblyName;
private long _disposedState;
public AspNetHostingStartupLoader(string filePath)
{
_filePath = filePath;
_simpleAssemblyName = CalculateSimpleAssemblyName(filePath);
RegisterHostingStartupAssembly(_simpleAssemblyName);
AssemblyLoadContext.Default.Resolving += AssemblyResolver;
}
private Assembly? AssemblyResolver(AssemblyLoadContext context, AssemblyName assemblyName)
{
if (_simpleAssemblyName.Equals(assemblyName.Name, StringComparison.OrdinalIgnoreCase))
{
return AssemblyLoadContext.Default.LoadFromAssemblyPath(_filePath);
}
return null;
}
private static string CalculateSimpleAssemblyName(string filePath)
{
string fileName = Path.GetFileName(filePath);
const string dllExtension = ".dll";
if (dllExtension.Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase))
{
return fileName[..^dllExtension.Length];
}
return fileName;
}
private static void RegisterHostingStartupAssembly(string simpleAssemblyName)
{
const string HostingStartupEnvVariable = "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES";
// aspnetcore explicitly uses ; as the delimiter for the above environment variable.
// ref: https://github.com/dotnet/aspnetcore/blob/898c164a1f537a8210a26eaf388bdc92531f6b09/src/Hosting/Hosting/src/Internal/WebHostOptions.cs#L79
const char Delimiter = ';';
string? curValue = Environment.GetEnvironmentVariable(HostingStartupEnvVariable);
string newValue = string.IsNullOrWhiteSpace(curValue) ? simpleAssemblyName : string.Concat(curValue, Delimiter, simpleAssemblyName);
Environment.SetEnvironmentVariable(HostingStartupEnvVariable, newValue);
}
public void Dispose()
{
if (!DisposableHelper.CanDispose(ref _disposedState))
return;
AssemblyLoadContext.Default.Resolving -= AssemblyResolver;
}
}
}

Просмотреть файл

@ -5,11 +5,9 @@ using Microsoft.Diagnostics.Monitoring.StartupHook.Exceptions;
using Microsoft.Diagnostics.Monitoring.StartupHook.Monitoring;
using Microsoft.Diagnostics.Monitoring.StartupHook.ParameterCapturing;
using Microsoft.Diagnostics.Tools.Monitor;
using Microsoft.Diagnostics.Tools.Monitor.HostingStartup;
using Microsoft.Diagnostics.Tools.Monitor.Profiler;
using Microsoft.Diagnostics.Tools.Monitor.StartupHook;
using System;
using System.IO;
using MessageDispatcher = Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher;
namespace Microsoft.Diagnostics.Monitoring.StartupHook
@ -18,7 +16,6 @@ namespace Microsoft.Diagnostics.Monitoring.StartupHook
IDisposable
{
private readonly CurrentAppDomainExceptionProcessor _exceptionProcessor;
private readonly AspNetHostingStartupLoader? _hostingStartupLoader;
private readonly ParameterCapturingService? _parameterCapturingService;
private long _disposedState;
@ -30,13 +27,6 @@ namespace Microsoft.Diagnostics.Monitoring.StartupHook
using IDisposable _ = MonitorExecutionContextTracker.MonitorScope();
string? hostingStartupPath = Environment.GetEnvironmentVariable(StartupHookIdentifiers.EnvironmentVariables.HostingStartupPath);
// TODO: Log if specified hosting startup assembly doesn't exist
if (File.Exists(hostingStartupPath))
{
_hostingStartupLoader = new AspNetHostingStartupLoader(hostingStartupPath);
}
try
{
// Check that the profiler is loaded before establishing the dispatcher, which has a dependency on the existence of the profiler
@ -68,7 +58,6 @@ namespace Microsoft.Diagnostics.Monitoring.StartupHook
_exceptionProcessor.Dispose();
_parameterCapturingService?.Stop();
_parameterCapturingService?.Dispose();
_hostingStartupLoader?.Dispose();
SharedInternals.MessageDispatcher?.Dispose();
}
}

Просмотреть файл

@ -14,7 +14,6 @@
<Compile Include="..\Microsoft.Diagnostics.Monitoring.WebApi\Stacks\NameIdentificationEvents.cs" Link="Exceptions\Eventing\NameIdentificationEvents.cs" />
<Compile Include="..\Tools\dotnet-monitor\DisposableHelper.cs" Link="DisposableHelper.cs" />
<Compile Include="..\Tools\dotnet-monitor\Exceptions\ExceptionEvents.cs" Link="Exceptions\Eventing\ExceptionEvents.cs" />
<Compile Include="..\Tools\dotnet-monitor\StartupHook\StartupHookIdentifiers.cs" Link="StartupHookIdentifiers.cs" />
<Compile Include="..\Tools\dotnet-monitor\ToolIdentifiers.cs" Link="ToolIdentifiers.cs" />
<Compile Include="..\Tools\dotnet-monitor\InProcessFeatures\InProcessFeaturesIdentifiers.cs" Link="InProcessFeaturesIdentifiers.cs" />
<Compile Include="..\Tools\dotnet-monitor\ParameterCapturing\ParameterCapturingEvents.cs" Link="ParameterCapturing\Eventing\ParameterCapturingEvents.cs" />
@ -27,9 +26,7 @@
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.StartupHook.UnitTests" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.HostingStartup" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.UnitTestApp" />
</ItemGroup>

Просмотреть файл

@ -10,8 +10,6 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi
bool IsStartupHookRequired { get; }
bool IsHostingStartupRequired { get; }
bool IsLibrarySharingRequired { get; }
}
}

Просмотреть файл

@ -5,11 +5,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Text;
#if HOSTINGSTARTUP
namespace Microsoft.Diagnostics.Monitoring.HostingStartup
#else
namespace Microsoft.Diagnostics.Monitoring.WebApi
#endif
{
// Logger implementations have different ways of serializing log scopes. This class helps those loggers
// serialize the scope information in the best way possible for each of the implementations.

Просмотреть файл

@ -2,14 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
#if HOSTINGSTARTUP
namespace Microsoft.Diagnostics.Monitoring.HostingStartup
#else
using System.Globalization;
namespace Microsoft.Diagnostics.Monitoring.WebApi
#endif
{
internal static class KeyValueLogScopeExtensions
{
@ -17,7 +12,7 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi
{
values.Add(new KeyValuePair<string, object>(key, value));
}
#if !HOSTINGSTARTUP
public static void AddArtifactType(this KeyValueLogScope scope, string artifactType)
{
scope.Values.Add("ArtifactType", artifactType);
@ -32,6 +27,5 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi
ArtifactMetadataNames.ArtifactSource.RuntimeInstanceCookie,
endpointInfo.RuntimeInstanceCookie.ToString("N"));
}
#endif
}
}

Просмотреть файл

@ -5,7 +5,7 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
#if STARTUPHOOK || HOSTINGSTARTUP
#if STARTUPHOOK
namespace Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models
#else
namespace Microsoft.Diagnostics.Monitoring.WebApi.Models

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using System.ComponentModel.DataAnnotations;
#if STARTUPHOOK || HOSTINGSTARTUP
#if STARTUPHOOK
namespace Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models
#else
using Microsoft.Diagnostics.Monitoring.Options;

Просмотреть файл

@ -6,7 +6,7 @@ using System.Text;
using System.Text.Json;
#if STARTUPHOOK || HOSTINGSTARTUP
#if STARTUPHOOK
namespace Microsoft.Diagnostics.Monitoring.StartupHook.Monitoring
#else
namespace Microsoft.Diagnostics.Monitoring
@ -29,9 +29,6 @@ namespace Microsoft.Diagnostics.Monitoring
Callstack
};
/// <summary>
/// Shared between the StartupHook and HostingStartup assembly.
/// </summary>
public enum StartupHookCommand : ushort
{
StartCapturingParameters,

Просмотреть файл

@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(TestTargetFrameworks)</TargetFrameworks>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Microsoft.Diagnostics.Monitoring.HostingStartup\Microsoft.Diagnostics.Monitoring.HostingStartup.csproj" />
<ProjectReference Include="..\Microsoft.Diagnostics.Monitoring.TestCommon\Microsoft.Diagnostics.Monitoring.TestCommon.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -33,7 +33,6 @@
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.Tool.UnitTests" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.AzureBlobStorageTests.UnitTests" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.HostingStartup.UnitTests" />
<InternalsVisibleTo Include="Microsoft.Diagnostics.Monitoring.UnitTestApp" />
</ItemGroup>

Просмотреть файл

@ -120,18 +120,6 @@ namespace Microsoft.Diagnostics.Monitoring.TestCommon
}
}
public static class HostingStartup
{
public const string Name = nameof(HostingStartup);
public static class SubScenarios
{
public const string VerifyAspNetAppWithoutHostingStartup = nameof(VerifyAspNetAppWithoutHostingStartup);
public const string VerifyAspNetApp = nameof(VerifyAspNetApp);
public const string VerifyNonAspNetAppNotImpacted = nameof(VerifyNonAspNetAppNotImpacted);
}
}
public static class Stacks
{
public const string Name = nameof(Stacks);

Просмотреть файл

@ -4,7 +4,7 @@
using Microsoft.Diagnostics.Monitoring.TestCommon;
using Microsoft.Diagnostics.Monitoring.TestCommon.Runners;
using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Fixtures;
using Microsoft.Diagnostics.Tools.Monitor.HostingStartup;
using Microsoft.Diagnostics.Tools.Monitor.StartupHook;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Linq;

Просмотреть файл

@ -1,62 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Diagnostics.Monitoring.TestCommon;
using Microsoft.Diagnostics.Monitoring.TestCommon.Options;
using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Fixtures;
using Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests.Runners;
using Microsoft.Diagnostics.Monitoring.WebApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace Microsoft.Diagnostics.Monitoring.Tool.FunctionalTests
{
[TargetFrameworkMonikerTrait(TargetFrameworkMonikerExtensions.CurrentTargetFrameworkMoniker)]
[Collection(DefaultCollectionFixture.Name)]
public class HostingStartupTests
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ITestOutputHelper _outputHelper;
public HostingStartupTests(ITestOutputHelper outputHelper, ServiceProviderFixture serviceProviderFixture)
{
_httpClientFactory = serviceProviderFixture.ServiceProvider.GetService<IHttpClientFactory>();
_outputHelper = outputHelper;
}
[Theory]
[InlineData(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetApp, true)]
[InlineData(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetAppWithoutHostingStartup, false)]
[InlineData(TestAppScenarios.HostingStartup.SubScenarios.VerifyNonAspNetAppNotImpacted, true)]
public async Task HostingStartupLoadTests(string subScenario, bool tryLoadHostingStartup)
{
await ScenarioRunner.SingleTarget(
_outputHelper,
_httpClientFactory,
DiagnosticPortConnectionMode.Listen,
TestAppScenarios.HostingStartup.Name,
appValidate: (runner, client) => { return Task.CompletedTask; },
configureApp: runner =>
{
runner.EnableMonitorStartupHook = true;
},
configureTool: runner =>
{
runner.ConfigurationFromEnvironment.EnableInProcessFeatures();
// Enable a feature that requires the hosting startup assembly.
runner.ConfigurationFromEnvironment.InProcessFeatures.ParameterCapturing = new()
{
Enabled = tryLoadHostingStartup
};
},
profilerLogLevel: LogLevel.Trace,
subScenarioName: subScenario);
}
}
}

Просмотреть файл

@ -85,7 +85,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Microsoft.Diagnostics.Monitoring.HostingStartup\Microsoft.Diagnostics.Monitoring.HostingStartup.csproj" />
<ProjectReference Include="..\..\Microsoft.Diagnostics.Monitoring.Options\Microsoft.Diagnostics.Monitoring.Options.csproj" />
<ProjectReference Include="..\..\Microsoft.Diagnostics.Monitoring.StartupHook\Microsoft.Diagnostics.Monitoring.StartupHook.csproj" />
<ProjectReference Include="..\..\Microsoft.Diagnostics.Monitoring.WebApi\Microsoft.Diagnostics.Monitoring.WebApi.csproj" />

Просмотреть файл

@ -4,7 +4,7 @@
using Microsoft.Diagnostics.Monitoring.TestCommon;
using Microsoft.Diagnostics.Monitoring.TestCommon.Runners;
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tools.Monitor.HostingStartup;
using Microsoft.Diagnostics.Tools.Monitor.StartupHook;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;

Просмотреть файл

@ -12,7 +12,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Microsoft.Diagnostics.Monitoring.HostingStartup\Microsoft.Diagnostics.Monitoring.HostingStartup.csproj" />
<ProjectReference Include="..\..\Microsoft.Diagnostics.Monitoring.StartupHook\Microsoft.Diagnostics.Monitoring.StartupHook.csproj" />
<ProjectReference Include="..\Microsoft.Diagnostics.Monitoring.TestCommon\Microsoft.Diagnostics.Monitoring.TestCommon.csproj" />
</ItemGroup>

Просмотреть файл

@ -22,7 +22,6 @@ namespace Microsoft.Diagnostics.Monitoring.UnitTestApp
FunctionProbesScenario.Command(),
LoggerScenario.Command(),
ParameterCapturingScenario.Command(),
HostingStartupScenario.Command(),
SpinWaitScenario.Command(),
EnvironmentVariablesScenario.Command(),
StacksScenario.Command(),

Просмотреть файл

@ -1,81 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Diagnostics.Monitoring.TestCommon;
using Microsoft.Extensions.DependencyInjection;
using System.CommandLine;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Diagnostics.Monitoring.UnitTestApp.Scenarios
{
internal sealed class HostingStartupScenario
{
public static CliCommand Command()
{
CliCommand aspnetAppNoHostingStartupCommand = new(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetAppWithoutHostingStartup);
aspnetAppNoHostingStartupCommand.SetAction(VerifyAspNetAppWithoutHostingStartupAsync);
CliCommand aspnetAppCommand = new(TestAppScenarios.HostingStartup.SubScenarios.VerifyAspNetApp);
aspnetAppCommand.SetAction(VerifyAspNetAppAsync);
CliCommand nonAspNetAppCommand = new(TestAppScenarios.HostingStartup.SubScenarios.VerifyNonAspNetAppNotImpacted);
nonAspNetAppCommand.SetAction(VerifyNonAspNetAppNotImpactedAsync);
CliCommand scenarioCommand = new(TestAppScenarios.HostingStartup.Name);
scenarioCommand.Subcommands.Add(aspnetAppNoHostingStartupCommand);
scenarioCommand.Subcommands.Add(aspnetAppCommand);
scenarioCommand.Subcommands.Add(nonAspNetAppCommand);
return scenarioCommand;
}
public static Task<int> VerifyNonAspNetAppNotImpactedAsync(ParseResult result, CancellationToken token)
{
return ScenarioHelpers.RunScenarioAsync(logger =>
{
Assert.Equal(0, HostingStartup.HostingStartup.InvocationCount);
return Task.FromResult(0);
}, token);
}
public static Task<int> VerifyAspNetAppWithoutHostingStartupAsync(ParseResult result, CancellationToken token)
{
return ScenarioHelpers.RunWebScenarioAsync<Startup>(logger =>
{
Assert.Equal(0, HostingStartup.HostingStartup.InvocationCount);
return Task.FromResult(0);
}, token);
}
public static Task<int> VerifyAspNetAppAsync(ParseResult result, CancellationToken token)
{
return ScenarioHelpers.RunWebScenarioAsync<Startup>(logger =>
{
Assert.Equal(1, HostingStartup.HostingStartup.InvocationCount);
return Task.FromResult(0);
}, token);
}
private sealed class Startup
{
public static void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", () => Results.Ok());
});
}
}
}
}

Просмотреть файл

@ -133,7 +133,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.Commands
services.ConfigureLibrarySharing();
services.ConfigureProfiler();
services.ConfigureStartupHook();
services.ConfigureHostingStartup();
services.ConfigureExceptions();
services.ConfigureStartupLoggers(authConfigurator);
services.ConfigureInProcessFeatures(context.Configuration);

Просмотреть файл

@ -1,91 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Diagnostics.Monitoring.WebApi;
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tools.Monitor.LibrarySharing;
using Microsoft.Diagnostics.Tools.Monitor.StartupHook;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup
{
internal sealed class HostingStartupService
: IDiagnosticLifetimeService
{
// Intent is to ship a single TFM of the hosting startup, which should be the lowest supported version.
private const string HostingStartupFileName = "Microsoft.Diagnostics.Monitoring.HostingStartup.dll";
private const string HostingStartupTargetFramework = "net6.0";
private readonly IEndpointInfo _endpointInfo;
private readonly StartupHookService _startupHookService;
private readonly IInProcessFeatures _inProcessFeatures;
private readonly ISharedLibraryService _sharedLibraryService;
private readonly ILogger<HostingStartupService> _logger;
public HostingStartupService(
IEndpointInfo endpointInfo,
StartupHookService startupHookService,
ISharedLibraryService sharedLibraryService,
IInProcessFeatures inProcessFeatures,
ILogger<HostingStartupService> logger)
{
_endpointInfo = endpointInfo;
_startupHookService = startupHookService;
_inProcessFeatures = inProcessFeatures;
_sharedLibraryService = sharedLibraryService;
_logger = logger;
}
public async ValueTask StartAsync(CancellationToken cancellationToken)
{
if (!_inProcessFeatures.IsHostingStartupRequired)
{
return;
}
// Hosting startup is only supported on .NET 6+
if (_endpointInfo.RuntimeVersion == null || _endpointInfo.RuntimeVersion.Major < 6)
{
return;
}
try
{
// Hosting startup requires the startup hook
if (!await _startupHookService.Applied.WaitAsync(cancellationToken))
{
return;
}
IFileProviderFactory fileProviderFactory = await _sharedLibraryService.GetFactoryAsync(cancellationToken);
IFileProvider managedFileProvider = fileProviderFactory.CreateManaged(HostingStartupTargetFramework);
IFileInfo hostingStartupLibraryFileInfo = managedFileProvider.GetFileInfo(HostingStartupFileName);
if (!hostingStartupLibraryFileInfo.Exists)
{
throw new FileNotFoundException(Strings.ErrorMessage_UnableToFindHostingStartupAssembly, hostingStartupLibraryFileInfo.Name);
}
DiagnosticsClient client = new DiagnosticsClient(_endpointInfo.Endpoint);
await client.SetEnvironmentVariableAsync(
StartupHookIdentifiers.EnvironmentVariables.HostingStartupPath,
hostingStartupLibraryFileInfo.PhysicalPath,
cancellationToken);
}
catch (Exception ex)
{
_logger.UnableToApplyHostingStartup(ex);
}
}
public ValueTask StopAsync(CancellationToken cancellationToken)
{
return ValueTask.CompletedTask;
}
}
}

Просмотреть файл

@ -32,10 +32,8 @@ namespace Microsoft.Diagnostics.Tools.Monitor
public bool IsMutatingProfilerRequired => IsParameterCapturingEnabled;
public bool IsStartupHookRequired => IsHostingStartupRequired || IsExceptionsEnabled;
public bool IsStartupHookRequired => IsParameterCapturingEnabled || IsExceptionsEnabled;
public bool IsHostingStartupRequired => IsParameterCapturingEnabled;
public bool IsLibrarySharingRequired => IsProfilerRequired || IsStartupHookRequired || IsHostingStartupRequired;
public bool IsLibrarySharingRequired => IsProfilerRequired || IsStartupHookRequired;
}
}

Просмотреть файл

@ -5,7 +5,7 @@ using Microsoft.Diagnostics.Monitoring.WebApi;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup
namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook
{
internal sealed class InProcessFeaturesEndpointInfoSourceCallbacks : IEndpointInfoSourceCallbacks
{

Просмотреть файл

@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup
namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook
{
public static class InProcessFeaturesIdentifiers
{
@ -26,7 +26,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup
private const string AvailableInfrastructurePrefix = InProcessFeaturesPrefix + "AvailableInfrastructure_";
public const string ManagedMessaging = AvailableInfrastructurePrefix + nameof(ManagedMessaging);
public const string StartupHook = AvailableInfrastructurePrefix + nameof(StartupHook);
public const string HostingStartup = AvailableInfrastructurePrefix + nameof(HostingStartup);
}
}
}

Просмотреть файл

@ -11,7 +11,7 @@ using System;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Diagnostics.Tools.Monitor.HostingStartup
namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook
{
internal sealed class InProcessFeaturesService
{

Просмотреть файл

@ -512,12 +512,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor
logLevel: LogLevel.Debug,
formatString: Strings.LogFormatString_EndpointRemovalFailed);
private static readonly Action<ILogger, Exception> _unableToApplyHostingStartup =
LoggerMessage.Define(
eventId: LoggingEventIds.UnableToApplyHostingStartup.EventId(),
logLevel: LogLevel.Error,
formatString: Strings.LogFormatString_UnableToApplyHostingStartup);
private static readonly Action<ILogger, Exception> _unableToApplyInProcessFeatureFlags =
LoggerMessage.Define(
eventId: LoggingEventIds.UnableToApplyInProcessFeatureFlags.EventId(),
@ -954,11 +948,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor
_endpointRemovalFailed(logger, processId, ex);
}
public static void UnableToApplyHostingStartup(this ILogger logger, Exception ex)
{
_unableToApplyHostingStartup(logger, ex);
}
public static void UnableToApplyInProcessFeatureFlags(this ILogger logger, Exception ex)
{
_unableToApplyInProcessFeatureFlags(logger, ex);

Просмотреть файл

@ -6,8 +6,8 @@ using Microsoft.Diagnostics.Monitoring.Options;
using Microsoft.Diagnostics.Monitoring.WebApi;
using Microsoft.Diagnostics.Monitoring.WebApi.Models;
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tools.Monitor.HostingStartup;
using Microsoft.Diagnostics.Tools.Monitor.Profiler;
using Microsoft.Diagnostics.Tools.Monitor.StartupHook;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@ -94,13 +94,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing
IDictionary<string, string> 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) ||
!ToolIdentifiers.IsEnvVarValueEnabled(isManagedMessagingAvailable))
{

Просмотреть файл

@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#if STARTUPHOOK || HOSTINGSTARTUP
#if STARTUPHOOK
using Microsoft.Diagnostics.Monitoring.StartupHook.MonitorMessageDispatcher.Models;
#else
using Microsoft.Diagnostics.Monitoring.WebApi.Models;

Просмотреть файл

@ -26,7 +26,6 @@ using Microsoft.Diagnostics.Tools.Monitor.Egress.Extension;
using Microsoft.Diagnostics.Tools.Monitor.Egress.FileSystem;
using Microsoft.Diagnostics.Tools.Monitor.Exceptions;
using Microsoft.Diagnostics.Tools.Monitor.Extensibility;
using Microsoft.Diagnostics.Tools.Monitor.HostingStartup;
using Microsoft.Diagnostics.Tools.Monitor.LibrarySharing;
using Microsoft.Diagnostics.Tools.Monitor.ParameterCapturing;
using Microsoft.Diagnostics.Tools.Monitor.Profiler;
@ -358,13 +357,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor
return services;
}
public static IServiceCollection ConfigureHostingStartup(this IServiceCollection services)
{
services.AddScoped<HostingStartupService>();
services.AddScopedForwarder<IDiagnosticLifetimeService, HostingStartupService>();
return services;
}
public static IServiceCollection ConfigureStartupHook(this IServiceCollection services)
{
services.AddScoped<StartupHookApplicator>();

Просмотреть файл

@ -1,16 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.Diagnostics.Tools.Monitor.StartupHook
{
public static class StartupHookIdentifiers
{
public static class EnvironmentVariables
{
private const string StartupHookPrefix = ToolIdentifiers.StandardPrefix + "StartupHook_";
// The full path of a HostingStartup assembly to load into a target process.
public const string HostingStartupPath = StartupHookPrefix + nameof(HostingStartupPath);
}
}
}

27
src/Tools/dotnet-monitor/Strings.Designer.cs сгенерированный
Просмотреть файл

@ -538,15 +538,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor {
}
}
/// <summary>
/// Looks up a localized string similar to Unable to find hosting startup assembly at determined path..
/// </summary>
internal static string ErrorMessage_UnableToFindHostingStartupAssembly {
get {
return ResourceManager.GetString("ErrorMessage_UnableToFindHostingStartupAssembly", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unable to find profiler assembly at determined path..
/// </summary>
@ -1519,15 +1510,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor {
}
}
/// <summary>
/// Looks up a localized string similar to Unable to apply hosting startup..
/// </summary>
internal static string LogFormatString_UnableToApplyHostingStartup {
get {
return ResourceManager.GetString("LogFormatString_UnableToApplyHostingStartup", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unable to apply in process feature flags..
/// </summary>
@ -1672,15 +1654,6 @@ namespace Microsoft.Diagnostics.Tools.Monitor {
}
}
/// <summary>
/// Looks up a localized string similar to The process has prevented hosting startup assemblies from loading using the ASPNETCORE_PREVENTHOSTINGSTARTUP environment variable..
/// </summary>
internal static string ParameterCapturingNotAvailable_Reason_PreventedHostingStartup {
get {
return ResourceManager.GetString("ParameterCapturingNotAvailable_Reason_PreventedHostingStartup", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This feature requires the startup hook to be loaded in the target process..
/// </summary>

Просмотреть файл

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
@ -897,12 +897,6 @@
0. providerName: The name of the provider that failed validation.
1. errorMessage: The validation failure message</comment>
</data>
<data name="ErrorMessage_UnableToFindHostingStartupAssembly" xml:space="preserve">
<value>Unable to find hosting startup assembly at determined path.</value>
</data>
<data name="LogFormatString_UnableToApplyHostingStartup" xml:space="preserve">
<value>Unable to apply hosting startup.</value>
</data>
<data name="LogFormatString_UnableToApplyInProcessFeatureFlags" xml:space="preserve">
<value>Unable to apply in process feature flags.</value>
</data>
@ -927,9 +921,6 @@
1 Format Parameters:
0. reason: The reason why the feature is unavailable.</comment>
</data>
<data name="ParameterCapturingNotAvailable_Reason_PreventedHostingStartup" xml:space="preserve">
<value>The process has prevented hosting startup assemblies from loading using the ASPNETCORE_PREVENTHOSTINGSTARTUP environment variable.</value>
</data>
<data name="ParameterCapturingNotAvailable_Reason_StartupHookDidNotLoad" xml:space="preserve">
<value>This feature requires the startup hook to be loaded in the target process.</value>
</data>

Просмотреть файл

@ -73,7 +73,6 @@
<!-- Targets and properties for ensuring publish before pack. -->
<Import Project="$(RepoRoot)src\archives\AzureBlobStorage\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\archives\S3Storage\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\Microsoft.Diagnostics.Monitoring.HostingStartup\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\Microsoft.Diagnostics.Monitoring.StartupHook\ProjectsToPublish.props" />
<Import Project="$(RepositoryEngineeringDir)PublishProjects.targets" />
@ -118,13 +117,6 @@
<TfmSpecificPackageFile Include="$(StartupHookSymbolsPath)">
<PackagePath>tools/$(TargetFramework)/any/shared/any/$(StartupHookTargetFramework)</PackagePath>
</TfmSpecificPackageFile>
<!-- Pack hosting startup files -->
<TfmSpecificPackageFile Include="$(HostingStartupLibraryPath)">
<PackagePath>tools/$(TargetFramework)/any/shared/any/$(HostingStartupTargetFramework)</PackagePath>
</TfmSpecificPackageFile>
<TfmSpecificPackageFile Include="$(HostingStartupSymbolsPath)">
<PackagePath>tools/$(TargetFramework)/any/shared/any/$(HostingStartupTargetFramework)</PackagePath>
</TfmSpecificPackageFile>
<!-- Pack extension files -->
<TfmSpecificPackageFile Include="$(AzureBlobStoragePublishRootPath)$(TargetFramework)\any\**">

Просмотреть файл

@ -1,7 +1,6 @@
<Project>
<!-- Create dotnet-monitor product archive (RID and TFM specific) -->
<Import Project="$(MSBuildThisFileDirectory)ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\Microsoft.Diagnostics.Monitoring.HostingStartup\ProjectsToPublish.props" />
<Import Project="$(RepoRoot)src\Microsoft.Diagnostics.Monitoring.StartupHook\ProjectsToPublish.props" />
<PropertyGroup>
<ExecutableName>dotnet-monitor</ExecutableName>