Skip to content

Make TerminalLogger capable of acting as a ForwardingLogger, and use it to implement SourceRoot-based relative paths for out-of-tree projects#12082

Merged
baronfel merged 11 commits intomainfrom
tl-forwarding-take-2
Aug 5, 2025
Merged

Make TerminalLogger capable of acting as a ForwardingLogger, and use it to implement SourceRoot-based relative paths for out-of-tree projects#12082
baronfel merged 11 commits intomainfrom
tl-forwarding-take-2

Conversation

@baronfel
Copy link
Copy Markdown
Member

@baronfel baronfel commented Jun 29, 2025

Fixes #9806

Context

This is another take on making TL a forwarding logger. I've gotten it much better this time - it's working in multi-node setups consistently on my machine, and I was able to get the Target Outputs for targets that I care about after a bit of work. We can make this more efficient be filtering down the Target Outputs at the forwarding level maybe? Yep! That was easy enough to do.

Changes Made

  • Made a Forwarding Terminal Logger
  • Hooked it up in the distributed logger registration for multi node scenarios
  • Plumbed through a knob for enabling Target Outputs to be logged in the build parameters, node configuration, logging server, etc. and toggled that knob on for TL-using scenarios
  • Used this infra to accurately get the Source Roots for the projects, so that when builds happen outside of the CWD and inside the Source Root we can render a relative path between the CWD and the Source Root as the 'anchor' for the project outputs
  • From this base we can do many of the data-based enhancements (NuGet package detection?!) that we've wanted to do.

Testing

Manual testing - the test case is building a solution from a project that is a sibling of that solution (so same parent, but different directory), building with /m:8.

image

Notes

TODO:

  • Tests
  • Perf comparison? This will likely be a mixed bag because we should be emitting fewer events from the child loggers, but some of the events may contain more data.
  • Reviews/cleanup

@baronfel baronfel changed the title TL forwarding take 2 Make TerminalLogger capable of acting as a ForwardingLogger, and use it to implement SourceRoot-based relative paths for out-of-tree projects Jun 29, 2025
@baronfel baronfel self-assigned this Jun 29, 2025
@baronfel baronfel added the Area: Terminal Logger Problems with the livelogger/fancylogger/terminallogger -tl functionality. label Jun 29, 2025
@baronfel baronfel marked this pull request as ready for review June 30, 2025 14:24
Copilot AI review requested due to automatic review settings June 30, 2025 14:24
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request extends the TerminalLogger functionality to act as a ForwardingLogger and introduces support for SourceRoot-based relative paths for out‐of‐tree projects while propagating a new enableTargetOutputLogging flag throughout the build system.

  • Added an optional enableTargetOutputLogging parameter to several project building methods and integrated it into project collection and logging service instantiation.
  • Introduced a new SourceRoot property in TerminalProjectInfo and updated TerminalLogger to choose a relative display path based on the working directory or source root.
  • Updated tests and configuration in various components, including the Distributed Logger registration, node configuration, and command-line switch handling.

