From 94ecbf3199d1abe3b08373dc53cf944e5587ce6e Mon Sep 17 00:00:00 2001 From: Emre KARA Date: Thu, 29 May 2025 15:41:28 +0300 Subject: [PATCH] Enhance telemetry functionality by updating TelemetryService to send activities based on a new condition, modifying ActivityData to initialize time correctly, and adding ShouldSendActivitiesAsync method in ITelemetryActivityStorage for improved activity management. --- .../Abp/Telemetry/Activity/ActivityData.cs | 7 ++++- .../Contracts/ITelemetryActivityStorage.cs | 1 + .../Storage/TelemetryActivityStorage.cs | 29 ++++++++++++++----- .../TelemetryActivityStorageOptions.cs | 10 +++++++ .../Volo/Abp/Telemetry/TelemetryService.cs | 19 +++++------- 5 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorageOptions.cs diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityData.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityData.cs index 96390ec243..7fef2f3c80 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityData.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityData.cs @@ -7,6 +7,7 @@ public class ActivityData : Dictionary { public ActivityData() { + Time = DateTimeOffset.UtcNow; } public ActivityData(string activityName, string? details = null) @@ -18,6 +19,7 @@ public class ActivityData : Dictionary ActivityName = activityName; ActivityDetails = details; + Time = DateTimeOffset.UtcNow; } public string ActivityName { @@ -55,5 +57,8 @@ public class ActivityData : Dictionary } } - public DateTimeOffset Time = DateTimeOffset.UtcNow; + public DateTimeOffset Time { + get => TryGetValue(nameof(Time), out var value) ? (DateTimeOffset)value : DateTimeOffset.UtcNow; + set => this[nameof(Time)] = value; + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Contracts/ITelemetryActivityStorage.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Contracts/ITelemetryActivityStorage.cs index f241b502ed..c65949ff3a 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Contracts/ITelemetryActivityStorage.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Contracts/ITelemetryActivityStorage.cs @@ -18,4 +18,5 @@ public interface ITelemetryActivityStorage Task ShouldAddDeviceInfoAsync(); Task ShouldAddSolutionInformation(Guid solutionId); Task ShouldAddApplicationInfoAsync(Guid applicationId); + Task ShouldSendActivitiesAsync(); } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorage.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorage.cs index 7eab630096..ddfba94924 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorage.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorage.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; +using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.Telemetry.Activity.Contracts; using Volo.Abp.Telemetry.Constants; @@ -15,10 +16,16 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep { private const int MaxFileRetries = 5; private const int RetryDelayMs = 100; - private static readonly TimeSpan InfoExpirationPeriod = TimeSpan.FromDays(7); - + + private readonly TelemetryActivityStorageOptions _options; private TelemetryActivityStorageState? _cachedState; + public TelemetryActivityStorage(IOptions options) + { + _options = options?.Value ?? new TelemetryActivityStorageOptions(); + + } + public async Task BufferActivityAsync(ActivityData activityData) { var state = await GetStateAsync(); @@ -48,15 +55,15 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep public async Task<(Guid SessionId, bool IsFirstSession)> GetOrCreateSessionAsync() { var isFirstSession = !File.Exists(TelemetryPaths.ActivityStorage); - + var state = await GetStateAsync(); - + if (state.SessionId is null) { state.SessionId = Guid.NewGuid(); await SaveAsync(); } - + return (state.SessionId.Value, isFirstSession); } @@ -108,6 +115,12 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep return ShouldAddInfo(lastSend); } + public virtual async Task ShouldSendActivitiesAsync() + { + var lastActivitySendTime = await GetLastActivitySendTimeAsync(); + return lastActivitySendTime is null || DateTimeOffset.UtcNow - lastActivitySendTime > _options.ActivitySendPeriod; + } + private async Task GetLastSolutionInfoSendTimeAsync(Guid solutionId) { var state = await GetStateAsync(); @@ -138,7 +151,7 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep { using var reader = new StreamReader(stream, Encoding.UTF8); var json = await reader.ReadToEndAsync(); - return JsonSerializer.Deserialize(json, GetJsonSerializerOptions()) + return JsonSerializer.Deserialize(json, GetJsonSerializerOptions()) ?? new TelemetryActivityStorageState(); }) ?? new TelemetryActivityStorageState(); return _cachedState; @@ -218,8 +231,8 @@ public class TelemetryActivityStorage : ITelemetryActivityStorage, ISingletonDep }; } - private static bool ShouldAddInfo(DateTimeOffset? lastSend) + private bool ShouldAddInfo(DateTimeOffset? lastSend) { - return lastSend is null || DateTimeOffset.UtcNow - lastSend > InfoExpirationPeriod; + return lastSend is null || DateTimeOffset.UtcNow - lastSend > _options.InfoExpirationPeriod; } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorageOptions.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorageOptions.cs new file mode 100644 index 0000000000..e5f1d5b491 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/Storage/TelemetryActivityStorageOptions.cs @@ -0,0 +1,10 @@ +using System; + +namespace Volo.Abp.Telemetry.Activity.Storage; + +public class TelemetryActivityStorageOptions +{ + public TimeSpan InfoExpirationPeriod { get; set; } = TimeSpan.FromDays(7); + + public TimeSpan ActivitySendPeriod { get; set; } = TimeSpan.FromDays(1); +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryService.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryService.cs index 81bf294f85..58c0d5c491 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryService.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryService.cs @@ -54,7 +54,7 @@ public class TelemetryService : ITelemetryService, IScopedDependency }); } - + public Task AddActivityAsync(ActivityData data) { @@ -70,7 +70,10 @@ public class TelemetryService : ITelemetryService, IScopedDependency await _telemetryActivityStorage.EndSessionAsync(); } - await SendActivityIfDueAsync(); + if (await _telemetryActivityStorage.ShouldSendActivitiesAsync()) + { + await _telemetryDataSender.SendAsync(); + } } catch { @@ -96,7 +99,7 @@ public class TelemetryService : ITelemetryService, IScopedDependency await AddActivityAsync(activityData); } - public async Task AddErrorActivityAsync(Action> configure) + public async Task AddErrorActivityAsync(Action> configure) { var activityData = new ActivityData(ActivityNameConsts.Error) { @@ -121,13 +124,5 @@ public class TelemetryService : ITelemetryService, IScopedDependency await AddActivityAsync(activityData); } - private async Task SendActivityIfDueAsync() - { - var lastActivitySendTime = await _telemetryActivityStorage.GetLastActivitySendTimeAsync(); - - if (lastActivitySendTime is not null && lastActivitySendTime < DateTimeOffset.UtcNow.AddDays(-1)) - { - await _telemetryDataSender.SendAsync(); - } - } + } \ No newline at end of file