Skip to content

OTel experimentation #49409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -280,6 +280,10 @@ dotnet_diagnostic.IDE0200.severity = none
dotnet_diagnostic.IDE0240.severity = warning

# Additional rules for template engine source code

# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.SpacingRules'
dotnet_analyzer_diagnostic.category-StyleCop.CSharp.SpacingRules.severity = none

[{src,test}/**{Microsoft.TemplateEngine.*,dotnet-new?*}/**.cs]
# Default analyzed API surface = 'public' (public APIs)
dotnet_code_quality.api_surface = public
8 changes: 6 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
<NoWarn>$(NoWarn);NU1507</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.4.0" />
<PackageVersion Include="Basic.CompilerLog.Util" Version="0.9.9" />
<PackageVersion Include="AwesomeAssertions" Version="$(AwesomeAssertionsVersion)" />
<PackageVersion Include="BenchmarkDotNet" Version="$(BenchmarkDotNetPackageVersion)" />
@@ -95,6 +96,9 @@
<PackageVersion Include="NuGet.ProjectModel" Version="$(NuGetProjectModelPackageVersion)" />
<PackageVersion Include="NuGet.Protocol" Version="$(NuGetBuildTasksPackageVersion)" />
<PackageVersion Include="NuGet.Versioning" Version="$(NuGetVersioningPackageVersion)" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
<PackageVersion Include="runtime.linux-musl-x64.Microsoft.NETCore.DotNetHostResolver" Version="$(MicrosoftNETCoreDotNetHostResolverPackageVersion)" />
<PackageVersion Include="runtime.linux-x64.Microsoft.NETCore.DotNetHostResolver" Version="$(MicrosoftNETCoreDotNetHostResolverPackageVersion)" />
<PackageVersion Include="runtime.osx-x64.Microsoft.NETCore.DotNetHostResolver" Version="$(MicrosoftNETCoreDotNetHostResolverPackageVersion)" />
@@ -108,6 +112,7 @@
<PackageVersion Include="System.Composition.Runtime" Version="$(SystemCompositionRuntimePackageVersion)" />
<PackageVersion Include="System.Composition.TypedParts" Version="$(SystemCompositionTypedPartsPackageVersion)" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerPackageVersion)" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="$(SystemDiagnosticsDiagnosticSourcePackageVersion)" />
<PackageVersion Include="System.Formats.Asn1" Version="$(SystemFormatsAsn1Version)" />
<PackageVersion Include="System.IO.Hashing" Version="$(SystemIOHashingPackageVersion)" />
<!-- System.Reflection.Metadata and System.Collections.Immutable cannot be pinned here because of hard dependencies within Roslyn on specific versions that have to work both here and in VS -->
@@ -126,7 +131,6 @@
<PackageVersion Include="Xunit.Combinatorial" Version="$(XunitCombinatorialVersion)" />
<PackageVersion Include="xunit.console" Version="$(XUnitVersion)" />
</ItemGroup>

<!-- Use different versions of Microsoft.Build.* depending on whether the output will be used in
.NET Framework (VS) or only in the .NET SDK.

@@ -158,4 +162,4 @@
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildMinimumVersion)" />
<PackageVersion Include="Microsoft.NET.StringTools" Version="$(MicrosoftBuildMinimumVersion)" />
</ItemGroup>
</Project>
</Project>
1 change: 1 addition & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
@@ -124,6 +124,7 @@
<SystemCompositionRuntimePackageVersion>10.0.0-preview.6.25316.103</SystemCompositionRuntimePackageVersion>
<SystemCompositionTypedPartsPackageVersion>10.0.0-preview.6.25316.103</SystemCompositionTypedPartsPackageVersion>
<SystemConfigurationConfigurationManagerPackageVersion>10.0.0-preview.6.25316.103</SystemConfigurationConfigurationManagerPackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>10.0.0-preview.6.25316.103</SystemDiagnosticsDiagnosticSourcePackageVersion>
<SystemReflectionMetadataLoadContextVersion>10.0.0-preview.6.25316.103</SystemReflectionMetadataLoadContextVersion>
<SystemResourcesExtensionsPackageVersion>10.0.0-preview.6.25316.103</SystemResourcesExtensionsPackageVersion>
<SystemSecurityCryptographyPkcsPackageVersion>10.0.0-preview.6.25316.103</SystemSecurityCryptographyPkcsPackageVersion>
14 changes: 14 additions & 0 deletions src/Cli/Microsoft.DotNet.Cli.Utils/Activities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;

namespace Microsoft.DotNet.Cli.Utils;

public static class Activities
{
public static ActivitySource Source { get; } = new("dotnet-cli", Product.Version);

public const string DOTNET_CLI_TRACEPARENT = nameof(DOTNET_CLI_TRACEPARENT);
public const string DOTNET_CLI_TRACESTATE = nameof(DOTNET_CLI_TRACESTATE);
}
Original file line number Diff line number Diff line change
@@ -171,7 +171,7 @@ private static string GetMSBuildExePath()
MSBuildExeName);
}

private static string GetMSBuildSDKsPath()
public static string GetMSBuildSDKsPath()
{
var envMSBuildSDKsPath = Environment.GetEnvironmentVariable("MSBuildSDKsPath");

Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@
Condition="'$([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework)))' == '.NETCoreApp'"
GeneratePathProperty="true" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" />
<PackageReference Include="System.Diagnostics.DiagnosticSource"/>
<PackageReference Include="NuGet.Versioning" />
<PackageReference Include="NuGet.Packaging" />
<PackageReference Include="NuGet.Frameworks" />
18 changes: 9 additions & 9 deletions src/Cli/Microsoft.DotNet.Cli.Utils/TelemetryEventEntry.cs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ public static class TelemetryEventEntry
public static ITelemetryFilter TelemetryFilter { get; set; } = new BlockFilter();

public static void TrackEvent(
string? eventName = null,
string eventName,
IDictionary<string, string?>? properties = null,
IDictionary<string, double>? measurements = null)
{
@@ -32,7 +32,7 @@ public static void SendFiltered(object? o = null)
}
}

public static void Subscribe(Action<string?, IDictionary<string, string?>?, IDictionary<string, double>?> subscriber)
public static void Subscribe(Action<string, IDictionary<string, string?>?, IDictionary<string, double>?> subscriber)
{
void Handler(object? sender, InstrumentationEventArgs eventArgs)
{
@@ -47,24 +47,24 @@ public sealed class PerformanceMeasurement : IDisposable
{
private readonly Stopwatch? _timer;
private readonly Dictionary<string, double>? _data;
private readonly string? _name;
private readonly string _name;

public PerformanceMeasurement(Dictionary<string, double>? data, string name)
{
_name = name;
// Measurement is a no-op if we don't have a dictionary to store the entry.
if (data == null)
{
return;
}

_data = data;
_name = name;
_timer = Stopwatch.StartNew();
}

public void Dispose()
{
if (_name is not null && _timer is not null)
if (_timer is not null)
{
_data?.Add(_name, _timer.Elapsed.TotalMilliseconds);
}
@@ -82,7 +82,7 @@ public IEnumerable<ApplicationInsightsEntryFormat> Filter(object o)
public class InstrumentationEventArgs : EventArgs
{
internal InstrumentationEventArgs(
string? eventName,
string eventName,
IDictionary<string, string?>? properties,
IDictionary<string, double>? measurements)
{
@@ -91,17 +91,17 @@ internal InstrumentationEventArgs(
Measurements = measurements;
}

public string? EventName { get; }
public string EventName { get; }
public IDictionary<string, string?>? Properties { get; }
public IDictionary<string, double>? Measurements { get; }
}

public class ApplicationInsightsEntryFormat(
string? eventName = null,
string eventName,
IDictionary<string, string?>? properties = null,
IDictionary<string, double>? measurements = null)
{
public string? EventName { get; } = eventName;
public string EventName { get; } = eventName;
public IDictionary<string, string?>? Properties { get; } = properties;
public IDictionary<string, double>? Measurements { get; } = measurements;

45 changes: 22 additions & 23 deletions src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.Extensions.EnvironmentAbstractions
namespace Microsoft.Extensions.EnvironmentAbstractions;

public readonly struct FilePath
{
public struct FilePath
{
public string Value { get; }
public string Value { get; }

/// <summary>
/// Create FilePath to represent an absolute file path. Note it may not exist.
/// </summary>
/// <param name="value">If the value is not rooted. Path.GetFullPath will be called during the constructor.</param>
public FilePath(string value)
/// <summary>
/// Create FilePath to represent an absolute file path. Note: It may not exist.
/// </summary>
/// <param name="value">If the value is not rooted. Path.GetFullPath will be called during the constructor.</param>
public FilePath(string value)
{
if (!Path.IsPathRooted(value))
{
if (!Path.IsPathRooted(value))
{
value = Path.GetFullPath(value);
}

Value = value;
value = Path.GetFullPath(value);
}

public override string ToString()
{
return Value;
}
Value = value;
}

public DirectoryPath GetDirectoryPath()
{
return new DirectoryPath(Path.GetDirectoryName(Value)!);
}
public override string ToString()
{
return Value;
}

public DirectoryPath GetDirectoryPath()
{
return new DirectoryPath(Path.GetDirectoryName(Value)!);
}
}
Original file line number Diff line number Diff line change
@@ -51,13 +51,13 @@ internal InstantiateCommand(
Arity = new ArgumentArity(0, 999)
};

internal IReadOnlyList<Option> PassByOptions { get; } = new Option[]
{
internal IReadOnlyList<Option> PassByOptions { get; } =
[
SharedOptions.ForceOption,
SharedOptions.NameOption,
SharedOptions.DryRunOption,
SharedOptions.NoUpdateCheckOption
};
];

internal static Task<NewCommandStatus> ExecuteAsync(
NewCommandArgs newCommandArgs,
@@ -74,6 +74,7 @@ internal static async Task<IEnumerable<TemplateGroup>> GetTemplateGroupsAsync(
HostSpecificDataLoader hostSpecificDataLoader,
CancellationToken cancellationToken)
{
using var createTemplateGroupsActivity = Activities.Source.StartActivity("create-template-groups");
IReadOnlyList<ITemplateInfo> templates = await templatePackageManager.GetTemplatesAsync(cancellationToken).ConfigureAwait(false);
return TemplateGroup.FromTemplateList(CliTemplateInfo.FromTemplateInfo(templates, hostSpecificDataLoader));
}
@@ -84,6 +85,7 @@ internal static HashSet<TemplateCommand> GetTemplateCommand(
TemplatePackageManager templatePackageManager,
TemplateGroup templateGroup)
{
using var getTemplateActivity = Activities.Source.StartActivity("get-template-command");
//groups templates in the group by precedence
foreach (IGrouping<int, CliTemplateInfo> templateGrouping in templateGroup.Templates.GroupBy(g => g.Precedence).OrderByDescending(g => g.Key))
{
@@ -114,7 +116,7 @@ internal static HashSet<TemplateCommand> GetTemplateCommand(
templateGroup,
candidates);
}
return new HashSet<TemplateCommand>();
return [];
}

internal static void HandleNoMatchingTemplateGroup(InstantiateCommandArgs instantiateArgs, IEnumerable<TemplateGroup> templateGroups, IReporter reporter)
@@ -204,6 +206,8 @@ private static async Task<NewCommandStatus> ExecuteIntAsync(

return await templateListCoordinator.DisplayCommandDescriptionAsync(instantiateArgs, cancellationToken).ConfigureAwait(false);
}
using var createActivity = Activities.Source.StartActivity("instantiate-command");
createActivity?.DisplayName = $"Invoke '{instantiateArgs.ShortName}'";

IEnumerable<TemplateGroup> allTemplateGroups = await GetTemplateGroupsAsync(
templatePackageManager,
@@ -273,10 +277,11 @@ private static async Task<NewCommandStatus> HandleTemplateInstantiationAsync(
{
TemplateCommand templateCommandToRun = candidates.Single();
args.Command.Subcommands.Add(templateCommandToRun);

var templateParseActivity = Activities.Source.StartActivity("reparse-for-template");
ParseResult updatedParseResult = args.ParseResult.RootCommandResult.Command.Parse(
args.ParseResult.Tokens.Select(t => t.Value).ToArray(),
args.ParseResult.Configuration);
templateParseActivity?.Stop();
return await candidates.Single().InvokeAsync(updatedParseResult, cancellationToken).ConfigureAwait(false);
}
else if (candidates.Any())
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ namespace Microsoft.TemplateEngine.Cli.Commands
internal class TemplateCommand : Command
{
private static readonly TimeSpan ConstraintEvaluationTimeout = TimeSpan.FromMilliseconds(1000);
private static readonly string[] _helpAliases = new[] { "-h", "/h", "--help", "-?", "/?" };
private static readonly string[] _helpAliases = ["-h", "/h", "--help", "-?", "/?"];
private readonly TemplatePackageManager _templatePackageManager;
private readonly IEngineEnvironmentSettings _environmentSettings;
private readonly BaseCommand _instantiateCommand;
@@ -146,19 +146,23 @@ internal static async Task<IReadOnlyList<TemplateConstraintResult>> ValidateCons

internal async Task<NewCommandStatus> InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
using var templateInvocationActivity = Activities.Source.StartActivity("invoke-template");
TemplateCommandArgs args = new(this, _instantiateCommand, parseResult);
TemplateInvoker invoker = new(_environmentSettings, () => Console.ReadLine() ?? string.Empty);
TemplatePackageCoordinator packageCoordinator = new(_environmentSettings, _templatePackageManager);
TemplateConstraintManager constraintManager = new(_environmentSettings);
using TemplateConstraintManager constraintManager = new(_environmentSettings);
TemplatePackageDisplay templatePackageDisplay = new(Reporter.Output, Reporter.Error);

CancellationTokenSource cancellationTokenSource = new();
cancellationTokenSource.CancelAfter(ConstraintEvaluationTimeout);

#pragma warning disable CA2025 // Do not pass 'IDisposable' instances into unawaited tasks
Task<IReadOnlyList<TemplateConstraintResult>> constraintsEvaluation = ValidateConstraintsAsync(constraintManager, args.Template, args.IsForceFlagSpecified ? cancellationTokenSource.Token : cancellationToken);
#pragma warning restore CA2025 // Do not pass 'IDisposable' instances into unawaited tasks

if (!args.IsForceFlagSpecified)
{
using var constraintResultsActivity = Activities.Source.StartActivity("validate-constraints");
var constraintResults = await constraintsEvaluation.ConfigureAwait(false);
if (constraintResults.Any())
{
@@ -173,7 +177,7 @@ internal async Task<NewCommandStatus> InvokeAsync(ParseResult parseResult, Cance
Task<(string Id, string Version, string Provider)> builtInPackageCheck = packageCoordinator.ValidateBuiltInPackageAvailabilityAsync(args.Template, cancellationToken);
Task<CheckUpdateResult?> checkForUpdateTask = packageCoordinator.CheckUpdateForTemplate(args, cancellationToken);

Task[] tasksToWait = new Task[] { instantiateTask, builtInPackageCheck, checkForUpdateTask };
Task[] tasksToWait = [instantiateTask, builtInPackageCheck, checkForUpdateTask];

await Task.WhenAll(tasksToWait).ConfigureAwait(false);
Reporter.Output.WriteLine();
3 changes: 3 additions & 0 deletions src/Cli/Microsoft.TemplateEngine.Cli/TemplateInvoker.cs
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ internal TemplateInvoker(

internal async Task<NewCommandStatus> InvokeTemplateAsync(TemplateCommandArgs templateArgs, CancellationToken cancellationToken)
{
using var invokerActivity = Activities.Source.StartActivity("invoker-invoking");
cancellationToken.ThrowIfCancellationRequested();

CliTemplateInfo templateToRun = templateArgs.Template;
@@ -158,6 +159,7 @@ private async Task<NewCommandStatus> CreateTemplateAsync(TemplateCommandArgs tem

try
{
using var templateCreationActivity = Activities.Source.StartActivity("actual-instantiate-template");
instantiateResult = await _templateCreator.InstantiateAsync(
templateArgs.Template,
templateArgs.Name,
@@ -306,6 +308,7 @@ private async Task<NewCommandStatus> CreateTemplateAsync(TemplateCommandArgs tem

private NewCommandStatus HandlePostActions(ITemplateCreationResult creationResult, TemplateCommandArgs args)
{
using var postActionActivity = Activities.Source.StartActivity("post-actions");
PostActionExecutionStatus result = _postActionDispatcher.Process(creationResult, args.IsDryRun, args.AllowScripts ?? AllowRunScripts.Prompt);

return result switch
Loading