From 455e2cb2c5466e0325dabf90b87c7d9c917275a4 Mon Sep 17 00:00:00 2001 From: berkansasmaz Date: Thu, 27 Nov 2025 09:29:17 +0300 Subject: [PATCH 1/7] Use IServiceScopeFactory to resolve service due to dispose problem --- .../Internal/Telemetry/TelemetryService.cs | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/TelemetryService.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/TelemetryService.cs index 8a2e3b4382..2f684acd29 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/TelemetryService.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/TelemetryService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.Internal.Telemetry.Activity.Contracts; using Volo.Abp.Internal.Telemetry.Constants; @@ -11,17 +12,11 @@ namespace Volo.Abp.Internal.Telemetry; public class TelemetryService : ITelemetryService, IScopedDependency { - private readonly ITelemetryActivitySender _telemetryActivitySender; - private readonly ITelemetryActivityEventBuilder _telemetryActivityEventBuilder; - private readonly ITelemetryActivityStorage _telemetryActivityStorage; + private readonly IServiceScopeFactory _serviceScopeFactory; - public TelemetryService(ITelemetryActivitySender telemetryActivitySender, - ITelemetryActivityEventBuilder telemetryActivityEventBuilder, - ITelemetryActivityStorage telemetryActivityStorage) + public TelemetryService(IServiceScopeFactory serviceScopeFactory) { - _telemetryActivitySender = telemetryActivitySender; - _telemetryActivityEventBuilder = telemetryActivityEventBuilder; - _telemetryActivityStorage = telemetryActivityStorage; + _serviceScopeFactory = serviceScopeFactory; } @@ -74,24 +69,37 @@ public class TelemetryService : ITelemetryService, IScopedDependency { _ = Task.Run(async () => { - await BuildAndSendActivityAsync(context); + using var scope = _serviceScopeFactory.CreateScope(); + + var telemetryActivityEventBuilder = scope.ServiceProvider.GetRequiredService(); + var telemetryActivityStorage = scope.ServiceProvider.GetRequiredService(); + var telemetryActivitySender = scope.ServiceProvider.GetRequiredService(); + + await BuildAndSendActivityAsync(context, + telemetryActivityEventBuilder, + telemetryActivityStorage, + telemetryActivitySender); }); return Task.CompletedTask; } - private async Task BuildAndSendActivityAsync(ActivityContext context) + private static async Task BuildAndSendActivityAsync( + ActivityContext context, + ITelemetryActivityEventBuilder telemetryActivityEventBuilder, + ITelemetryActivityStorage telemetryActivityStorage, + ITelemetryActivitySender telemetryActivitySender) { try { - var activityEvent = await _telemetryActivityEventBuilder.BuildAsync(context); + var activityEvent = await telemetryActivityEventBuilder.BuildAsync(context); if (activityEvent is null) { return; } - _telemetryActivityStorage.SaveActivity(activityEvent); - await _telemetryActivitySender.TrySendQueuedActivitiesAsync(); + telemetryActivityStorage.SaveActivity(activityEvent); + await telemetryActivitySender.TrySendQueuedActivitiesAsync(); } catch { From 4506f06fc667c3b645fd2bfc374835b5c3051f75 Mon Sep 17 00:00:00 2001 From: berkansasmaz Date: Thu, 27 Nov 2025 09:29:40 +0300 Subject: [PATCH 2/7] AllowTrailingCommas while parse jsons for telemetry --- .../Providers/TelemetrySolutionInfoEnricher.cs | 5 ++++- .../Detectors/AbpStudioDetector.cs | 10 ++++++++-- .../Detectors/VisualStudioCodeDetector.cs | 10 ++++++++-- .../Telemetry/Helpers/AbpPackageMetadataReader.cs | 6 ++++-- 4 files changed, 24 insertions(+), 7 deletions(-) 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 e01768c418..c57d51e6f2 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 @@ -114,7 +114,10 @@ internal sealed class TelemetrySolutionInfoEnricher : TelemetryActivityEventEnri } var moduleJsonFileContent = File.ReadAllText(modulePath); - using var moduleDoc = JsonDocument.Parse(moduleJsonFileContent); + using var moduleDoc = JsonDocument.Parse(moduleJsonFileContent, new JsonDocumentOptions + { + AllowTrailingCommas = true + }); if (!moduleDoc.RootElement.TryGetProperty("imports", out var imports)) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs index 3d35c7192a..b37760cb04 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs @@ -40,7 +40,10 @@ internal sealed class AbpStudioDetector : SoftwareDetector return null; } using var fs = new FileStream(ideStateJsonPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - using var doc = JsonDocument.Parse(fs); + using var doc = JsonDocument.Parse(fs, new JsonDocumentOptions + { + AllowTrailingCommas = true + }); return doc.RootElement.TryGetProperty("theme", out var themeElement) ? themeElement.GetString() : null; } @@ -55,7 +58,10 @@ internal sealed class AbpStudioDetector : SoftwareDetector } using var fs = new FileStream(extensionsFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - using var doc = JsonDocument.Parse(fs); + using var doc = JsonDocument.Parse(fs, new JsonDocumentOptions + { + AllowTrailingCommas = true + }); if (doc.RootElement.TryGetProperty("Extensions", out var extensionsElement) && extensionsElement.ValueKind == JsonValueKind.Array) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/VisualStudioCodeDetector.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/VisualStudioCodeDetector.cs index 72fda0f500..52559663c2 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/VisualStudioCodeDetector.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/EnvironmentInspection/Detectors/VisualStudioCodeDetector.cs @@ -77,7 +77,10 @@ internal sealed class VisualStudioCodeDetector : SoftwareDetector { try { - using var jsonDoc = JsonDocument.Parse(File.ReadAllText(productJson)); + using var jsonDoc = JsonDocument.Parse(File.ReadAllText(productJson), new JsonDocumentOptions + { + AllowTrailingCommas = true + }); var root = jsonDoc.RootElement; if (root.TryGetProperty("version", out var versionProp)) { @@ -105,7 +108,10 @@ internal sealed class VisualStudioCodeDetector : SoftwareDetector { try { - using var json = JsonDocument.Parse( File.ReadAllText(settingsPath)); + using var json = JsonDocument.Parse( File.ReadAllText(settingsPath), new JsonDocumentOptions + { + AllowTrailingCommas = true + }); var root = json.RootElement; if (root.TryGetProperty("theme", out var themeProp)) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Helpers/AbpPackageMetadataReader.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Helpers/AbpPackageMetadataReader.cs index f9ce98a2e5..446462c527 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Helpers/AbpPackageMetadataReader.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Helpers/AbpPackageMetadataReader.cs @@ -49,11 +49,13 @@ static internal class AbpProjectMetadataReader private static AbpProjectMetaData ReadOrCreateMetadata(string packagePath) { - var fileContent = File.ReadAllText(packagePath); var metadata = new AbpProjectMetaData(); - using var document = JsonDocument.Parse(fileContent); + using var document = JsonDocument.Parse(fileContent, new JsonDocumentOptions + { + AllowTrailingCommas = true + }); var root = document.RootElement; if (TryGetProjectId(root,out var projectId)) From 3faae2cf148235547aba3f94a4acc385b648bd27 Mon Sep 17 00:00:00 2001 From: berkansasmaz Date: Fri, 28 Nov 2025 16:43:23 +0300 Subject: [PATCH 3/7] Sends telemetry for only server-side applications --- .../src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 04ea98644e..7d466004f4 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -200,7 +200,13 @@ public abstract class AbpApplicationBase : IAbpApplication using var scope = ServiceProvider.CreateScope(); var abpHostEnvironment = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); - return abpHostEnvironment.IsDevelopment() && configuration.GetValue("Abp:Telemetry:IsEnabled") != false; + + if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) + { + return abpHostEnvironment.IsDevelopment() && configuration.GetValue("Abp:Telemetry:IsEnabled") != false; + } + + return false; } //TODO: We can extract a new class for this From 6b1fec92096251c92ffe7dfa175dba3fe6a5c692 Mon Sep 17 00:00:00 2001 From: berkansasmaz Date: Fri, 28 Nov 2025 16:43:40 +0300 Subject: [PATCH 4/7] Delete old telemetry information if exist --- .../Storage/TelemetryActivityStorage.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Storage/TelemetryActivityStorage.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Storage/TelemetryActivityStorage.cs index 6796af7179..b37ec15d71 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Storage/TelemetryActivityStorage.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Activity/Storage/TelemetryActivityStorage.cs @@ -25,6 +25,8 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep public TelemetryActivityStorage() { CreateDirectoryIfNotExist(); + + DeleteExistingOldInformation(); State = LoadState(); } @@ -166,6 +168,22 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep } } + private static void DeleteExistingOldInformation() + { + try + { + var file = new FileInfo(TelemetryPaths.ActivityStorage); + if (file.Exists && file.CreationTime < new DateTime(2025, 12, 01)) + { + file.Delete(); + } + } + catch + { + // Ignored + } + } + private static TelemetryActivityStorageState LoadState() { try From 21937b1220c533e637761fc4b5dac43f9097a6d1 Mon Sep 17 00:00:00 2001 From: berkansasmaz Date: Fri, 28 Nov 2025 16:43:52 +0300 Subject: [PATCH 5/7] Add UserDeviceId to ActivityPropertyNames --- .../Abp/Internal/Telemetry/Constants/ActivityPropertyNames.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/ActivityPropertyNames.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/ActivityPropertyNames.cs index 924cd1dd7d..0157c61bb8 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/ActivityPropertyNames.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/ActivityPropertyNames.cs @@ -12,6 +12,7 @@ public static class ActivityPropertyNames public const string IpAddress = "IpAddress"; public const string IsFirstSession = "IsFirstSession"; public const string DeviceId = "DeviceId"; + public const string UserDeviceId = "UserDeviceId"; public const string DeviceLanguage = "DeviceLanguage"; public const string OperatingSystem = "OperatingSystem"; public const string CountryIsoCode = "CountryIsoCode"; From a5637ea38a5fe5cf3f1eec1e2e7346cb96057e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SAL=C4=B0H=20=C3=96ZKARA?= <58659931+salihozkara@users.noreply.github.com> Date: Mon, 1 Dec 2025 09:26:07 +0300 Subject: [PATCH 6/7] Use baseboard serial number for Windows device ID Replaces the use of processor ID with baseboard serial number when retrieving the unique device identifier on Windows. This change improves reliability and consistency of device identification. --- .../Abp/Internal/Telemetry/Constants/DeviceManager.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/DeviceManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/DeviceManager.cs index e3993886a0..393f974e98 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/DeviceManager.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Internal/Telemetry/Constants/DeviceManager.cs @@ -133,7 +133,7 @@ static internal class DeviceManager { try { - return GetProcessorIdForWindows(); + return GetBaseBoardSerialNumberForWindows(); } catch { @@ -142,10 +142,10 @@ static internal class DeviceManager return GetWindowsMachineUniqueId(); } - private static string GetProcessorIdForWindows() + private static string GetBaseBoardSerialNumberForWindows() { using (var managementObjectSearcher = - new System.Management.ManagementObjectSearcher("SELECT ProcessorId FROM Win32_Processor")) + new System.Management.ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard")) { using (var searcherObj = managementObjectSearcher.Get()) { @@ -156,7 +156,7 @@ static internal class DeviceManager var managementObjectEnumerator = searcherObj.GetEnumerator(); managementObjectEnumerator.MoveNext(); - return managementObjectEnumerator.Current.GetPropertyValue("ProcessorId").ToString()!; + return managementObjectEnumerator.Current.GetPropertyValue("SerialNumber").ToString()!; } } } From c559ad8ce215ce10efbadce9afa93a518006b431 Mon Sep 17 00:00:00 2001 From: berkansasmaz Date: Tue, 2 Dec 2025 09:23:46 +0300 Subject: [PATCH 7/7] Fix build error --- framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs index 7d466004f4..4ec967ed01 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/AbpApplicationBase.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.Configuration; @@ -201,7 +202,7 @@ public abstract class AbpApplicationBase : IAbpApplication var abpHostEnvironment = scope.ServiceProvider.GetRequiredService(); var configuration = scope.ServiceProvider.GetRequiredService(); - if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { return abpHostEnvironment.IsDevelopment() && configuration.GetValue("Abp:Telemetry:IsEnabled") != false; }