diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityDataProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityDataProvider.cs index 58453d6e4b..a4c70c2697 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityDataProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityDataProvider.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; -using System.Net.Http.Json; using System.Text.Json; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -35,7 +34,6 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency public async Task AddDeviceInformationAsync(ActivityData activityData) { - activityData.Add(ActivityPropertyName.DeviceId, await _deviceInfoProvider.GetDeviceIdAsync()); activityData.Add(ActivityPropertyName.DeviceType, _deviceInfoProvider.GetDeviceType()); activityData.Add(ActivityPropertyName.DeviceLanguage, _deviceInfoProvider.GetLanguage()); activityData.Add(ActivityPropertyName.OperatingSystem, _deviceInfoProvider.GetOperatingSystem()); @@ -60,20 +58,18 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency return; } - var solutionPath = value as string; - if (string.IsNullOrEmpty(solutionPath) || !File.Exists(solutionPath)) + var solutionPath = (string)value; + if (!File.Exists(solutionPath)) { return; } - var solutionJson = await File.ReadAllTextAsync(solutionPath); + var solutionJson = File.ReadAllText(solutionPath); using var solutionDoc = JsonDocument.Parse(solutionJson); var root = solutionDoc.RootElement; - - if (!TryAddSolutionId(activityData, root, out var solutionId)) - { - return; - } + var solutionId = GetSolutionId(root); + + activityData.Add(ActivityPropertyName.SolutionId, solutionId); if (root.TryGetProperty("creatingStudioConfiguration", out var config)) { @@ -84,22 +80,38 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency if (root.TryGetProperty("modules", out var modulesElement) && modulesElement.ValueKind == JsonValueKind.Object) { - var modules = await ExtractModulesAsync(modulesElement); + var modules = ExtractModulesAsync(modulesElement); activityData.Add(ActivityPropertyName.InstalledModules, modules); } } - private bool TryAddSolutionId(ActivityData activityData, JsonElement root, out Guid solutionId) + public async Task ReadDeviceIdAsync() { - solutionId = Guid.Empty; - if (!root.TryGetProperty("id", out var idElement) || - !Guid.TryParse(idElement.GetString(), out solutionId)) + return await _deviceInfoProvider.GetDeviceIdAsync(); + } + + public Guid? ReadSolutionId(string solutionPath) + { + if (!File.Exists(solutionPath)) { - return false; + return null; } + var solutionJson = File.ReadAllText(solutionPath); + using var solutionDoc = JsonDocument.Parse(solutionJson); + var root = solutionDoc.RootElement; - activityData.Add(ActivityPropertyName.SolutionId, solutionId); - return true; + return GetSolutionId(root); + } + + private Guid GetSolutionId(JsonElement root) + { + if (root.TryGetProperty("id", out var idElement) && + Guid.TryParse(idElement.GetString(), out var solutionId)) + { + return solutionId; + } + + throw new Exception("Solution ID is not valid."); } private void AddCreatingStudioConfiguration(ActivityData activityData, JsonElement config) @@ -133,7 +145,7 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency activityData.Add(ActivityPropertyName.SocialLogins, config.GetProperty("socialLogin").GetBoolean()); } - private async Task> ExtractModulesAsync(JsonElement modulesElement) + private List ExtractModulesAsync(JsonElement modulesElement) { var modules = new List(); @@ -151,7 +163,7 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency continue; } - var moduleJson = await File.ReadAllTextAsync(path); + var moduleJson = File.ReadAllText(path); using var moduleDoc = JsonDocument.Parse(moduleJson); if (!moduleDoc.RootElement.TryGetProperty("imports", out var importsElement) || @@ -283,9 +295,9 @@ public class ActivityDataProvider : IActivityDataProvider, IScopedDependency httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); - await using var stream = await httpClient.GetStreamAsync($"{AbpPlatformUrls.AbpIoUrl}api/license/api-key"); - using var doc = await JsonDocument.ParseAsync(stream); + var json = await httpClient.GetStringAsync($"{AbpPlatformUrls.AbpIoUrl}api/license/api-key"); + using var doc = JsonDocument.Parse(json); return doc.RootElement.GetProperty("licenseType").GetInt32(); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityStorage.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityStorage.cs index d6c043f6e0..a03e0b4866 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityStorage.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/ActivityStorage.cs @@ -28,7 +28,7 @@ public class ActivityStorage : IActivityStorage, ISingletonDependency public async Task> GetBufferedActivitiesAsync() { var state = await GetStateAsync(); - return state.Activities; + return state.Activities.OrderBy(x => x.Time).ToList(); } public async Task RemoveActivityAsync(string activityName, CancellationToken cancellationToken = default) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/IActivityDataProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/IActivityDataProvider.cs index 0d74a2a682..a66ab1308d 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/IActivityDataProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/Activity/IActivityDataProvider.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -9,4 +10,6 @@ public interface IActivityDataProvider Task AddDeviceInformationAsync(ActivityData activityData); Task AddApplicationInformation(ActivityData activityData); Task AddSolutionInformationAsync(ActivityData activityData); + Task ReadDeviceIdAsync(); + Guid? ReadSolutionId(string solutionPath); } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryDataSender.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryDataSender.cs index d2eb0837ca..00f2d30710 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryDataSender.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryDataSender.cs @@ -15,9 +15,8 @@ using Volo.Abp.Telemetry.Shared; namespace Volo.Abp.Telemetry; -public class TelemetryDataSender : ITelemetryDataSender , IScopedDependency +public class TelemetryDataSender : ITelemetryDataSender, IScopedDependency { - private readonly IActivityStorage _activityStorage; private readonly IActivityDataProvider _activityDataProvider; private const int ActivityBatchSize = 50; @@ -37,12 +36,17 @@ public class TelemetryDataSender : ITelemetryDataSender , IScopedDependency if (activities.Count > 0) { - await AddExtraInformationAsync(activities[0]); for (var i = 0; i < activities.Count; i += ActivityBatchSize) { var activityBatch = activities.Skip(i).Take(ActivityBatchSize).ToList(); - await httpClient.PostAsync($"{AbpPlatformUrls.TelemetryApiUrl}api/telemetry/collect", new StringContent(JsonSerializer.Serialize(activityBatch), Encoding.UTF8, "application/json")); + foreach (var activity in activityBatch) + { + await AddExtraInformationAsync(activity); + } + + await httpClient.PostAsync($"{AbpPlatformUrls.TelemetryApiUrl}api/telemetry/collect", + new StringContent(JsonSerializer.Serialize(activityBatch), Encoding.UTF8, "application/json")); } await _activityStorage.MarkActivitiesAsSentAsync(); @@ -58,13 +62,15 @@ public class TelemetryDataSender : ITelemetryDataSender , IScopedDependency activityData.Add(ActivityPropertyName.SessionId, sessionId); activityData.Add(ActivityPropertyName.IsFirstSession, isFirstSession); + activityData.Add(ActivityPropertyName.DeviceId, await _activityDataProvider.ReadDeviceIdAsync()); + + var lastDeviceInfoSendTime = await _activityStorage.GetLastDeviceInfoSendTimeAsync(); if (lastDeviceInfoSendTime is null || DateTimeOffset.UtcNow - lastDeviceInfoSendTime > TimeSpan.FromDays(7)) { await _activityDataProvider.AddDeviceInformationAsync(activityData); await _activityStorage.MarkDeviceInfoAsSentAsync(); - } if (activityData.ContainsKey(ActivityPropertyName.Assembly)) @@ -74,21 +80,20 @@ public class TelemetryDataSender : ITelemetryDataSender , IScopedDependency if (activityData.TryGetValue(ActivityPropertyName.SolutionPath, out var path)) { - var solutionPath = path as string; - if (string.IsNullOrEmpty(solutionPath) || !File.Exists(solutionPath)) + var id = _activityDataProvider.ReadSolutionId((string)path); + if (id.HasValue) { - return; + activityData.Add(ActivityPropertyName.SolutionId, id); + await _activityDataProvider.AddSolutionInformationAsync(activityData); } - - await _activityDataProvider.AddSolutionInformationAsync(activityData); } - } catch { //ignored } } + private static void AddAbpAuthenticationTokenAsync(HttpClient httpClient) { if (!File.Exists(AbpTelemetryPaths.AccessToken)) 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 00f1c434d4..6f21dac006 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryService.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Telemetry/TelemetryService.cs @@ -58,7 +58,7 @@ public class TelemetryService : ITelemetryService , IScopedDependency await _telemetryDataSender.SendAsync(); } - if (lastActivitySendTime is not null && lastActivitySendTime > DateTimeOffset.UtcNow.AddDays(7) ) + if (lastActivitySendTime is not null && lastActivitySendTime < DateTimeOffset.UtcNow.AddDays(-1) ) { await _telemetryDataSender.SendAsync(); }