diff --git a/eng/cibuild_bootstrapped_msbuild.ps1 b/eng/cibuild_bootstrapped_msbuild.ps1 index 8fb7f590527..6e22aacb0d3 100644 --- a/eng/cibuild_bootstrapped_msbuild.ps1 +++ b/eng/cibuild_bootstrapped_msbuild.ps1 @@ -53,6 +53,7 @@ $RepoRoot = [System.IO.Path]::GetFullPath($RepoRoot).TrimEnd($([System.IO.Path]: $ArtifactsDir = Join-Path $RepoRoot "artifacts" $Stage1Dir = Join-Path $RepoRoot "stage1" $Stage1BinDir = Join-Path $Stage1Dir "bin" +$PerfLogDir = Join-Path $ArtifactsDir "log\$Configuration\PerformanceLogs" if ($msbuildEngine -eq '') { @@ -123,6 +124,9 @@ try { # Ensure that debug bits fail fast, rather than hanging waiting for a debugger attach. $env:MSBUILDDONOTLAUNCHDEBUGGER="true" + # Opt into performance logging. https://github.com/dotnet/msbuild/issues/5900 + $env:DOTNET_PERFLOG_DIR=$PerfLogDir + # When using bootstrapped MSBuild: # - Turn off node reuse (so that bootstrapped MSBuild processes don't stay running and lock files) # - Do run tests diff --git a/eng/cibuild_bootstrapped_msbuild.sh b/eng/cibuild_bootstrapped_msbuild.sh index 23987f994d9..26fe13a7c82 100755 --- a/eng/cibuild_bootstrapped_msbuild.sh +++ b/eng/cibuild_bootstrapped_msbuild.sh @@ -39,6 +39,7 @@ done RepoRoot="$ScriptRoot/.." ArtifactsDir="$RepoRoot/artifacts" Stage1Dir="$RepoRoot/stage1" +PerfLogDir="$ArtifactsDir/log/$configuration/PerformanceLogs" . "$ScriptRoot/common/tools.sh" InitializeDotNetCli true @@ -86,6 +87,9 @@ mv $ArtifactsDir $Stage1Dir # Ensure that debug bits fail fast, rather than hanging waiting for a debugger attach. export MSBUILDDONOTLAUNCHDEBUGGER=true +# Opt into performance logging. +export DOTNET_PERFLOG_DIR=$PerfLogDir + # Prior to 3.0, the Csc task uses this environment variable to decide whether to run # a CLI host or directly execute the compiler. export DOTNET_HOST_PATH="$_InitializeDotNetCli/dotnet" diff --git a/src/MSBuild.UnitTests/PerfLog_Tests.cs b/src/MSBuild.UnitTests/PerfLog_Tests.cs index b39f192a446..be18d7b6a47 100644 --- a/src/MSBuild.UnitTests/PerfLog_Tests.cs +++ b/src/MSBuild.UnitTests/PerfLog_Tests.cs @@ -74,7 +74,7 @@ public void TestPerfLogEnabledProducedLogFile() } [Fact] - public void TestPerfLogDirectoryDoesNotExist() + public void TestPerfLogDirectoryGetsCreated() { using (TestEnvironment testEnv = TestEnvironment.Create(_output)) { @@ -101,7 +101,7 @@ public void TestPerfLogDirectoryDoesNotExist() RunnerUtilities.ExecMSBuild(msbuildParameters, out bool successfulExit); successfulExit.ShouldBeTrue(); - Directory.Exists(perfLogPath).ShouldBeFalse(); + Directory.Exists(perfLogPath).ShouldBeTrue(); } } } diff --git a/src/MSBuild/PerformanceLogEventListener.cs b/src/MSBuild/PerformanceLogEventListener.cs index a9ffec3aae4..b3857fd50f4 100644 --- a/src/MSBuild/PerformanceLogEventListener.cs +++ b/src/MSBuild/PerformanceLogEventListener.cs @@ -7,6 +7,7 @@ using System.IO; using System.Text; using Microsoft.Build.Eventing; +using Microsoft.Build.Shared; namespace Microsoft.Build.CommandLine { @@ -51,7 +52,8 @@ internal static PerformanceLogEventListener Create() // Check to see if we should enable the event listener. string logDirectory = Environment.GetEnvironmentVariable(PerfLogDirEnvVar); - if (Directory.Exists(logDirectory)) + + if (!string.IsNullOrEmpty(logDirectory) && Directory.CreateDirectory(logDirectory).Exists) { eventListener = new PerformanceLogEventListener(); eventListener.Initialize(logDirectory); diff --git a/src/Shared/UnitTests/TestAssemblyInfo.cs b/src/Shared/UnitTests/TestAssemblyInfo.cs index a325fb4cac4..e1e7ef66d5a 100644 --- a/src/Shared/UnitTests/TestAssemblyInfo.cs +++ b/src/Shared/UnitTests/TestAssemblyInfo.cs @@ -40,6 +40,10 @@ public MSBuildTestAssemblyFixture() // (VerifySubToolsetVersionSetByConstructorOverridable), as the environment variable would take precedence. _testEnvironment.SetEnvironmentVariable("VisualStudioVersion", string.Empty); + // Prevent test assemblies from logging any performance info. + // https://github.com/dotnet/msbuild/pull/6274 + _testEnvironment.SetEnvironmentVariable("DOTNET_PERFLOG_DIR", string.Empty); + SetDotnetHostPath(_testEnvironment); // Use a project-specific temporary path