diff --git a/src/Build.UnitTests/BackEnd/KnownTelemetry_Tests.cs b/src/Build.UnitTests/BackEnd/KnownTelemetry_Tests.cs index 3b7b1987f96..cfbf63deebd 100644 --- a/src/Build.UnitTests/BackEnd/KnownTelemetry_Tests.cs +++ b/src/Build.UnitTests/BackEnd/KnownTelemetry_Tests.cs @@ -49,8 +49,7 @@ public void BuildTelemetryConstructedHasNoProperties() buildTelemetry.Target.ShouldBeNull(); buildTelemetry.Version.ShouldBeNull(); - buildTelemetry.UpdateEventProperties(); - buildTelemetry.Properties.ShouldBeEmpty(); + buildTelemetry.GetProperties().ShouldBeEmpty(); } [Fact] @@ -75,22 +74,23 @@ public void BuildTelemetryCreateProperProperties() buildTelemetry.Target = "clean"; buildTelemetry.Version = new Version(1, 2, 3, 4); - buildTelemetry.UpdateEventProperties(); - buildTelemetry.Properties.Count.ShouldBe(11); + var properties = buildTelemetry.GetProperties(); - buildTelemetry.Properties["BuildEngineDisplayVersion"].ShouldBe("Some Display Version"); - buildTelemetry.Properties["BuildEngineFrameworkName"].ShouldBe("new .NET"); - buildTelemetry.Properties["BuildEngineHost"].ShouldBe("Host description"); - buildTelemetry.Properties["InitialMSBuildServerState"].ShouldBe("hot"); - buildTelemetry.Properties["ProjectPath"].ShouldBe(@"C:\\dev\\theProject"); - buildTelemetry.Properties["ServerFallbackReason"].ShouldBe("busy"); - buildTelemetry.Properties["BuildSuccess"].ShouldBe("True"); - buildTelemetry.Properties["BuildTarget"].ShouldBe("clean"); - buildTelemetry.Properties["BuildEngineVersion"].ShouldBe("1.2.3.4"); + properties.Count.ShouldBe(11); + + properties["BuildEngineDisplayVersion"].ShouldBe("Some Display Version"); + properties["BuildEngineFrameworkName"].ShouldBe("new .NET"); + properties["BuildEngineHost"].ShouldBe("Host description"); + properties["InitialMSBuildServerState"].ShouldBe("hot"); + properties["ProjectPath"].ShouldBe(@"C:\\dev\\theProject"); + properties["ServerFallbackReason"].ShouldBe("busy"); + properties["BuildSuccess"].ShouldBe("True"); + properties["BuildTarget"].ShouldBe("clean"); + properties["BuildEngineVersion"].ShouldBe("1.2.3.4"); // verify computed - buildTelemetry.Properties["BuildDurationInMilliseconds"] = (finishedAt - startAt).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); - buildTelemetry.Properties["InnerBuildDurationInMilliseconds"] = (finishedAt - innerStartAt).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); + properties["BuildDurationInMilliseconds"] = (finishedAt - startAt).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); + properties["InnerBuildDurationInMilliseconds"] = (finishedAt - innerStartAt).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); } [Fact] @@ -100,22 +100,18 @@ public void BuildTelemetryHandleNullsInRecordedTimes() buildTelemetry.StartAt = DateTime.MinValue; buildTelemetry.FinishedAt = null; - buildTelemetry.UpdateEventProperties(); - buildTelemetry.Properties.ShouldBeEmpty(); + buildTelemetry.GetProperties().ShouldBeEmpty(); buildTelemetry.StartAt = null; buildTelemetry.FinishedAt = DateTime.MaxValue; - buildTelemetry.UpdateEventProperties(); - buildTelemetry.Properties.ShouldBeEmpty(); + buildTelemetry.GetProperties().ShouldBeEmpty(); buildTelemetry.InnerStartAt = DateTime.MinValue; buildTelemetry.FinishedAt = null; - buildTelemetry.UpdateEventProperties(); - buildTelemetry.Properties.ShouldBeEmpty(); + buildTelemetry.GetProperties().ShouldBeEmpty(); buildTelemetry.InnerStartAt = null; buildTelemetry.FinishedAt = DateTime.MaxValue; - buildTelemetry.UpdateEventProperties(); - buildTelemetry.Properties.ShouldBeEmpty(); + buildTelemetry.GetProperties().ShouldBeEmpty(); } } diff --git a/src/Build.UnitTests/BackEnd/LoggingConfigurationTelemetry_Tests.cs b/src/Build.UnitTests/BackEnd/LoggingConfigurationTelemetry_Tests.cs index 27b30d71997..d6e66cc6ecd 100644 --- a/src/Build.UnitTests/BackEnd/LoggingConfigurationTelemetry_Tests.cs +++ b/src/Build.UnitTests/BackEnd/LoggingConfigurationTelemetry_Tests.cs @@ -40,8 +40,7 @@ public void BuildTelemetryConstructedHasNoProperties() telemetry.BinaryLogger.ShouldBe(false); telemetry.BinaryLoggerUsedDefaultName.ShouldBe(false); - telemetry.UpdateEventProperties(); - telemetry.Properties.Where(kv => kv.Value != bool.FalseString).ShouldBeEmpty(); + telemetry.GetProperties().Where(kv => kv.Value != bool.FalseString).ShouldBeEmpty(); } [Fact] @@ -65,21 +64,20 @@ public void BuildTelemetryCreateProperProperties() BinaryLoggerUsedDefaultName = true }; - telemetry.UpdateEventProperties(); - - telemetry.Properties["TerminalLogger"].ShouldBe(bool.TrueString); - telemetry.Properties["TerminalLoggerUserIntent"].ShouldBe("on"); - telemetry.Properties["TerminalLoggerUserIntentSource"].ShouldBe("arg"); - telemetry.Properties["TerminalLoggerDefault"].ShouldBe("auto"); - telemetry.Properties["TerminalLoggerDefaultSource"].ShouldBe("sdk"); - telemetry.Properties["ConsoleLogger"].ShouldBe(bool.TrueString); - telemetry.Properties["ConsoleLoggerType"].ShouldBe("serial"); - telemetry.Properties["ConsoleLoggerVerbosity"].ShouldBe("minimal"); - telemetry.Properties["FileLogger"].ShouldBe(bool.TrueString); - telemetry.Properties["FileLoggerType"].ShouldBe("serial"); - telemetry.Properties["FileLoggersCount"].ShouldBe("2"); - telemetry.Properties["FileLoggerVerbosity"].ShouldBe("normal"); - telemetry.Properties["BinaryLogger"].ShouldBe(bool.TrueString); - telemetry.Properties["BinaryLoggerUsedDefaultName"].ShouldBe(bool.TrueString); + var properties = telemetry.GetProperties(); + properties["TerminalLogger"].ShouldBe(bool.TrueString); + properties["TerminalLoggerUserIntent"].ShouldBe("on"); + properties["TerminalLoggerUserIntentSource"].ShouldBe("arg"); + properties["TerminalLoggerDefault"].ShouldBe("auto"); + properties["TerminalLoggerDefaultSource"].ShouldBe("sdk"); + properties["ConsoleLogger"].ShouldBe(bool.TrueString); + properties["ConsoleLoggerType"].ShouldBe("serial"); + properties["ConsoleLoggerVerbosity"].ShouldBe("minimal"); + properties["FileLogger"].ShouldBe(bool.TrueString); + properties["FileLoggerType"].ShouldBe("serial"); + properties["FileLoggersCount"].ShouldBe("2"); + properties["FileLoggerVerbosity"].ShouldBe("normal"); + properties["BinaryLogger"].ShouldBe(bool.TrueString); + properties["BinaryLoggerUsedDefaultName"].ShouldBe(bool.TrueString); } } diff --git a/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs b/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs index 791bd5332ee..6266cb6e4c7 100644 --- a/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs +++ b/src/Build.UnitTests/TerminalLoggerConfiguration_Tests.cs @@ -70,8 +70,7 @@ public void TerminalLoggerOn(string tlValue) FileLogger = false, }; - expectedTelemetry.UpdateEventProperties(); - foreach (KeyValuePair pair in expectedTelemetry.Properties) + foreach (KeyValuePair pair in expectedTelemetry.GetProperties()) { output.ShouldContain($"{expectedTelemetry.EventName}:{pair.Key}={pair.Value}"); } @@ -101,8 +100,7 @@ public void TerminalLoggerWithTlAutoIsOff(string tlValue) FileLogger = false, }; - expectedTelemetry.UpdateEventProperties(); - foreach (KeyValuePair pair in expectedTelemetry.Properties) + foreach (KeyValuePair pair in expectedTelemetry.GetProperties()) { output.ShouldContain($"{expectedTelemetry.EventName}:{pair.Key}={pair.Value}"); } @@ -129,8 +127,7 @@ public void TerminalLoggerDefaultByEnv() FileLogger = false, }; - expectedTelemetry.UpdateEventProperties(); - foreach (KeyValuePair pair in expectedTelemetry.Properties) + foreach (KeyValuePair pair in expectedTelemetry.GetProperties()) { output.ShouldContain($"{expectedTelemetry.EventName}:{pair.Key}={pair.Value}"); } @@ -159,8 +156,7 @@ public void TerminalLoggerOnByEnv(string envVarSource) FileLogger = false, }; - expectedTelemetry.UpdateEventProperties(); - foreach (KeyValuePair pair in expectedTelemetry.Properties) + foreach (KeyValuePair pair in expectedTelemetry.GetProperties()) { output.ShouldContain($"{expectedTelemetry.EventName}:{pair.Key}={pair.Value}"); } @@ -188,8 +184,7 @@ public void TerminalLoggerDefaultOn(string defaultValue) FileLogger = false, }; - expectedTelemetry.UpdateEventProperties(); - foreach (KeyValuePair pair in expectedTelemetry.Properties) + foreach (KeyValuePair pair in expectedTelemetry.GetProperties()) { output.ShouldContain($"{expectedTelemetry.EventName}:{pair.Key}={pair.Value}"); } @@ -219,8 +214,7 @@ public void TerminalLoggerDefaultOff(string defaultValue) FileLogger = false, }; - expectedTelemetry.UpdateEventProperties(); - foreach (KeyValuePair pair in expectedTelemetry.Properties) + foreach (KeyValuePair pair in expectedTelemetry.GetProperties()) { output.ShouldContain($"{expectedTelemetry.EventName}:{pair.Key}={pair.Value}"); } diff --git a/src/Build/BackEnd/BuildManager/BuildManager.cs b/src/Build/BackEnd/BuildManager/BuildManager.cs index 2b2a01fee65..b2aae4fb743 100644 --- a/src/Build/BackEnd/BuildManager/BuildManager.cs +++ b/src/Build/BackEnd/BuildManager/BuildManager.cs @@ -576,8 +576,7 @@ public void BeginBuild(BuildParameters parameters) LogDeferredMessages(loggingService, _deferredBuildMessages); // Log known deferred telemetry - KnownTelemetry.LoggingConfigurationTelemetry.UpdateEventProperties(); - loggingService.LogTelemetry(buildEventContext: null, KnownTelemetry.LoggingConfigurationTelemetry.EventName, KnownTelemetry.LoggingConfigurationTelemetry.Properties); + loggingService.LogTelemetry(buildEventContext: null, KnownTelemetry.LoggingConfigurationTelemetry.EventName, KnownTelemetry.LoggingConfigurationTelemetry.GetProperties()); InitializeCaches(); @@ -1090,8 +1089,7 @@ public void EndBuild() } _buildTelemetry.Host = host; - _buildTelemetry.UpdateEventProperties(); - loggingService.LogTelemetry(buildEventContext: null, _buildTelemetry.EventName, _buildTelemetry.Properties); + loggingService.LogTelemetry(buildEventContext: null, _buildTelemetry.EventName, _buildTelemetry.GetProperties()); // Clean telemetry to make it ready for next build submission. _buildTelemetry = null; } diff --git a/src/Framework/Telemetry/BuildTelemetry.cs b/src/Framework/Telemetry/BuildTelemetry.cs index 9515a2e185e..7e2e0c6b514 100644 --- a/src/Framework/Telemetry/BuildTelemetry.cs +++ b/src/Framework/Telemetry/BuildTelemetry.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.Globalization; namespace Microsoft.Build.Framework.Telemetry @@ -84,62 +85,67 @@ internal class BuildTelemetry : TelemetryBase /// public string? FrameworkName { get; set; } - public override void UpdateEventProperties() + public override IDictionary GetProperties() { + var properties = new Dictionary(); + + // populate property values if (DisplayVersion != null) { - Properties["BuildEngineDisplayVersion"] = DisplayVersion; + properties["BuildEngineDisplayVersion"] = DisplayVersion; } if (StartAt.HasValue && FinishedAt.HasValue) { - Properties["BuildDurationInMilliseconds"] = (FinishedAt.Value - StartAt.Value).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); + properties["BuildDurationInMilliseconds"] = (FinishedAt.Value - StartAt.Value).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); } if (InnerStartAt.HasValue && FinishedAt.HasValue) { - Properties["InnerBuildDurationInMilliseconds"] = (FinishedAt.Value - InnerStartAt.Value).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); + properties["InnerBuildDurationInMilliseconds"] = (FinishedAt.Value - InnerStartAt.Value).TotalMilliseconds.ToString(CultureInfo.InvariantCulture); } if (FrameworkName != null) { - Properties["BuildEngineFrameworkName"] = FrameworkName; + properties["BuildEngineFrameworkName"] = FrameworkName; } if (Host != null) { - Properties["BuildEngineHost"] = Host; + properties["BuildEngineHost"] = Host; } if (InitialServerState != null) { - Properties["InitialMSBuildServerState"] = InitialServerState; + properties["InitialMSBuildServerState"] = InitialServerState; } if (Project != null) { - Properties["ProjectPath"] = Project; + properties["ProjectPath"] = Project; } if (ServerFallbackReason != null) { - Properties["ServerFallbackReason"] = ServerFallbackReason; + properties["ServerFallbackReason"] = ServerFallbackReason; } if (Success.HasValue) { - Properties["BuildSuccess"] = Success.HasValue.ToString(CultureInfo.InvariantCulture); + properties["BuildSuccess"] = Success.HasValue.ToString(CultureInfo.InvariantCulture); } if (Target != null) { - Properties["BuildTarget"] = Target; + properties["BuildTarget"] = Target; } if (Version != null) { - Properties["BuildEngineVersion"] = Version.ToString(); + properties["BuildEngineVersion"] = Version.ToString(); } + + return properties; } } } diff --git a/src/Framework/Telemetry/LoggingConfigurationTelemetry.cs b/src/Framework/Telemetry/LoggingConfigurationTelemetry.cs index 5281c43b9d2..493a945a526 100644 --- a/src/Framework/Telemetry/LoggingConfigurationTelemetry.cs +++ b/src/Framework/Telemetry/LoggingConfigurationTelemetry.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Collections.Generic; using System.Globalization; namespace Microsoft.Build.Framework.Telemetry; @@ -97,54 +98,59 @@ internal class LoggingConfigurationTelemetry : TelemetryBase /// public bool BinaryLoggerUsedDefaultName { get; set; } - public override void UpdateEventProperties() + public override IDictionary GetProperties() { - Properties["TerminalLogger"] = TerminalLogger.ToString(CultureInfo.InvariantCulture); + var properties = new Dictionary(); + + // populate property values + properties["TerminalLogger"] = TerminalLogger.ToString(CultureInfo.InvariantCulture); if (TerminalLoggerUserIntent != null) { - Properties["TerminalLoggerUserIntent"] = TerminalLoggerUserIntent; + properties["TerminalLoggerUserIntent"] = TerminalLoggerUserIntent; } if (TerminalLoggerUserIntentSource != null) { - Properties["TerminalLoggerUserIntentSource"] = TerminalLoggerUserIntentSource; + properties["TerminalLoggerUserIntentSource"] = TerminalLoggerUserIntentSource; } if (TerminalLoggerDefault != null) { - Properties["TerminalLoggerDefault"] = TerminalLoggerDefault; + properties["TerminalLoggerDefault"] = TerminalLoggerDefault; } if (TerminalLoggerDefaultSource != null) { - Properties["TerminalLoggerDefaultSource"] = TerminalLoggerDefaultSource; + properties["TerminalLoggerDefaultSource"] = TerminalLoggerDefaultSource; } - Properties["ConsoleLogger"] = ConsoleLogger.ToString(CultureInfo.InvariantCulture); + properties["ConsoleLogger"] = ConsoleLogger.ToString(CultureInfo.InvariantCulture); if (ConsoleLoggerType != null) { - Properties["ConsoleLoggerType"] = ConsoleLoggerType; + properties["ConsoleLoggerType"] = ConsoleLoggerType; } if (ConsoleLoggerVerbosity != null) { - Properties["ConsoleLoggerVerbosity"] = ConsoleLoggerVerbosity; + properties["ConsoleLoggerVerbosity"] = ConsoleLoggerVerbosity; } - Properties["FileLogger"] = FileLogger.ToString(CultureInfo.InvariantCulture); + properties["FileLogger"] = FileLogger.ToString(CultureInfo.InvariantCulture); if (FileLoggerType != null) { - Properties["FileLoggerType"] = FileLoggerType; - Properties["FileLoggersCount"] = FileLoggersCount.ToString(CultureInfo.InvariantCulture); + properties["FileLoggerType"] = FileLoggerType; + properties["FileLoggersCount"] = FileLoggersCount.ToString(CultureInfo.InvariantCulture); } if (FileLoggerVerbosity != null) { - Properties["FileLoggerVerbosity"] = FileLoggerVerbosity; + properties["FileLoggerVerbosity"] = FileLoggerVerbosity; } - Properties["BinaryLogger"] = BinaryLogger.ToString(CultureInfo.InvariantCulture); - Properties["BinaryLoggerUsedDefaultName"] = BinaryLoggerUsedDefaultName.ToString(CultureInfo.InvariantCulture); + properties["BinaryLogger"] = BinaryLogger.ToString(CultureInfo.InvariantCulture); + properties["BinaryLoggerUsedDefaultName"] = BinaryLoggerUsedDefaultName.ToString(CultureInfo.InvariantCulture); + + return properties; } } diff --git a/src/Framework/Telemetry/TelemetryBase.cs b/src/Framework/Telemetry/TelemetryBase.cs index d2475146c5b..9084c330488 100644 --- a/src/Framework/Telemetry/TelemetryBase.cs +++ b/src/Framework/Telemetry/TelemetryBase.cs @@ -13,12 +13,7 @@ internal abstract class TelemetryBase public abstract string EventName { get; } /// - /// Gets or sets a list of properties associated with the event. + /// Fetches all derived type members wrapped in Dictionary which will be used to build . /// - public IDictionary Properties { get; set; } = new Dictionary(); - - /// - /// Translate all derived type members into properties which will be used to build . - /// - public abstract void UpdateEventProperties(); + public abstract IDictionary GetProperties(); }