From 39ad3e6d3380f80ad771304d8cd3eecd68e7eb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SAL=C4=B0H=20=C3=96ZKARA?= Date: Wed, 10 Dec 2025 13:18:12 +0300 Subject: [PATCH] Improve telemetry solution path handling and enrichment Refactored telemetry logic to better handle and enrich solution path information, including moving TelemetryCliSessionProvider, updating activity tracking in commands, and enhancing TelemetrySolutionInfoEnricher to reliably find and set solution paths and IDs. Removed redundant service registrations and improved the order and conditions for telemetry activities. --- .../Volo/Abp/Cli/AbpCliCoreModule.cs | 2 - .../Volo/Abp/Cli/CliService.cs | 3 +- .../Abp/Cli/Commands/AddPackageCommand.cs | 10 +--- .../Volo/Abp/Cli/Commands/NewCommand.cs | 1 - .../Volo.Abp.Cli/Volo/Abp/Cli/AbpCliModule.cs | 9 ++- .../Telemetry/TelemetryCliSessionProvider.cs | 21 ++++++- .../TelemetrySolutionInfoEnricher.cs | 57 ++++++++++++++++++- .../Activity/TelemetryJsonExtensions.cs | 10 ++++ 8 files changed, 97 insertions(+), 16 deletions(-) rename framework/src/{Volo.Abp.Cli.Core => Volo.Abp.Cli}/Volo/Abp/Cli/Telemetry/TelemetryCliSessionProvider.cs (51%) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs index 5f4f6cfaf6..cea7a38b8b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs @@ -38,8 +38,6 @@ public class AbpCliCoreModule : AbpModule { client.DefaultRequestHeaders.UserAgent.ParseAdd("MyAgent/1.0"); }); - - context.Services.RemoveAll(x => x.ImplementationType == typeof(TelemetrySessionInfoEnricher)); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs index d89b68989b..7f5f3224e6 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs @@ -84,7 +84,6 @@ public class CliService : ITransientDependency catch (CliUsageException usageException) { Logger.LogWarning(usageException.Message); - await TelemetryService.AddActivityAsync(ActivityNameConsts.AbpCliExit); Environment.ExitCode = 1; } catch (Exception ex) @@ -94,6 +93,8 @@ public class CliService : ITransientDependency Logger.LogException(ex); throw; } + + await TelemetryService.AddActivityAsync(ActivityNameConsts.AbpCliExit); } private async Task RunPromptAsync() diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs index cbda50602a..4cec1023b3 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs @@ -43,6 +43,9 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency GetUsageInfo() ); } + + await using var _ = TelemetryService.TrackActivityAsync(ActivityNameConsts.AbpCliCommandsNewPackage); + await using var __ = TelemetryService.TrackActivityAsync(ActivityNameConsts.AbpCliCommandsAddPackage); var isNpmPackage = false; var isNugetPackage = true; @@ -63,11 +66,6 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency var slnFile = GetSolutionFile(commandLineArgs); var projectFile = GetProjectFile(commandLineArgs); - await using var _ = TelemetryService.TrackActivityAsync(ActivityNameConsts.AbpCliCommandsAddPackage, o => - { - o[ActivityPropertyNames.SolutionPath] = slnFile; - }); - await ProjectNugetPackageAdder.AddAsync( slnFile, projectFile, @@ -80,8 +78,6 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency } else if (isNpmPackage) { - await using var _ = TelemetryService.TrackActivityAsync(ActivityNameConsts.AbpCliCommandsAddPackage); - await ProjectNpmPackageAdder.AddNpmPackageAsync( GetAngularDirectory(commandLineArgs), commandLineArgs.Target, diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index 0c8367a7c5..ac932dae67 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -112,7 +112,6 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien { o[ActivityPropertyNames.CreationTool] = AbpTool.OldCli; o[ActivityPropertyNames.Template] = template; - o[ActivityPropertyNames.SolutionPath] = projectArgs.OutputFolder; }); ExtractProjectZip(result, projectArgs.OutputFolder); diff --git a/framework/src/Volo.Abp.Cli/Volo/Abp/Cli/AbpCliModule.cs b/framework/src/Volo.Abp.Cli/Volo/Abp/Cli/AbpCliModule.cs index c782eadd52..d1b30d34b5 100644 --- a/framework/src/Volo.Abp.Cli/Volo/Abp/Cli/AbpCliModule.cs +++ b/framework/src/Volo.Abp.Cli/Volo/Abp/Cli/AbpCliModule.cs @@ -1,4 +1,6 @@ -using Volo.Abp.Autofac; +using System.Collections.Generic; +using Volo.Abp.Autofac; +using Volo.Abp.Internal.Telemetry.Activity.Providers; using Volo.Abp.Modularity; namespace Volo.Abp.Cli; @@ -9,5 +11,8 @@ namespace Volo.Abp.Cli; )] public class AbpCliModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.RemoveAll(x => x.ImplementationType == typeof(TelemetrySessionInfoEnricher)); + } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Telemetry/TelemetryCliSessionProvider.cs b/framework/src/Volo.Abp.Cli/Volo/Abp/Cli/Telemetry/TelemetryCliSessionProvider.cs similarity index 51% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Telemetry/TelemetryCliSessionProvider.cs rename to framework/src/Volo.Abp.Cli/Volo/Abp/Cli/Telemetry/TelemetryCliSessionProvider.cs index 1934f9fc3f..807b94f5e4 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Telemetry/TelemetryCliSessionProvider.cs +++ b/framework/src/Volo.Abp.Cli/Volo/Abp/Cli/Telemetry/TelemetryCliSessionProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -18,13 +19,31 @@ public class TelemetryCliSessionProvider : TelemetryActivityEventEnricher } public override int ExecutionOrder { get; set; } = 10; - protected override Type ReplaceParentType { get; set; } = typeof(TelemetrySessionInfoEnricher); + protected override Type? ReplaceParentType { get; set; } = typeof(TelemetrySessionInfoEnricher); protected override Task ExecuteAsync(ActivityContext context) { context.Current[ActivityPropertyNames.SessionType] = SessionType.AbpCli; context.Current[ActivityPropertyNames.SessionId] = Guid.NewGuid(); context.Current[ActivityPropertyNames.IsFirstSession] = !File.Exists(TelemetryPaths.ActivityStorage); + + if (context.ExtraProperties.ContainsKey(ActivityPropertyNames.SolutionPath)) + { + return Task.CompletedTask; + } + + if(context.Current.TryGetValue(ActivityPropertyNames.SolutionPath, out var existingSolutionPath) && existingSolutionPath is string) + { + context.ExtraProperties[ActivityPropertyNames.SolutionPath] = existingSolutionPath; + return Task.CompletedTask; + } + + if (context.Current.TryGetValue(ActivityPropertyNames.AdditionalProperties, out var additionalProperties) && + additionalProperties is Dictionary additionalPropertiesDict && + additionalPropertiesDict.TryGetValue(ActivityPropertyNames.SolutionPath, out var solutionPath)) + { + context.ExtraProperties[ActivityPropertyNames.SolutionPath] = solutionPath; + } return Task.CompletedTask; } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs index c57d51e6f2..f39b3babd8 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Providers/TelemetrySolutionInfoEnricher.cs @@ -21,12 +21,17 @@ internal sealed class TelemetrySolutionInfoEnricher : TelemetryActivityEventEnri protected override Task CanExecuteAsync(ActivityContext context) { - if (context.SolutionId.HasValue && !context.SolutionPath.IsNullOrEmpty()) + if (context.SolutionPath.IsNullOrEmpty()) + { + return Task.FromResult(false); + } + + if (context.SolutionId.HasValue) { return Task.FromResult(_telemetryActivityStorage.ShouldAddSolutionInformation(context.SolutionId.Value)); } - return Task.FromResult(false); + return Task.FromResult(true); } protected override Task ExecuteAsync(ActivityContext context) @@ -37,6 +42,14 @@ internal sealed class TelemetrySolutionInfoEnricher : TelemetryActivityEventEnri { return Task.CompletedTask; } + + var correctSolutionPath = FindCorrectSolutionPath(context.SolutionPath); + if (correctSolutionPath.IsNullOrEmpty()) + { + return Task.CompletedTask; + } + + context.ExtraProperties[ActivityPropertyNames.SolutionPath] = correctSolutionPath; var jsonContent = File.ReadAllText(context.SolutionPath!); using var doc = JsonDocument.Parse(jsonContent, new JsonDocumentOptions @@ -45,6 +58,15 @@ internal sealed class TelemetrySolutionInfoEnricher : TelemetryActivityEventEnri }); var root = doc.RootElement; + + var solutionId = TelemetryJsonExtensions.GetGuidOrNull(root, "id"); + + if (!solutionId.HasValue) + { + return Task.CompletedTask; + } + + context.Current[ActivityPropertyNames.SolutionId] = solutionId; if (root.TryGetProperty("versions", out var versions)) { @@ -149,4 +171,35 @@ internal sealed class TelemetrySolutionInfoEnricher : TelemetryActivityEventEnri var fullPath = Path.Combine(Path.GetDirectoryName(solutionPath)!, path); return File.Exists(fullPath) ? fullPath : null; } + + private static string? FindCorrectSolutionPath(string solutionPath) + { + if (solutionPath.EndsWith(".abpsln")) + { + return solutionPath; + } + + if (solutionPath.EndsWith(".sln")) + { + solutionPath = solutionPath[..^4] + ".abpsln"; + if (File.Exists(solutionPath)) + { + return solutionPath; + } + } + + var dir = Path.GetDirectoryName(solutionPath); + if (dir.IsNullOrEmpty()) + { + return null; + } + + var abpSolutionFiles = Directory.GetFiles(dir, "*.abpsln", SearchOption.TopDirectoryOnly); + + return abpSolutionFiles.Length switch + { + 1 => abpSolutionFiles[0], + _ => null + }; + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/TelemetryJsonExtensions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/TelemetryJsonExtensions.cs index 6f8b5c2a10..f822f72f18 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/TelemetryJsonExtensions.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/TelemetryJsonExtensions.cs @@ -31,4 +31,14 @@ static internal class TelemetryJsonExtensions return null; } + + static internal Guid? GetGuidOrNull(JsonElement element, string propertyName) + { + if (element.TryGetProperty(propertyName, out var guidProperty) && Guid.TryParse(guidProperty.GetString(), out var guidValue)) + { + return guidValue; + } + + return null; + } } \ No newline at end of file