From 2425b7e861de688964b1dd383f8d09293d6f283b Mon Sep 17 00:00:00 2001 From: Emre KARA Date: Mon, 5 May 2025 15:46:32 +0300 Subject: [PATCH] Refactor telemetry system to remove ABP CLI dependencies --- .../Volo.Abp.Telemetry/AbpTelemetryModule.cs | 5 +- .../Activity/ActivityData.cs | 41 ++++++++++++++ .../Activity/ActivityDataProvider.cs | 53 +++++++++---------- .../Activity/ActivityStorage.cs | 35 ++++++------ .../ActivityEventHandler.cs | 41 -------------- .../Detectors/AbpStudioDetector.cs | 7 +-- .../DeviceInfoProvider.cs | 4 +- .../Volo.Abp.Telemetry/ITelemetryService.cs | 2 +- .../Shared/AbpTelemetryPaths.cs | 12 +++++ .../Volo.Abp.Telemetry/TelemetryDataSender.cs | 38 +++++++++---- .../Volo.Abp.Telemetry/TelemetryService.cs | 35 ++++++++---- .../Volo.Abp.Telemetry.csproj | 2 - 12 files changed, 159 insertions(+), 116 deletions(-) delete mode 100644 framework/src/Volo.Abp.Telemetry/ActivityEventHandler.cs create mode 100644 framework/src/Volo.Abp.Telemetry/Shared/AbpTelemetryPaths.cs diff --git a/framework/src/Volo.Abp.Telemetry/AbpTelemetryModule.cs b/framework/src/Volo.Abp.Telemetry/AbpTelemetryModule.cs index eedb5b5231..59fd3e3ee5 100644 --- a/framework/src/Volo.Abp.Telemetry/AbpTelemetryModule.cs +++ b/framework/src/Volo.Abp.Telemetry/AbpTelemetryModule.cs @@ -5,12 +5,9 @@ using Activity; using Helpers; using Microsoft.Extensions.DependencyInjection; using Volo.Abp; -using Volo.Abp.Autofac; using Volo.Abp.Modularity; -[DependsOn( - typeof(AbpAutofacModule) -)] + public class AbpTelemetryModule : AbpModule { diff --git a/framework/src/Volo.Abp.Telemetry/Activity/ActivityData.cs b/framework/src/Volo.Abp.Telemetry/Activity/ActivityData.cs index 4e31d5e7b4..1bbfd5c2a9 100644 --- a/framework/src/Volo.Abp.Telemetry/Activity/ActivityData.cs +++ b/framework/src/Volo.Abp.Telemetry/Activity/ActivityData.cs @@ -45,3 +45,44 @@ public class ActivityData : Dictionary ActivityDetails = details; } } + + +public static class ActivityPropertyNameConstants +{ + public const string SessionId = "SessionId"; + public const string IsFirstSession = "IsFirstSession"; + public const string DeviceId = "DeviceId"; + public const string DeviceType = "DeviceType"; + public const string DeviceLanguage = "DeviceLanguage"; + public const string OperatingSystem = "OperatingSystem"; + public const string CountryIsoCode = "CountryIsoCode"; + public const string InstalledSoftwares = "InstalledSoftwares"; + public const string ControllerCount = nameof(ApplicationInfo.ControllerCount); + public const string EntityCount = nameof(ApplicationInfo.EntityCount); + public const string AbpModuleCount = nameof(ApplicationInfo.AbpModuleCount); + public const string PermissionCount = nameof(ApplicationInfo.PermissionCount); + public const string AppServiceCount = nameof(ApplicationInfo.AppServiceCount); + public const string ProjectType = "ProjectType"; + public const string ProjectId = "ProjectId"; + public const string SolutionId = "SolutionId"; + public const string Template = "Template"; + public const string CreatedAbpStudioVersion = "CreatedAbpStudioVersion"; + public const string IsTiered = "IsTiered"; + public const string UiFramework = "UiFramework"; + public const string DatabaseProvider = "DatabaseProvider"; + public const string DatabaseManagementSystem = "DatabaseManagementSystem"; + public const string IsSeparateTenantSchema = "IsSeparateTenantSchema"; + public const string Theme = "Theme"; + public const string ThemeStyle = "ThemeStyle"; + public const string MobileFramework = "MobileFramework"; + public const string HasPublicWebsite = "HasPublicWebsite"; + public const string IncludeTests = "IncludeTests"; + public const string MultiTenancy = "MultiTenancy"; + public const string DynamicLocalization = "DynamicLocalization"; + public const string KubernetesConfiguration = "KubernetesConfiguration"; + public const string GrafanaDashboard = "GrafanaDashboard"; + public const string SocialLogins = "SocialLogins"; + public const string InstalledModules = "InstalledModules"; + public const string ProjectAssemblyForScan = "ProjectAssemblyForScan"; + public const string SolutionPath = "SolutionPath"; +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Telemetry/Activity/ActivityDataProvider.cs b/framework/src/Volo.Abp.Telemetry/Activity/ActivityDataProvider.cs index 68bd6a4b2b..28a6a25b2e 100644 --- a/framework/src/Volo.Abp.Telemetry/Activity/ActivityDataProvider.cs +++ b/framework/src/Volo.Abp.Telemetry/Activity/ActivityDataProvider.cs @@ -70,13 +70,13 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency private async Task AddDeviceInformationAsync(ActivityData activityData) { - activityData.Add("DeviceType", _deviceInfoProvider.GetDeviceType()); - activityData.Add("DeviceLanguage", _deviceInfoProvider.GetLanguage()); - activityData.Add("OperatingSystem", _deviceInfoProvider.GetOperatingSystem()); - activityData.Add("CountryIsoCode", _deviceInfoProvider.GetCountry()); + activityData.Add(ActivityPropertyNameConstants.DeviceType , _deviceInfoProvider.GetDeviceType()); + activityData.Add(ActivityPropertyNameConstants.DeviceLanguage, _deviceInfoProvider.GetLanguage()); + activityData.Add(ActivityPropertyNameConstants.OperatingSystem, _deviceInfoProvider.GetOperatingSystem()); + activityData.Add(ActivityPropertyNameConstants.CountryIsoCode, _deviceInfoProvider.GetCountry()); var softwareList = await _softwareInfoProvider.GetSoftwareInfoAsync(); - activityData.Add("InstalledSoftwares", softwareList); + activityData.Add(ActivityPropertyNameConstants.InstalledSoftwares, softwareList); await _activityStorage.MarkDeviceInfoAsSentAsync(); } @@ -89,8 +89,8 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency activityData.Add(nameof(ApplicationInfo.AbpModuleCount), info.AbpModuleCount); activityData.Add(nameof(ApplicationInfo.PermissionCount), info.PermissionCount); activityData.Add(nameof(ApplicationInfo.AppServiceCount), info.AppServiceCount); - activityData.Add("ProjectType", activityData["ProjectType"]); - activityData.Add("ProjectId", activityData["ProjectId"]); + activityData.Add(ActivityPropertyNameConstants.ProjectType, activityData["ProjectType"]); + activityData.Add(ActivityPropertyNameConstants.ProjectId, activityData["ProjectId"]); activityData.Remove("ProjectAssemblyForScan"); } @@ -105,30 +105,29 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency var solutionId = rootJObject["id"]!.To(); var lastSolutionInfoSendTime = await _activityStorage.GetLastSolutionInfoSendTimeAsync(solutionId); - activityData.Add("SolutionId", solutionId); + activityData.Add(ActivityPropertyNameConstants.SolutionId, solutionId); if (lastSolutionInfoSendTime is null || DateTimeOffset.UtcNow - lastSolutionInfoSendTime > TimeSpan.FromDays(7)) { var infoJObject = (JObject)rootJObject["creatingStudioConfiguration"]!; - activityData.Add("Template", GetSolutionTemplate(infoJObject["template"]?.ToString())); - activityData.Add("CreatedAbpStudioVersion", infoJObject["createdAbpStudioVersion"]!.ToString()); - activityData.Add("IsTiered", infoJObject.Value("Tiered")); - activityData.Add("UiFramework", GetUiFramework(infoJObject["uiFramework"]?.ToString())); - activityData.Add("DatabaseProvider", GetDatabaseProvider(infoJObject["databaseProvider"]?.ToString())); - activityData.Add("DatabaseManagementSystem",GetDbms(infoJObject["databaseManagementSystem"]?.ToString())); - activityData.Add("IsSeparateTenantSchema", infoJObject.Value("separateTenantSchema")); - activityData.Add("Theme", GetUiTheme(infoJObject["theme"]?.ToString())); - activityData.Add("ThemeStyle", GetUiThemeStyle(infoJObject["themeStyle"]?.ToString())); - activityData.Add("MobileFramework", GetMobileApp(infoJObject["mobileFramework"]?.ToString())); - activityData.Add("HasPublicWebsite", infoJObject.Value("publicWebsite")); - activityData.Add("IncludeTests", infoJObject.Value("includeTests")); - activityData.Add("MultiTenancy", infoJObject.Value("multiTenancy")); - activityData.Add("DynamicLocalization", infoJObject.Value("dynamicLocalization")); - activityData.Add("KubernetesConfiguration", infoJObject.Value("kubernetesConfiguration")); - activityData.Add("GrafanaDashboard", infoJObject.Value("grafanaDashboard")); - activityData.Add("SocialLogins", infoJObject.Value("socialLogin")); - + activityData.Add(ActivityPropertyNameConstants.Template, GetSolutionTemplate(infoJObject["template"]?.ToString())); + activityData.Add(ActivityPropertyNameConstants.CreatedAbpStudioVersion, infoJObject["createdAbpStudioVersion"]!.ToString()); + activityData.Add(ActivityPropertyNameConstants.IsTiered, infoJObject.Value("Tiered")); + activityData.Add(ActivityPropertyNameConstants.UiFramework, GetUiFramework(infoJObject["uiFramework"]?.ToString())); + activityData.Add(ActivityPropertyNameConstants.DatabaseProvider, GetDatabaseProvider(infoJObject["databaseProvider"]?.ToString())); + activityData.Add(ActivityPropertyNameConstants.DatabaseManagementSystem, GetDbms(infoJObject["databaseManagementSystem"]?.ToString())); + activityData.Add(ActivityPropertyNameConstants.IsSeparateTenantSchema, infoJObject.Value("separateTenantSchema")); + activityData.Add(ActivityPropertyNameConstants.Theme, GetUiTheme(infoJObject["theme"]?.ToString())); + activityData.Add(ActivityPropertyNameConstants.ThemeStyle, GetUiThemeStyle(infoJObject["themeStyle"]?.ToString())); + activityData.Add(ActivityPropertyNameConstants.MobileFramework, GetMobileApp(infoJObject["mobileFramework"]?.ToString())); + activityData.Add(ActivityPropertyNameConstants.HasPublicWebsite, infoJObject.Value("publicWebsite")); + activityData.Add(ActivityPropertyNameConstants.IncludeTests, infoJObject.Value("includeTests")); + activityData.Add(ActivityPropertyNameConstants.MultiTenancy, infoJObject.Value("multiTenancy")); + activityData.Add(ActivityPropertyNameConstants.DynamicLocalization, infoJObject.Value("dynamicLocalization")); + activityData.Add(ActivityPropertyNameConstants.KubernetesConfiguration, infoJObject.Value("kubernetesConfiguration")); + activityData.Add(ActivityPropertyNameConstants.GrafanaDashboard, infoJObject.Value("grafanaDashboard")); + activityData.Add(ActivityPropertyNameConstants.SocialLogins, infoJObject.Value("socialLogin")); var modules = new List(); foreach (var module in rootJObject["modules"]!.Children()) @@ -168,7 +167,7 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency }); } - activityData.Add("InstalledModules", modules); + activityData.Add(ActivityPropertyNameConstants.InstalledModules, modules); } } } diff --git a/framework/src/Volo.Abp.Telemetry/Activity/ActivityStorage.cs b/framework/src/Volo.Abp.Telemetry/Activity/ActivityStorage.cs index 888ac35997..4abb9a5922 100644 --- a/framework/src/Volo.Abp.Telemetry/Activity/ActivityStorage.cs +++ b/framework/src/Volo.Abp.Telemetry/Activity/ActivityStorage.cs @@ -3,25 +3,20 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Volo.Abp.Cli; +using Shared; using Volo.Abp.DependencyInjection; -using Volo.Abp.Json; namespace Activity; public class ActivityStorage : IActivityStorage, ISingletonDependency { - private readonly IJsonSerializer _jsonSerializer; - private readonly string _filePath; + private ActivityStorageState? _cachedState; - public ActivityStorage(IJsonSerializer jsonSerializer) - { - _jsonSerializer = jsonSerializer; - _filePath = Path.Combine(CliPaths.AbpRootPath, "activity-storage.json"); - } + public async Task BufferActivityAsync(ActivityData activityData, CancellationToken cancellationToken = default) { @@ -154,7 +149,7 @@ public class ActivityStorage : IActivityStorage, ISingletonDependency { using var reader = new StreamReader(stream, Encoding.UTF8, leaveOpen: true); var json = await reader.ReadToEndAsync(); - return _jsonSerializer.Deserialize(json) ?? new ActivityStorageState(); + return JsonSerializer.Deserialize(json) ?? new ActivityStorageState(); }); return _cachedState; } @@ -169,7 +164,7 @@ public class ActivityStorage : IActivityStorage, ISingletonDependency try { await using var stream = new FileStream( - _filePath, + AbpTelemetryPaths.ActivityStorage, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None @@ -191,8 +186,11 @@ public class ActivityStorage : IActivityStorage, ISingletonDependency private async Task SaveAsync() { - var json = _jsonSerializer.Serialize(_cachedState ?? new ActivityStorageState(), indented: true); - await File.WriteAllTextAsync(_filePath, json, Encoding.UTF8); + var json = JsonSerializer.Serialize(_cachedState ?? new ActivityStorageState(), new JsonSerializerOptions + { + WriteIndented = true + }); + await File.WriteAllTextAsync(AbpTelemetryPaths.ActivityStorage, json, Encoding.UTF8); } @@ -200,17 +198,20 @@ public class ActivityStorage : IActivityStorage, ISingletonDependency { try { - var directory = Path.GetDirectoryName(_filePath); + var directory = Path.GetDirectoryName(AbpTelemetryPaths.ActivityStorage); if (!Directory.Exists(directory) && ! directory.IsNullOrEmpty()) { Directory.CreateDirectory(directory); } - if (!File.Exists(_filePath)) + if (!File.Exists(AbpTelemetryPaths.ActivityStorage)) { - var json = _jsonSerializer.Serialize(new ActivityStorageState(), indented: true); - await File.WriteAllTextAsync(_filePath, json, Encoding.UTF8); + var json = JsonSerializer.Serialize(_cachedState ?? new ActivityStorageState(), new JsonSerializerOptions + { + WriteIndented = true + }); + await File.WriteAllTextAsync(AbpTelemetryPaths.ActivityStorage, json, Encoding.UTF8); } } catch diff --git a/framework/src/Volo.Abp.Telemetry/ActivityEventHandler.cs b/framework/src/Volo.Abp.Telemetry/ActivityEventHandler.cs deleted file mode 100644 index 560366b80e..0000000000 --- a/framework/src/Volo.Abp.Telemetry/ActivityEventHandler.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Threading.Tasks; -using Activity; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EventBus; - -public class ActivityEventHandler : ILocalEventHandler, ITransientDependency -{ - private readonly IActivityStorage _activityStorage; - private readonly IActivityDataProvider _activityDataProvider; - private readonly ITelemetryDataSender _telemetryDataSender; - - public ActivityEventHandler(IActivityDataProvider activityDataProvider, IActivityStorage activityStorage, ITelemetryDataSender telemetryDataSender) - { - _activityDataProvider = activityDataProvider; - _activityStorage = activityStorage; - _telemetryDataSender = telemetryDataSender; - } - - public async Task HandleEventAsync(ActivityData eventData) - { - var build = await _activityDataProvider.AddExtraInformationAsync(eventData); - await _activityStorage.BufferActivityAsync(build); - - await CheckIfActivitySendTimeIsDueAsync(); - } - - private async Task CheckIfActivitySendTimeIsDueAsync() - { - var lastActivitySendTime = await _activityStorage.GetLastActivitySendTimeAsync(); - if (lastActivitySendTime is null) - { - await _telemetryDataSender.SendAsync(); - } - - if (lastActivitySendTime is not null && lastActivitySendTime > DateTimeOffset.UtcNow.AddDays(7) ) - { - await _telemetryDataSender.SendAsync(); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs b/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs index 4813021f8a..c812175389 100644 --- a/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs +++ b/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/Detectors/AbpStudioDetector.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using EnvironmentInspection.Contracts; using EnvironmentInspection.Enums; using Newtonsoft.Json.Linq; -using Volo.Abp.Cli; namespace EnvironmentInspection.Detectors; @@ -30,7 +29,8 @@ internal class AbpStudioDetector : SoftwareDetector, ISoftwareDetector public async Task GetAbpStudioUiThemeAsync() { var ideStateJsonPath = Path.Combine( - CliPaths.AbpRootPath, + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".abp", "studio", "ui", "ide-state.json" @@ -43,7 +43,8 @@ internal class AbpStudioDetector : SoftwareDetector, ISoftwareDetector public async Task GetAbpStudioVersionAsync() { var extensionsFilePath = Path.Combine( - CliPaths.AbpRootPath, + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + ".abp", "studio", "extensions.json" ); diff --git a/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/DeviceInfoProvider.cs b/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/DeviceInfoProvider.cs index c04aa66fdc..60a38be88f 100644 --- a/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/DeviceInfoProvider.cs +++ b/framework/src/Volo.Abp.Telemetry/EnvironmentInspection/DeviceInfoProvider.cs @@ -7,7 +7,6 @@ using System.Management; using System.Runtime.InteropServices; using System.Threading.Tasks; using EnvironmentInspection.Enums; -using Volo.Abp.Cli; using Volo.Abp.DependencyInjection; namespace EnvironmentInspection; @@ -16,8 +15,7 @@ public class DeviceInfoProvider : IDeviceInfoProvider , ISingletonDependency { public async Task GetDeviceIdAsync() { - var deviceId = - await File.ReadAllTextAsync(Path.Combine(CliPaths.AbpRootPath, "cli", "computer-id.bin")); + var deviceId = await File.ReadAllTextAsync(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".abp", "cli", "computer-id.bin")); return deviceId.To(); } diff --git a/framework/src/Volo.Abp.Telemetry/ITelemetryService.cs b/framework/src/Volo.Abp.Telemetry/ITelemetryService.cs index d81615ff67..48b4298952 100644 --- a/framework/src/Volo.Abp.Telemetry/ITelemetryService.cs +++ b/framework/src/Volo.Abp.Telemetry/ITelemetryService.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using Activity; using Volo.Abp.DependencyInjection; -public interface ITelemetryService : IScopedDependency +public interface ITelemetryService { IAsyncDisposable TrackActivity(string activityName, Action? configure = null); IAsyncDisposable TrackActivity(ActivityData activityData); diff --git a/framework/src/Volo.Abp.Telemetry/Shared/AbpTelemetryPaths.cs b/framework/src/Volo.Abp.Telemetry/Shared/AbpTelemetryPaths.cs new file mode 100644 index 0000000000..d2ac2a015c --- /dev/null +++ b/framework/src/Volo.Abp.Telemetry/Shared/AbpTelemetryPaths.cs @@ -0,0 +1,12 @@ +using System; +using System.IO; + +namespace Shared; + +public static class AbpTelemetryPaths +{ + public static string AccessToken => Path.Combine(AbpRootPath, "cli", "access-token.bin"); + public static string ComputerId => Path.Combine(AbpRootPath, "cli", "computer-id.bin"); + public static string ActivityStorage => Path.Combine(AbpRootPath, "activity-storage.json"); + private readonly static string AbpRootPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".abp"); +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Telemetry/TelemetryDataSender.cs b/framework/src/Volo.Abp.Telemetry/TelemetryDataSender.cs index b47c550298..6d78127caf 100644 --- a/framework/src/Volo.Abp.Telemetry/TelemetryDataSender.cs +++ b/framework/src/Volo.Abp.Telemetry/TelemetryDataSender.cs @@ -1,30 +1,36 @@ -using System.Net.Http; +using System; +using System.IO; +using System.Net.Http; +using System.Net.Http.Headers; using System.Net.Mime; using System.Text; using System.Text.Json; using System.Threading.Tasks; using Activity; -using Volo.Abp.Cli; -using Volo.Abp.Cli.Http; +using Shared; using Volo.Abp.DependencyInjection; public class TelemetryDataSender : ITelemetryDataSender , IScopedDependency { - private readonly CliHttpClientFactory _cliHttpClientFactory; + + #if DEBUG + private const string ApiUrl = "https://localhost:44393/"; + #else + private const string ApiUrl = "https://telemetry.abp.io/"; + #endif private readonly IActivityStorage _activityStorage; private readonly IActivityDataProvider _activityDataProvider; - public TelemetryDataSender(CliHttpClientFactory cliHttpClientFactory, IActivityStorage activityStorage, IActivityDataProvider activityDataProvider) + public TelemetryDataSender(IActivityStorage activityStorage, IActivityDataProvider activityDataProvider) { - _cliHttpClientFactory = cliHttpClientFactory; _activityStorage = activityStorage; _activityDataProvider = activityDataProvider; } public async Task SendAsync() { - using var client = _cliHttpClientFactory.CreateClient(); - client.AddAbpAuthenticationToken(); + using var httpClient = new HttpClient(); + await AddAbpAuthenticationTokenAsync(httpClient); var activities = await _activityStorage.GetBufferedActivitiesAsync(); @@ -33,7 +39,7 @@ public class TelemetryDataSender : ITelemetryDataSender , IScopedDependency foreach (var activity in activities) { await _activityDataProvider.AddExtraInformationAsync(activity); - await client.PostAsync(CliUrls.TelemetryAbpIo, + await httpClient.PostAsync(ApiUrl, new StringContent(JsonSerializer.Serialize(activity), Encoding.UTF8, MediaTypeNames.Application.Json)); @@ -42,4 +48,18 @@ public class TelemetryDataSender : ITelemetryDataSender , IScopedDependency await _activityStorage.MarkActivitiesAsSentAsync(); } } + + private async static Task AddAbpAuthenticationTokenAsync(HttpClient httpClient) + { + if (!File.Exists(AbpTelemetryPaths.AccessToken)) + { + return; + } + + var accessToken = await File.ReadAllTextAsync(AbpTelemetryPaths.AccessToken, Encoding.UTF8); + if (!accessToken.IsNullOrEmpty()) + { + httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); + } + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Telemetry/TelemetryService.cs b/framework/src/Volo.Abp.Telemetry/TelemetryService.cs index ab775f275c..36399092ce 100644 --- a/framework/src/Volo.Abp.Telemetry/TelemetryService.cs +++ b/framework/src/Volo.Abp.Telemetry/TelemetryService.cs @@ -4,18 +4,21 @@ using System.Threading; using System.Threading.Tasks; using Activity; using Volo.Abp; -using Volo.Abp.EventBus.Local; +using Volo.Abp.DependencyInjection; -public class TelemetryService : ITelemetryService +public class TelemetryService : ITelemetryService , IScopedDependency { + private readonly IActivityStorage _activityStorage; + private readonly IActivityDataProvider _activityDataProvider; + private readonly ITelemetryDataSender _telemetryDataSender; - private readonly ILocalEventBus _localEventBus; - public TelemetryService( ILocalEventBus localEventBus) + public TelemetryService(IActivityStorage activityStorage, IActivityDataProvider activityDataProvider, ITelemetryDataSender telemetryDataSender) { - _localEventBus = localEventBus; + _activityStorage = activityStorage; + _activityDataProvider = activityDataProvider; + _telemetryDataSender = telemetryDataSender; } - public IAsyncDisposable TrackActivity(string activityName, Action? configure = null) { var stopwatch = Stopwatch.StartNew(); @@ -48,11 +51,25 @@ public class TelemetryService : ITelemetryService }); } - - + private async Task CheckIfActivitySendTimeIsDueAsync() + { + var lastActivitySendTime = await _activityStorage.GetLastActivitySendTimeAsync(); + if (lastActivitySendTime is null) + { + await _telemetryDataSender.SendAsync(); + } + + if (lastActivitySendTime is not null && lastActivitySendTime > DateTimeOffset.UtcNow.AddDays(7) ) + { + await _telemetryDataSender.SendAsync(); + } + } public async Task AddActivityAsync(ActivityData data, CancellationToken cancellationToken = default) { - await _localEventBus.PublishAsync(data); + var build = await _activityDataProvider.AddExtraInformationAsync(data, cancellationToken); + await _activityStorage.BufferActivityAsync(build, cancellationToken); + + await CheckIfActivitySendTimeIsDueAsync(); } public async Task AddActivityAsync(string activityName, string? details = null, CancellationToken cancellationToken = default) diff --git a/framework/src/Volo.Abp.Telemetry/Volo.Abp.Telemetry.csproj b/framework/src/Volo.Abp.Telemetry/Volo.Abp.Telemetry.csproj index cb629dc33b..55268dc6ac 100644 --- a/framework/src/Volo.Abp.Telemetry/Volo.Abp.Telemetry.csproj +++ b/framework/src/Volo.Abp.Telemetry/Volo.Abp.Telemetry.csproj @@ -16,8 +16,6 @@ - -