Reviewed Changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/UnitTests.Shared/ObjectModelHelpers.cs Added a parameter for target output logging to build helper methods.
src/MSBuild/XMake.cs Propagated the new logging flag and introduced a specialized forwarding logger record.
src/Build/Logging/TerminalLogger/TerminalLogger.cs Updated path rendering logic to support relative paths via SourceRoot.
src/Build/Definition/ProjectCollection.cs Added enableTargetOutputLogging support and event triggering in the properties.
src/Build/BackEnd/Node/*.cs and Logging components Updated logging service, node configuration and related tests to support the new flag.
src/Build.UnitTests/* Converted tests to [Theory]/[InlineData] and updated target outputs verification.
src/Build.UnitTests/BackEnd/MockLoggingService.cs Updated mock implementation to include the logging flag (returns fixed false).
Comments suppressed due to low confidence (1)

src/UnitTests.Shared/ObjectModelHelpers.cs:1343

  • [nitpick] Consider updating the XML documentation of BuildProjectWithNewOMExpectSuccess to describe the new enableTargetOutputLogging parameter and its effect on the build behavior.
        public static MockLogger BuildProjectWithNewOMExpectSuccess(string content, Dictionary<string, string> globalProperties = null, MockLogger logger = null, bool enableTargetOutputLogging = false)

Comment thread src/Build/Logging/TerminalLogger/TerminalLogger.cs
Comment thread src/Build.UnitTests/BackEnd/MockLoggingService.cs
Comment thread src/Build.UnitTests/BackEnd/TargetEntry_Tests.cs
Comment thread src/Build.UnitTests/BackEnd/TargetEntry_Tests.cs
Comment thread src/Build/BackEnd/BuildManager/BuildManager.cs
Comment thread src/Build/BackEnd/Components/Logging/TargetLoggingContext.cs Outdated
Comment thread src/Build/Definition/ProjectCollection.cs
Comment thread src/Build/Instance/ProjectInstance.cs
Comment thread src/Build/Logging/TerminalLogger/ForwardingTerminalLogger.cs
Comment thread src/Build/Logging/TerminalLogger/ForwardingTerminalLogger.cs
Comment thread src/Build/Logging/TerminalLogger/ForwardingTerminalLogger.cs
Comment thread src/Build/Logging/TerminalLogger/TerminalLogger.cs
Comment thread src/Build/Logging/TerminalLogger/TerminalLogger.cs
Comment thread src/MSBuild/XMake.cs
Comment thread src/MSBuild/XMake.cs Outdated
Comment thread src/Build.UnitTests/BackEnd/TargetEntry_Tests.cs Outdated
Copy link
Copy Markdown
Member

@SimaTian SimaTian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've run into an issue. Long story short, I'm having trouble with validating if the behavior of the environment variable stays consistent with what was happening before:

In logging TargetLoggingContext.cs
Before, the s_enableTargetOutputLogging was directly affected by the environment variable.

Now, the same behavior depends on
LoggingService.EnableTargetOutputLogging
which as you state here: https://github.com/dotnet/msbuild/pull/12082/files#r2191360984
can be set up from many places.

So to validate the consistency, it is now necessary to check if all the previous endpoints are referencing both the property(which is new, so it won't break anyone) and the old env var.

I understand and support the addition of command line parameter.
Moving from environment variable to Trait that is populated by the environment variable is good.

With that in mind, can we keep both the old tests(with env var) and the new tests going forward?
I'm not sure what the probability of someone depending on the env var is but it could be a pain if we break someone because he depended on it (and we failed to fully transfer the behavior)

Alternatively we could do
if (!LoggingService.OnlyLogCriticalEvents && (LoggingService.EnableTargetOutputLogging || Traits.Instance.EnableTargetOutputLogging) && targetOutputs != null)
and call it good enough. Although I admit it's kind of ugly.

Initially I though "this is due to the PR being too big, we need to split it". However after some consideration, I've come to conclusion that the core issue would stay the same even in a split scenario, so it won't actually help.

@baronfel
Copy link
Copy Markdown
Member Author

baronfel commented Jul 8, 2025

Good call @SimaTian - I'll see if I can flow the Trait check into a central location to preserve the existing behavior as a fallback.

@baronfel
Copy link
Copy Markdown
Member Author

Alternatively we could do if (!LoggingService.OnlyLogCriticalEvents && (LoggingService.EnableTargetOutputLogging || Traits.Instance.EnableTargetOutputLogging) && targetOutputs != null) and call it good enough. Although I admit it's kind of ugly.

It may be ugly, but it's also the most central location I could find! I've added new permutations of the tests that now also stress the environment variable pathway so that we have parity. Note now that if a user set the env var explicitly to false while the TL was configured, we would still emit the events due to the TL requiring them.

@SimaTian
Copy link
Copy Markdown
Member

SimaTian commented Jul 28, 2025

I think the new tests (because of the env var)

This plagues my sidecar tests that are based on env var as well. I still don't have a reasonable solution so I've had to disable the tests in the meantime, which is annoying.
The behavior is mostly the same - locally all green, in pipelines quite flaky, no matter how I attempt to force any sort of decent behavior. If you figure anything out, please let me know. I will also look into it since it is vexing.

@baronfel baronfel force-pushed the tl-forwarding-take-2 branch from 49df8da to 522ec2e Compare July 29, 2025 15:46
@baronfel
Copy link
Copy Markdown
Member Author

The failing tests are green on my machine - I don't have a theory for the failures yet.

@baronfel baronfel force-pushed the tl-forwarding-take-2 branch from 522ec2e to fe50034 Compare July 30, 2025 16:33
@baronfel
Copy link
Copy Markdown
Member Author

I dug in a bit, and the pipelines are using the cibuild_bootstrapped_msbuild scripts to run the tests, so I did the same locally. Those tests also worked. I can only imaging that there's some kind of pinned/broken state here? Maybe I can try resetting the trait explicitly in the tests?

baronfel added 4 commits July 31, 2025 11:26
* Made a Forwarding Terminal Logger for the non-central build nodes
* Hooked it up in the distributed logger registration for multi node scenarios
* Plumbed through a knob for enabling Target Outputs to be logged in the build parameters, node configuration, logging server, etc. and toggled that knob on for TL-using scenarios
* Used this infra to accurately get the Source Roots for the projects, so that when builds happen outside of the CWD and inside the Source Root we can render a relative path between the CWD and the Source Root as the 'anchor' for the project outputs
* From this base we can do many of the data-based enhancements (NuGet package detection?!) that we've wanted to do.
@baronfel baronfel force-pushed the tl-forwarding-take-2 branch from fe50034 to b568440 Compare July 31, 2025 16:26
@baronfel baronfel requested a review from a team as a code owner July 31, 2025 16:41
Copy link
Copy Markdown
Member

@SimaTian SimaTian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue I've raised has been addressed and rest was(and continues to be) fine.
Thank you @YuliiaKovalova for resolving the test issues.

Comment thread src/Build/Logging/BinaryLogger/BinaryLogger.cs
these tests shouldn't be impacted, we have some env var state corruption
@baronfel baronfel merged commit 7335100 into main Aug 5, 2025
9 checks passed
@baronfel baronfel deleted the tl-forwarding-take-2 branch August 5, 2025 19:24
YuliiaKovalova pushed a commit that referenced this pull request Aug 7, 2025
…king change (#12296)

### Context
#12082 introduced a
binary-breaking change to the ProjectCollection constructors, which is
breaking VMR codeflow at dotnet/dotnet#1764.

### Changes Made

Made the new change in a binary-compatible way by adding the old
constructor signature and forwarding to the new constructor with a
default value set for the new parameter. This also meant that we get to
remove the CompatibilitySuppression, which should have been a red flag
in the first place.
baronfel added a commit that referenced this pull request Sep 18, 2025
### Context
This change builds on #12082 by
listening to the project evaluation finished event and getting RID usage
data for the current Target. We then use this RID data to render the RID
(if any) on project status lines.

This is sliced out of #12114 to
make that PR smaller and focused on the 'new output kind detection'
feature.

### Changes Made

* Create a container for all eval-related data we capture for a project
* associate that container with a TerminalProjectInfo (since each
TerminalProjectInfo uses data from a given evaluation (paired by ID)
* make output rendering for projects more factored out for easier
reading
* include the RID in the output

### Testing

Updated existing node tests.
Manual testing.

<img width="1347" height="327" alt="image"
src="https://github.com/user-attachments/assets/39014bee-5616-4d93-883f-a55a933f0c3d"
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Terminal Logger Problems with the livelogger/fancylogger/terminallogger -tl functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Convert Terminal Logger to a ForwardingLogger

4 participants