From 609a0297d590785b1a5ecf002879e54ac38ae16f Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Tue, 13 May 2025 17:22:47 +0200
Subject: [PATCH] moved diagnose to own controller, added advanced diagnose
building, ui for advanced still missing
---
.../Admin/Sys/DiagnoseController.cs | 44 ++++++++++++
.../Controllers/Admin/Sys/SystemController.cs | 16 +----
.../Services/DiagnoseService.cs | 71 +++++++++++++++----
.../UI/Views/Admin/Sys/Diagnose.razor | 43 +++++++++--
...SystemAvailableDiagnoseProviderResponse.cs | 8 +++
Moonlight.Shared/Misc/DiagnoseProvider.cs | 8 +++
6 files changed, 155 insertions(+), 35 deletions(-)
create mode 100644 Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs
create mode 100644 Moonlight.Shared/Http/Responses/Admin/Sys/SystemAvailableDiagnoseProviderResponse.cs
create mode 100644 Moonlight.Shared/Misc/DiagnoseProvider.cs
diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs
new file mode 100644
index 00000000..b4ecd92c
--- /dev/null
+++ b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs
@@ -0,0 +1,44 @@
+using Microsoft.AspNetCore.Mvc;
+using MoonCore.Attributes;
+using Moonlight.ApiServer.Services;
+using Moonlight.Shared.Http.Requests.Admin.Sys;
+using Moonlight.Shared.Http.Responses.Admin.Sys;
+using Moonlight.Shared.Misc;
+
+
+namespace Moonlight.ApiServer.Http.Controllers.Admin.Sys;
+
+[ApiController]
+[Route("api/admin/system/diagnose")]
+public class DiagnoseController : Controller
+{
+ private readonly DiagnoseService DiagnoseService;
+
+ public DiagnoseController(DiagnoseService diagnoseService)
+ {
+ DiagnoseService = diagnoseService;
+ }
+
+ [HttpPost]
+ [RequirePermission("admin.system.diagnose")]
+ public async Task Diagnose([FromBody] string[]? requestedDiagnoseProviders = null)
+ {
+ var stream = new MemoryStream();
+
+ await DiagnoseService.GenerateDiagnose(stream, requestedDiagnoseProviders);
+
+ return File(stream, "application/zip", "diagnose.zip");
+ }
+
+ [HttpGet("available")]
+ [RequirePermission("admin.system.diagnose")]
+ public async Task GetAvailable()
+ {
+ var availableProviders = await DiagnoseService.GetAvailable();
+
+ return new SystemAvailableDiagnoseProviderResponse()
+ {
+ AvailableProviders = availableProviders
+ };
+ }
+}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
index faeef12f..b2ad01ae 100644
--- a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
+++ b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
@@ -18,13 +18,12 @@ public class SystemController : Controller
{
private readonly ApplicationService ApplicationService;
private readonly IEnumerable DiagnoseProviders;
- private readonly DiagnoseService DiagnoseService;
- public SystemController(ApplicationService applicationService, IEnumerable diagnoseProviders, DiagnoseService diagnoseService)
+
+ public SystemController(ApplicationService applicationService, IEnumerable diagnoseProviders)
{
ApplicationService = applicationService;
DiagnoseProviders = diagnoseProviders;
- DiagnoseService = diagnoseService;
}
[HttpGet]
@@ -46,15 +45,4 @@ public class SystemController : Controller
{
await ApplicationService.Shutdown();
}
-
- [HttpGet("diagnose")]
- [RequirePermission("admin.system.diagnose")]
- public async Task Diagnose()
- {
- var stream = new MemoryStream();
-
- await DiagnoseService.GenerateDiagnose(stream);
-
- return File(stream, "application/zip", "diagnose.zip");
- }
}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Services/DiagnoseService.cs b/Moonlight.ApiServer/Services/DiagnoseService.cs
index 3c4aca15..5d3024af 100644
--- a/Moonlight.ApiServer/Services/DiagnoseService.cs
+++ b/Moonlight.ApiServer/Services/DiagnoseService.cs
@@ -3,13 +3,14 @@ using Moonlight.ApiServer.Interfaces;
using Moonlight.ApiServer.Models.Diagnose;
using System.IO.Compression;
using MoonCore.Attributes;
+using Moonlight.Shared.Http.Responses.Admin.Sys;
+using Moonlight.Shared.Misc;
namespace Moonlight.ApiServer.Services;
[Scoped]
public class DiagnoseService
{
-
private readonly IEnumerable DiagnoseProviders;
public DiagnoseService(IEnumerable diagnoseProviders)
@@ -17,21 +18,62 @@ public class DiagnoseService
DiagnoseProviders = diagnoseProviders;
}
- public async Task GenerateDiagnose(Stream outputStream)
+ public async Task GetAvailable()
{
- var tasks = DiagnoseProviders
+ var availableProviders = new List();
+
+ foreach (var diagnoseProvider in DiagnoseProviders)
+ {
+ var name = diagnoseProvider.GetType().Name;
+
+ var type = diagnoseProvider.GetType().FullName;
+
+ // The type name is null if the type is a generic type, unlikely, but still could happen
+ if (type != null)
+ availableProviders.Add(new DiagnoseProvider()
+ {
+ Name = name,
+ Type = type
+ });
+ }
+
+ return availableProviders.ToArray();
+ }
+
+ public async Task GenerateDiagnose(Stream outputStream, string[]? requestedProviders)
+ {
+ List providers;
+
+ if (requestedProviders != null && requestedProviders.Length > 0)
+ {
+ providers = new List();
+
+ foreach (var requestedProvider in requestedProviders)
+ {
+ var provider = DiagnoseProviders.FirstOrDefault(x => x.GetType().FullName == requestedProvider);
+
+ if (provider != null)
+ providers.Add(provider);
+ }
+ }
+ else
+ {
+ providers = DiagnoseProviders.ToList();
+ }
+
+
+ var tasks = providers
.SelectMany(x => x.GetFiles())
.Select(async x => await ProcessDiagnoseEntry(null, x));
-
+
var fileEntries = (await Task.WhenAll(tasks))
.SelectMany(x => x)
.ToDictionary();
-
+
try
{
-
using (var zip = new ZipArchive(outputStream, ZipArchiveMode.Create, leaveOpen: true))
{
foreach (var kv in fileEntries)
@@ -57,11 +99,11 @@ public class DiagnoseService
throw new Exception($"An unknown error occured while building the Diagnose: {ex.Message}");
}
}
-
+
private async Task> ProcessDiagnoseEntry(string? path, DiagnoseEntry entry)
{
var fileEntries = new Dictionary();
-
+
switch (entry)
{
case DiagnoseDirectory diagnoseDirectory:
@@ -80,20 +122,20 @@ public class DiagnoseService
var file = await ProcessDiagnoseFile(path, diagnoseFile);
fileEntries.Add(file.Key, file.Value);
-
+
break;
}
}
return fileEntries;
}
-
+
private async Task> ProcessDiagnoseDirectory(string? path, DiagnoseDirectory directory)
{
var result = new Dictionary();
- var directoryPath = path != null ? string.Join("/", path, directory.Name) : directory.Name;
-
+ var directoryPath = path != null ? string.Join("/", path, directory.Name) : directory.Name;
+
foreach (var entry in directory.Children)
{
var files = await ProcessDiagnoseEntry(directoryPath, entry);
@@ -103,14 +145,13 @@ public class DiagnoseService
result.Add(file.Key, file.Value);
}
}
-
+
return result;
}
private async Task> ProcessDiagnoseFile(string? path, DiagnoseFile file)
{
-
- var filePath = path != null ? string.Join("/", path, file.Name) : file.Name;
+ var filePath = path != null ? string.Join("/", path, file.Name) : file.Name;
var bytes = file.GetContent();
diff --git a/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
index 079cf665..596da604 100644
--- a/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
+++ b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
@@ -2,6 +2,8 @@
@using MoonCore.Attributes
@using MoonCore.Helpers
+@using Moonlight.Shared.Http.Responses.Admin.Sys
+@using Moonlight.Shared.Misc
@attribute [RequirePermission("admin.system.diagnose")]
@@ -25,22 +27,51 @@
The report includes useful information about your system, plugins, and environment, making it easier to identify problems or share with support.
- Generate diagnose
+ Generate diagnose
+
+ @* *@
+ @*
Advanced *@
+ @* *@
+ @*
*@
+ @* *@
+ @* *@
+ @*
*@
+ @* *@
+ @* @for (int i = 0; i < AvailableProviders.Length; i++) *@
+ @* { *@
+ @* *@
+ @* @Formatter.ConvertCamelCaseToSpaces(AvailableProviders[i].Name) *@
+ @*
*@
+ @* } *@
+ @* *@
+ @* *@
+ @* *@
+ @* *@
+ @*
*@
+ @* *@
+ @*
*@
@code
{
- private async Task GenerateFrontend(WButton _)
- {
- var stream = await ApiClient.GetStream("api/admin/system/diagnose");
+ private async Task GenerateDiagnose(WButton _)
+ {
+ var stream = await ApiClient.PostStream("api/admin/system/diagnose");
+
await DownloadService.DownloadStream("diagnose.zip", stream);
}
-}
+
+ private async Task Load(LazyLoader arg)
+ {
+ // AvailableProviders = (await ApiClient.GetJson("api/admin/system/diagnose/available")).AvailableProviders;
+ }
+
+
+
-@code {
}
\ No newline at end of file
diff --git a/Moonlight.Shared/Http/Responses/Admin/Sys/SystemAvailableDiagnoseProviderResponse.cs b/Moonlight.Shared/Http/Responses/Admin/Sys/SystemAvailableDiagnoseProviderResponse.cs
new file mode 100644
index 00000000..a32fe302
--- /dev/null
+++ b/Moonlight.Shared/Http/Responses/Admin/Sys/SystemAvailableDiagnoseProviderResponse.cs
@@ -0,0 +1,8 @@
+using Moonlight.Shared.Misc;
+
+namespace Moonlight.Shared.Http.Responses.Admin.Sys;
+
+public class SystemAvailableDiagnoseProviderResponse
+{
+ public DiagnoseProvider[] AvailableProviders { get; set; }= [];
+}
diff --git a/Moonlight.Shared/Misc/DiagnoseProvider.cs b/Moonlight.Shared/Misc/DiagnoseProvider.cs
new file mode 100644
index 00000000..dd552700
--- /dev/null
+++ b/Moonlight.Shared/Misc/DiagnoseProvider.cs
@@ -0,0 +1,8 @@
+namespace Moonlight.Shared.Misc;
+
+public class DiagnoseProvider
+{
+ public string Name { get; set; }
+
+ public string Type { get; set; }
+}
\ No newline at end of file