Use a multi-proc aware MSBuild logger (#8371)

Make use of the MSBuild distributed logger functionality and add a
forwarding logger. When in a multi-proc build, the forwarding logger
will decide which events to forward to the main node to be logged.
Without this, all events are routed and a perf penalty is incurred.
This commit is contained in:
Andy Gerlicher 2018-01-11 15:30:56 -08:00 committed by Nick Guerrera
parent ed2ca5d49a
commit 2b3ade043d
4 changed files with 51 additions and 7 deletions

View file

@ -28,11 +28,12 @@ namespace Microsoft.DotNet.Tools.MSBuild
try try
{ {
Type loggerType = typeof(MSBuildLogger); Type loggerType = typeof(MSBuildLogger);
Type forwardingLoggerType = typeof(MSBuildForwardingLogger);
return argsToForward return argsToForward
.Concat(new[] .Concat(new[]
{ {
$"/Logger:{loggerType.FullName},{loggerType.GetTypeInfo().Assembly.Location}" $"/distributedlogger:{loggerType.FullName},{loggerType.GetTypeInfo().Assembly.Location}*{forwardingLoggerType.FullName},{forwardingLoggerType.GetTypeInfo().Assembly.Location}"
}); });
} }
catch (Exception) catch (Exception)

View file

@ -0,0 +1,36 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.Build.Framework;
namespace Microsoft.DotNet.Tools.MSBuild
{
public sealed class MSBuildForwardingLogger : IForwardingLogger
{
public LoggerVerbosity Verbosity { get; set; }
public string Parameters { get; set; }
public IEventRedirector BuildEventRedirector { get; set; }
public int NodeId { get; set; }
public void Initialize(IEventSource eventSource)
{
// Only forward telemetry events
if (eventSource is IEventSource2 eventSource2)
{
eventSource2.TelemetryLogged += (sender, args) => BuildEventRedirector.ForwardEvent(args);
}
}
public void Initialize(IEventSource eventSource, int nodeCount)
{
Initialize(eventSource);
}
public void Shutdown()
{
}
}
}

View file

@ -11,7 +11,7 @@ using System.Collections.Generic;
namespace Microsoft.DotNet.Tools.MSBuild namespace Microsoft.DotNet.Tools.MSBuild
{ {
public sealed class MSBuildLogger : Logger public sealed class MSBuildLogger : INodeLogger
{ {
private readonly IFirstTimeUseNoticeSentinel _sentinel = private readonly IFirstTimeUseNoticeSentinel _sentinel =
new FirstTimeUseNoticeSentinel(new CliFolderPathCalculator()); new FirstTimeUseNoticeSentinel(new CliFolderPathCalculator());
@ -38,7 +38,12 @@ namespace Microsoft.DotNet.Tools.MSBuild
} }
} }
public override void Initialize(IEventSource eventSource) public void Initialize(IEventSource eventSource, int nodeCount)
{
Initialize(eventSource);
}
public void Initialize(IEventSource eventSource)
{ {
try try
{ {
@ -76,7 +81,7 @@ namespace Microsoft.DotNet.Tools.MSBuild
FormatAndSend(_telemetry, args); FormatAndSend(_telemetry, args);
} }
public override void Shutdown() public void Shutdown()
{ {
try try
{ {
@ -86,8 +91,10 @@ namespace Microsoft.DotNet.Tools.MSBuild
{ {
// Exceptions during telemetry shouldn't cause anything else to fail // Exceptions during telemetry shouldn't cause anything else to fail
} }
base.Shutdown();
} }
public LoggerVerbosity Verbosity { get; set; }
public string Parameters { get; set; }
} }
} }

View file

@ -138,7 +138,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
allArgs.Should().NotBeNull(); allArgs.Should().NotBeNull();
allArgs.Should().Contain( allArgs.Should().Contain(
value => value.IndexOf("/Logger", StringComparison.OrdinalIgnoreCase) >= 0, value => value.IndexOf("/distributedlogger", StringComparison.OrdinalIgnoreCase) >= 0,
"The MSBuild logger argument should be specified when telemetry is enabled."); "The MSBuild logger argument should be specified when telemetry is enabled.");
} }
} }