From 371d23852bebf865c73a9a3ff26f7f08b8b36abb Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Mon, 29 Nov 2021 20:22:12 -0700 Subject: [PATCH] WIP metrics reports --- Wabbajack.CLI/Program.cs | 1 + Wabbajack.CLI/Verbs/GenerateMetricsReports.cs | 58 +++++++++++++++++++ .../ServerResponses/MetricResponse.cs | 14 +++++ Wabbajack.Server/Controllers/Metrics.cs | 8 +-- Wabbajack.Server/DataModels/Metrics.cs | 10 +--- 5 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 Wabbajack.CLI/Verbs/GenerateMetricsReports.cs create mode 100644 Wabbajack.DTOs/ServerResponses/MetricResponse.cs diff --git a/Wabbajack.CLI/Program.cs b/Wabbajack.CLI/Program.cs index 9ef7249e..d871e63f 100644 --- a/Wabbajack.CLI/Program.cs +++ b/Wabbajack.CLI/Program.cs @@ -60,6 +60,7 @@ internal class Program services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); }).Build(); var service = host.Services.GetService(); diff --git a/Wabbajack.CLI/Verbs/GenerateMetricsReports.cs b/Wabbajack.CLI/Verbs/GenerateMetricsReports.cs new file mode 100644 index 00000000..ec329db8 --- /dev/null +++ b/Wabbajack.CLI/Verbs/GenerateMetricsReports.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.IO; +using System.Net.Http; +using System.Threading.Tasks; +using Wabbajack.Common; +using Wabbajack.DTOs.JsonConverters; +using Wabbajack.DTOs.ServerResponses; +using Wabbajack.Paths; + +namespace Wabbajack.CLI.Verbs; + +public class GenerateMetricsReports : IVerb +{ + private readonly HttpClient _client; + private readonly DTOSerializer _dtos; + + public GenerateMetricsReports(HttpClient client, DTOSerializer dtos) + { + _client = client; + _dtos = dtos; + } + public Command MakeCommand() + { + var command = new Command("generate-metrics-report"); + command.Add(new Option(new[] {"-o", "-output"}, "Output folder")); + command.Description = "Generates usage metrics and outputs a html report about them"; + command.Handler = CommandHandler.Create(Run); + return command; + + + } + + private async Task Run(AbsolutePath output) + { + var subjects = await GetMetrics("one day ago", "now", "finish_install") + .Select(async d => d.GroupingSubject) + .ToHashSet(); + + return 0; + } + + private async IAsyncEnumerable GetMetrics(string start, string end, string action) + { + await using var response = await _client.GetStreamAsync(new Uri($"https://build.wabbajack.org/metrics/report?action={action}&from={start}&end={end}")); + + var sr = new StreamReader(response, leaveOpen: false); + + while (true) + { + var line = await sr.ReadLineAsync(); + if (line == null) break; + yield return _dtos.Deserialize(line)!; + } + } +} \ No newline at end of file diff --git a/Wabbajack.DTOs/ServerResponses/MetricResponse.cs b/Wabbajack.DTOs/ServerResponses/MetricResponse.cs new file mode 100644 index 00000000..5c3bd5c0 --- /dev/null +++ b/Wabbajack.DTOs/ServerResponses/MetricResponse.cs @@ -0,0 +1,14 @@ +using System; + +namespace Wabbajack.DTOs.ServerResponses; + + +public class MetricResult +{ + public string Action { get; set; } + public string Subject { get; set; } + public string GroupingSubject { get; set; } + public long MetricKey { get; set; } + public string UserAgent { get; set; } + public DateTime Timestamp { get; set; } +} \ No newline at end of file diff --git a/Wabbajack.Server/Controllers/Metrics.cs b/Wabbajack.Server/Controllers/Metrics.cs index 9ee80f8a..e89fe366 100644 --- a/Wabbajack.Server/Controllers/Metrics.cs +++ b/Wabbajack.Server/Controllers/Metrics.cs @@ -64,20 +64,20 @@ public class MetricsController : ControllerBase } [HttpGet] - [Route("{subject}/{value}")] - public async Task LogMetricAsync(string subject, string value) + [Route("{action}/{subject}")] + public async Task LogMetricAsync(string action, string subject) { var date = DateTime.UtcNow; var metricsKey = Request.Headers[_settings.MetricsKeyHeader].FirstOrDefault(); // Used in tests - if (value is "Default" or "untitled" || subject == "failed_download" || Guid.TryParse(value, out _)) + if (subject is "Default" or "untitled" || subject == "failed_download" || Guid.TryParse(subject, out _)) return new Result {Timestamp = date}; await _metricsStore.Ingest(new Metric { Timestamp = DateTime.UtcNow, - Action = subject, + Action = action, Subject = subject, MetricsKey = metricsKey, UserAgent = Request.Headers.UserAgent.FirstOrDefault() ?? "", diff --git a/Wabbajack.Server/DataModels/Metrics.cs b/Wabbajack.Server/DataModels/Metrics.cs index 3e2acf25..b6f79fa9 100644 --- a/Wabbajack.Server/DataModels/Metrics.cs +++ b/Wabbajack.Server/DataModels/Metrics.cs @@ -9,6 +9,7 @@ using Microsoft.Toolkit.HighPerformance; using Wabbajack.BuildServer; using Wabbajack.Common; using Wabbajack.DTOs.JsonConverters; +using Wabbajack.DTOs.ServerResponses; using Wabbajack.Paths; using Wabbajack.Paths.IO; using Wabbajack.Server.DTOs; @@ -104,13 +105,4 @@ public class Metrics } } - public class MetricResult - { - public string Action { get; set; } - public string Subject { get; set; } - public string GroupingSubject { get; set; } - public long MetricKey { get; set; } - public string UserAgent { get; set; } - public DateTime Timestamp { get; set; } - } } \ No newline at end of file