| File: AllowEmptyTelemetry.cs | Web Access |
| Project: src\sdk\src\Tasks\Microsoft.NET.Build.Tasks\Microsoft.NET.Build.Tasks.csproj (Microsoft.NET.Build.Tasks) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using Microsoft.Build.Framework; using Microsoft.NET.Build.Tasks; namespace Microsoft.Build.Tasks { /// <summary> /// Task that logs telemetry. /// </summary> [MSBuildMultiThreadableTask] public sealed class AllowEmptyTelemetry : TaskBase { public AllowEmptyTelemetry() { EventData = Array.Empty<ITaskItem>(); EventName = string.Empty; } /// <summary> /// Gets or sets an array of ITaskItems. The ItemSpec of the item will be the 'key' of the telemetry event property. The 'Value' metadata will be the value. /// If the 'Hash' metadata is present and set to 'true', the value will be hashed before being logged. /// </summary> public ITaskItem[] EventData { get; set; } [Required] public string EventName { get; set; } protected override void ExecuteCore() { if (EventData == null) { (BuildEngine as IBuildEngine5)?.LogTelemetry(EventName, null); } else { IDictionary<string, string> properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); foreach (var item in EventData) { var key = item.ItemSpec; var availableNames = item.MetadataNames.Cast<string>(); var hasValue = availableNames.Contains("Value"); var value = hasValue ? item.GetMetadata("Value") : null; var hasHash = availableNames.Contains("Hash"); var hash = hasHash ? bool.Parse(item.GetMetadata("Hash")) : false; if (hash && value != null) { value = HashWithNormalizedCasing(value); } if (string.IsNullOrEmpty(value)) { properties[key] = "null"; } else { properties[key] = value; } } (BuildEngine as IBuildEngine5)?.LogTelemetry(EventName, properties); } } // A local copy of Sha256Hasher.HashWithNormalizedCasing from the Microsoft.DotNet.Cli.Utils project. // We don't want to introduce a project<->project dependency, and the logic is straightforward enough. private static string HashWithNormalizedCasing(string text) { var utf8UpperBytes = Encoding.UTF8.GetBytes(text.ToUpperInvariant()); #if NETFRAMEWORK var crypt = System.Security.Cryptography.SHA256.Create(); var hash = new System.Text.StringBuilder(); byte[] crypto = crypt.ComputeHash(utf8UpperBytes); foreach (byte theByte in crypto) { hash.Append(theByte.ToString("x2")); } return hash.ToString().ToLowerInvariant(); #endif #if NET byte[] hash = System.Security.Cryptography.SHA256.HashData(utf8UpperBytes); return Convert.ToHexStringLower(hash); #endif } } }