From 8ac2d20d8a3d2246f6c6ce890c84b66cd29f7db0 Mon Sep 17 00:00:00 2001
From: moritz
Date: Sun, 11 May 2025 13:03:44 +0200
Subject: [PATCH 01/14] added base diagnose, is not working, yet, still
contains test objects
---
Moonlight.ApiServer/Helpers/DiagnoseHelper.cs | 6 ++++++
.../Diagnose/CoreDiagnoseProvider.cs | 16 ++++++++++++++++
.../Implementations/Diagnose/TestProvider.cs | 6 ++++++
.../Interfaces/IDiagnoseProvider.cs | 8 ++++++++
.../Models/Diagnose/DiagnoseDirectory.cs | 7 +++++++
.../Models/Diagnose/DiagnoseEntry.cs | 8 ++++++++
.../Models/Diagnose/DiagnoseFile.cs | 8 ++++++++
7 files changed, 59 insertions(+)
create mode 100644 Moonlight.ApiServer/Helpers/DiagnoseHelper.cs
create mode 100644 Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
create mode 100644 Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs
create mode 100644 Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
create mode 100644 Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs
create mode 100644 Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
create mode 100644 Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs
diff --git a/Moonlight.ApiServer/Helpers/DiagnoseHelper.cs b/Moonlight.ApiServer/Helpers/DiagnoseHelper.cs
new file mode 100644
index 00000000..5095e355
--- /dev/null
+++ b/Moonlight.ApiServer/Helpers/DiagnoseHelper.cs
@@ -0,0 +1,6 @@
+namespace Moonlight.ApiServer.Helpers;
+
+public class DiagnoseHelper
+{
+
+}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
new file mode 100644
index 00000000..479c8991
--- /dev/null
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
@@ -0,0 +1,16 @@
+using System.Text;
+using Moonlight.ApiServer.Interfaces;
+using Moonlight.ApiServer.Models.Diagnose;
+
+namespace Moonlight.ApiServer.Implementations.Diagnose;
+
+public class CoreDiagnoseProvider : IDiagnoseProvider
+{
+ public async Task GetFiles()
+ {
+ return new DiagnoseFile()
+ {
+ GetContent = () => Encoding.UTF8.GetBytes("hello world")
+ };
+ }
+}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs
new file mode 100644
index 00000000..2b6e4b7b
--- /dev/null
+++ b/Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs
@@ -0,0 +1,6 @@
+namespace Moonlight.ApiServer.Implementations.Diagnose;
+
+public class TestProvider
+{
+
+}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs b/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
new file mode 100644
index 00000000..02ad81b7
--- /dev/null
+++ b/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
@@ -0,0 +1,8 @@
+using Moonlight.ApiServer.Models.Diagnose;
+
+namespace Moonlight.ApiServer.Interfaces;
+
+public interface IDiagnoseProvider
+{
+ public Task GetFiles();
+}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs b/Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs
new file mode 100644
index 00000000..85bda05a
--- /dev/null
+++ b/Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs
@@ -0,0 +1,7 @@
+namespace Moonlight.ApiServer.Models.Diagnose;
+
+public class DiagnoseDirectory : DiagnoseEntry
+{
+ public List Children { get; set; } = new();
+ public override bool IsDirectory => true;
+}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs b/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
new file mode 100644
index 00000000..96dc3439
--- /dev/null
+++ b/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
@@ -0,0 +1,8 @@
+namespace Moonlight.ApiServer.Models.Diagnose;
+
+public abstract class DiagnoseEntry
+{
+ public string Name { get; set; } = "";
+
+ public abstract bool IsDirectory { get; }
+}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs b/Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs
new file mode 100644
index 00000000..dfeeb3aa
--- /dev/null
+++ b/Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs
@@ -0,0 +1,8 @@
+namespace Moonlight.ApiServer.Models.Diagnose;
+
+public class DiagnoseFile : DiagnoseEntry
+{
+ public Func GetContent = () => [];
+
+ public override bool IsDirectory => false;
+}
\ No newline at end of file
From bd8ea67017d5933bb89f3ada37174be54a30485f Mon Sep 17 00:00:00 2001
From: moritz
Date: Mon, 12 May 2025 16:51:29 +0200
Subject: [PATCH 02/14] zip extracts now, still some issues with the ressource
building
---
Moonlight.ApiServer/Helpers/DiagnoseHelper.cs | 6 ------
Moonlight.ApiServer/Services/DiagnoseService.cs | 6 ++++++
2 files changed, 6 insertions(+), 6 deletions(-)
delete mode 100644 Moonlight.ApiServer/Helpers/DiagnoseHelper.cs
create mode 100644 Moonlight.ApiServer/Services/DiagnoseService.cs
diff --git a/Moonlight.ApiServer/Helpers/DiagnoseHelper.cs b/Moonlight.ApiServer/Helpers/DiagnoseHelper.cs
deleted file mode 100644
index 5095e355..00000000
--- a/Moonlight.ApiServer/Helpers/DiagnoseHelper.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Moonlight.ApiServer.Helpers;
-
-public class DiagnoseHelper
-{
-
-}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Services/DiagnoseService.cs b/Moonlight.ApiServer/Services/DiagnoseService.cs
new file mode 100644
index 00000000..1abdeafa
--- /dev/null
+++ b/Moonlight.ApiServer/Services/DiagnoseService.cs
@@ -0,0 +1,6 @@
+namespace Moonlight.ApiServer.Services;
+
+public class DiagnoseService
+{
+
+}
\ No newline at end of file
From a4e0175173b026035fd25c88ea296e840ab5b566 Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Mon, 12 May 2025 19:00:09 +0200
Subject: [PATCH 03/14] finished diagnose system
---
.../Controllers/Admin/Sys/SystemController.cs | 24 +++-
.../Diagnose/CoreDiagnoseProvider.cs | 14 ++-
.../Implementations/Diagnose/TestProvider.cs | 6 -
.../Implementations/Startup/CoreStartup.cs | 8 ++
.../Interfaces/IDiagnoseProvider.cs | 2 +-
.../Models/Diagnose/DiagnoseEntry.cs | 2 +-
.../Services/DiagnoseService.cs | 113 ++++++++++++++++++
7 files changed, 155 insertions(+), 14 deletions(-)
delete mode 100644 Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs
diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
index b0c9f8d2..faeef12f 100644
--- a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
+++ b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
@@ -1,5 +1,12 @@
+using System.IO.Compression;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging.Console;
using MoonCore.Attributes;
+using MoonCore.Exceptions;
+using MoonCore.Helpers;
+using Moonlight.ApiServer.Helpers;
+using Moonlight.ApiServer.Interfaces;
+using Moonlight.ApiServer.Models.Diagnose;
using Moonlight.ApiServer.Services;
using Moonlight.Shared.Http.Responses.Admin.Sys;
@@ -10,10 +17,14 @@ namespace Moonlight.ApiServer.Http.Controllers.Admin.Sys;
public class SystemController : Controller
{
private readonly ApplicationService ApplicationService;
+ private readonly IEnumerable DiagnoseProviders;
+ private readonly DiagnoseService DiagnoseService;
- public SystemController(ApplicationService applicationService)
+ public SystemController(ApplicationService applicationService, IEnumerable diagnoseProviders, DiagnoseService diagnoseService)
{
ApplicationService = applicationService;
+ DiagnoseProviders = diagnoseProviders;
+ DiagnoseService = diagnoseService;
}
[HttpGet]
@@ -35,4 +46,15 @@ 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/Implementations/Diagnose/CoreDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
index 479c8991..92d5d09a 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
@@ -6,11 +6,15 @@ namespace Moonlight.ApiServer.Implementations.Diagnose;
public class CoreDiagnoseProvider : IDiagnoseProvider
{
- public async Task GetFiles()
+ public DiagnoseEntry[] GetFiles()
{
- return new DiagnoseFile()
- {
- GetContent = () => Encoding.UTF8.GetBytes("hello world")
- };
+ return
+ [
+ new DiagnoseFile()
+ {
+ Name = "test.txt",
+ GetContent = () => Encoding.UTF8.GetBytes("hello world")
+ }
+ ];
}
}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs
deleted file mode 100644
index 2b6e4b7b..00000000
--- a/Moonlight.ApiServer/Implementations/Diagnose/TestProvider.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Moonlight.ApiServer.Implementations.Diagnose;
-
-public class TestProvider
-{
-
-}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs b/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs
index 6ca274db..19782349 100644
--- a/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs
+++ b/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs
@@ -1,6 +1,8 @@
using Microsoft.OpenApi.Models;
using Moonlight.ApiServer.Configuration;
using Moonlight.ApiServer.Database;
+using Moonlight.ApiServer.Implementations.Diagnose;
+using Moonlight.ApiServer.Interfaces;
using Moonlight.ApiServer.Interfaces.Startup;
namespace Moonlight.ApiServer.Implementations.Startup;
@@ -48,6 +50,12 @@ public class CoreStartup : IPluginStartup
builder.Services.AddDbContext();
+ #endregion
+
+ #region Diagnose
+
+ builder.Services.AddSingleton();
+
#endregion
return Task.CompletedTask;
diff --git a/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs b/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
index 02ad81b7..d2f1b95c 100644
--- a/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
@@ -4,5 +4,5 @@ namespace Moonlight.ApiServer.Interfaces;
public interface IDiagnoseProvider
{
- public Task GetFiles();
+ public DiagnoseEntry[] GetFiles();
}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs b/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
index 96dc3439..f83d4670 100644
--- a/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
+++ b/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
@@ -2,7 +2,7 @@ namespace Moonlight.ApiServer.Models.Diagnose;
public abstract class DiagnoseEntry
{
- public string Name { get; set; } = "";
+ public required string Name { get; set; } = "";
public abstract bool IsDirectory { get; }
}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Services/DiagnoseService.cs b/Moonlight.ApiServer/Services/DiagnoseService.cs
index 1abdeafa..3c4aca15 100644
--- a/Moonlight.ApiServer/Services/DiagnoseService.cs
+++ b/Moonlight.ApiServer/Services/DiagnoseService.cs
@@ -1,6 +1,119 @@
+using MoonCore.Helpers;
+using Moonlight.ApiServer.Interfaces;
+using Moonlight.ApiServer.Models.Diagnose;
+using System.IO.Compression;
+using MoonCore.Attributes;
+
namespace Moonlight.ApiServer.Services;
+[Scoped]
public class DiagnoseService
{
+
+ private readonly IEnumerable DiagnoseProviders;
+
+ public DiagnoseService(IEnumerable diagnoseProviders)
+ {
+ DiagnoseProviders = diagnoseProviders;
+ }
+
+ public async Task GenerateDiagnose(Stream outputStream)
+ {
+ var tasks = DiagnoseProviders
+ .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)
+ {
+ string entryName = kv.Key.Replace('\\', '/');
+ byte[] data = kv.Value;
+
+ // Optionally pick CompressionLevel.Optimal or NoCompression
+ var entry = zip.CreateEntry(entryName, CompressionLevel.Fastest);
+
+ using (var entryStream = entry.Open())
+ using (var ms = new MemoryStream(data))
+ {
+ await ms.CopyToAsync(entryStream);
+ }
+ }
+ }
+
+ outputStream.Seek(0, SeekOrigin.Begin);
+ }
+ catch (Exception ex)
+ {
+ 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:
+ {
+ var files = await ProcessDiagnoseDirectory(path, diagnoseDirectory);
+
+ foreach (var file in files)
+ {
+ fileEntries.Add(file.Key, file.Value);
+ }
+
+ break;
+ }
+ case DiagnoseFile diagnoseFile:
+ {
+ 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;
+
+ foreach (var entry in directory.Children)
+ {
+ var files = await ProcessDiagnoseEntry(directoryPath, entry);
+
+ foreach (var file in files)
+ {
+ 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 bytes = file.GetContent();
+
+ return new KeyValuePair(filePath, bytes);
+ }
}
\ No newline at end of file
From bc25210fe41777b6a01c1de622840d89bd3f3ff3 Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Mon, 12 May 2025 19:36:27 +0200
Subject: [PATCH 04/14] added config to diagnose, while censoring sensitive
data
---
.../Diagnose/CoreDiagnoseProvider.cs | 54 +++++++++++++++++--
1 file changed, 51 insertions(+), 3 deletions(-)
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
index 92d5d09a..53028d59 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
@@ -1,4 +1,7 @@
using System.Text;
+using System.Text.Json;
+using MoonCore.Helpers;
+using Moonlight.ApiServer.Configuration;
using Moonlight.ApiServer.Interfaces;
using Moonlight.ApiServer.Models.Diagnose;
@@ -8,13 +11,58 @@ public class CoreDiagnoseProvider : IDiagnoseProvider
{
public DiagnoseEntry[] GetFiles()
{
+ // TODO:
+ // - read logs out from file for the diagnose below
+
return
[
- new DiagnoseFile()
+ new DiagnoseDirectory()
{
- Name = "test.txt",
- GetContent = () => Encoding.UTF8.GetBytes("hello world")
+ Name = "core",
+ Children = [
+
+ new DiagnoseFile()
+ {
+ Name = "logs.txt",
+ GetContent = () => Encoding.UTF8.GetBytes("placeholder")
+ },
+
+ new DiagnoseFile()
+ {
+ Name = "logs.txt",
+ GetContent = () =>
+ {
+
+ var configJson = File.ReadAllText(PathBuilder.File("storage", "app.json"));
+
+ var config = JsonSerializer.Deserialize(configJson);
+
+ if (config == null)
+ {
+ return Encoding.UTF8.GetBytes("could not fetch config");
+ }
+
+ config.Database.Password = CheckForNullOrEmpty(config.Database.Password);
+
+ config.Authentication.OAuth2.ClientSecret = CheckForNullOrEmpty(config.Authentication.OAuth2.ClientSecret);
+
+ config.Authentication.OAuth2.Secret = CheckForNullOrEmpty(config.Authentication.OAuth2.Secret);
+
+ config.Authentication.Secret = CheckForNullOrEmpty(config.Authentication.Secret);
+
+ return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(config));
+ }
+ }
+
+ ]
}
];
}
+
+ private string CheckForNullOrEmpty(string? content)
+ {
+ return string.IsNullOrEmpty(content)
+ ? "ISEMPTY"
+ : "ISNOTEMPTY";
+ }
}
\ No newline at end of file
From 753cb04dfe2f077900020e84995601615e93ad0c Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Tue, 13 May 2025 14:06:59 +0200
Subject: [PATCH 05/14] improved the config in the diagnose
---
.../Diagnose/CoreDiagnoseProvider.cs | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
index 53028d59..be89d2ee 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
@@ -9,6 +9,8 @@ namespace Moonlight.ApiServer.Implementations.Diagnose;
public class CoreDiagnoseProvider : IDiagnoseProvider
{
+ private readonly AppConfiguration Config;
+
public DiagnoseEntry[] GetFiles()
{
// TODO:
@@ -29,19 +31,17 @@ public class CoreDiagnoseProvider : IDiagnoseProvider
new DiagnoseFile()
{
- Name = "logs.txt",
+ Name = "config.txt",
GetContent = () =>
{
-
- var configJson = File.ReadAllText(PathBuilder.File("storage", "app.json"));
-
- var config = JsonSerializer.Deserialize(configJson);
+ var json = JsonSerializer.Serialize(Config);
+ var config = JsonSerializer.Deserialize(json);
if (config == null)
{
- return Encoding.UTF8.GetBytes("could not fetch config");
+ return Encoding.UTF8.GetBytes("Could not fetch config.");
}
-
+
config.Database.Password = CheckForNullOrEmpty(config.Database.Password);
config.Authentication.OAuth2.ClientSecret = CheckForNullOrEmpty(config.Authentication.OAuth2.ClientSecret);
@@ -50,7 +50,7 @@ public class CoreDiagnoseProvider : IDiagnoseProvider
config.Authentication.Secret = CheckForNullOrEmpty(config.Authentication.Secret);
- return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(config));
+ return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(config, new JsonSerializerOptions() { WriteIndented = true}));
}
}
From ba736d2b19b62fe5543120c7285e505c9e511e54 Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Tue, 13 May 2025 14:14:22 +0200
Subject: [PATCH 06/14] added file logging and log rotation
---
Moonlight.ApiServer/Startup.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Moonlight.ApiServer/Startup.cs b/Moonlight.ApiServer/Startup.cs
index baf2ee51..4e691bbb 100644
--- a/Moonlight.ApiServer/Startup.cs
+++ b/Moonlight.ApiServer/Startup.cs
@@ -123,6 +123,7 @@ public class Startup
private Task CreateStorage()
{
Directory.CreateDirectory("storage");
+ Directory.CreateDirectory(PathBuilder.Dir("storage", "logs"));
Directory.CreateDirectory(PathBuilder.Dir("storage", "plugins"));
return Task.CompletedTask;
@@ -426,7 +427,10 @@ public class Startup
{
configuration.Console.Enable = true;
configuration.Console.EnableAnsiMode = true;
- configuration.FileLogging.Enable = false;
+ configuration.FileLogging.Enable = true;
+ configuration.FileLogging.Path = PathBuilder.File("storage", "logs", "latest.log");
+ configuration.FileLogging.EnableLogRotation = true;
+ configuration.FileLogging.RotateLogNameTemplate = PathBuilder.File("storage", "logs", "apiserver.{0}.log");
});
LoggerFactory = new LoggerFactory();
From 49848db96f1385d2a80c188ce358830541533990 Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Tue, 13 May 2025 14:26:29 +0200
Subject: [PATCH 07/14] added logs to the diagnose
---
.../Diagnose/CoreDiagnoseProvider.cs | 20 ++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
index be89d2ee..aff19bfd 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreDiagnoseProvider.cs
@@ -10,12 +10,14 @@ namespace Moonlight.ApiServer.Implementations.Diagnose;
public class CoreDiagnoseProvider : IDiagnoseProvider
{
private readonly AppConfiguration Config;
-
+
+ public CoreDiagnoseProvider(AppConfiguration config)
+ {
+ Config = config;
+ }
+
public DiagnoseEntry[] GetFiles()
{
- // TODO:
- // - read logs out from file for the diagnose below
-
return
[
new DiagnoseDirectory()
@@ -26,7 +28,15 @@ public class CoreDiagnoseProvider : IDiagnoseProvider
new DiagnoseFile()
{
Name = "logs.txt",
- GetContent = () => Encoding.UTF8.GetBytes("placeholder")
+ GetContent = () =>
+ {
+ var logs = File.ReadAllText(PathBuilder.File("storage", "logs", "latest.log"));
+
+ if (string.IsNullOrEmpty(logs))
+ return Encoding.UTF8.GetBytes("Could not get the latest logs.");
+
+ return Encoding.UTF8.GetBytes(logs);
+ }
},
new DiagnoseFile()
From 0743bad93c96859f6a6873ce7b0f4485ddbb9c5a Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Tue, 13 May 2025 15:28:46 +0200
Subject: [PATCH 08/14] added ui for the diagnose system
---
.../UI/Views/Admin/Sys/Diagnose.razor | 46 +++++++++++++++++++
Moonlight.Client/UiConstants.cs | 4 +-
2 files changed, 48 insertions(+), 2 deletions(-)
create mode 100644 Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
diff --git a/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
new file mode 100644
index 00000000..079cf665
--- /dev/null
+++ b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
@@ -0,0 +1,46 @@
+@page "/admin/system/diagnose"
+
+@using MoonCore.Attributes
+@using MoonCore.Helpers
+
+@attribute [RequirePermission("admin.system.diagnose")]
+
+@inject HttpApiClient ApiClient
+@inject DownloadService DownloadService
+
+
+
+
+
+
+
+
+ Diagnose
+
+
+
+ If you're experiencing issues or need help via our Discord, you're in the right place here!
+ By pressing the button below, Moonlight will run all available diagnostic checks and package the results into a
+ downloadable zip file.
+ The report includes useful information about your system, plugins, and environment, making it easier to identify problems or share with support.
+
+
+ Generate diagnose
+
+
+
+
+@code
+{
+ private async Task GenerateFrontend(WButton _)
+ {
+ var stream = await ApiClient.GetStream("api/admin/system/diagnose");
+
+ await DownloadService.DownloadStream("diagnose.zip", stream);
+ }
+}
+
+
+@code {
+
+}
\ No newline at end of file
diff --git a/Moonlight.Client/UiConstants.cs b/Moonlight.Client/UiConstants.cs
index 9293cc7f..dce82611 100644
--- a/Moonlight.Client/UiConstants.cs
+++ b/Moonlight.Client/UiConstants.cs
@@ -4,12 +4,12 @@ public static class UiConstants
{
public static readonly string[] AdminNavNames =
[
- "Overview", "Theme", "Files", "Hangfire", "Advanced"
+ "Overview", "Theme", "Files", "Hangfire", "Advanced", "Diagnose"
];
public static readonly string[] AdminNavLinks =
[
"/admin/system", "/admin/system/theme", "/admin/system/files", "/admin/system/hangfire",
- "/admin/system/advanced"
+ "/admin/system/advanced", "/admin/system/diagnose"
];
}
\ No newline at end of file
From 609a0297d590785b1a5ecf002879e54ac38ae16f Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Tue, 13 May 2025 17:22:47 +0200
Subject: [PATCH 09/14] 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.
+
+ @foreach (var item in AvailableProviders)
+ {
+
+
+
+
+ }
+
+
+
@@ -59,19 +57,51 @@
private async Task GenerateDiagnose(WButton _)
{
- var stream = await ApiClient.PostStream("api/admin/system/diagnose");
+ string[] payload = [];
+
+ if (!SelectAll)
+ {
+ // filter the providers which have been selected if not all providers have been selected
+ payload = AvailableProviders
+ .Where(x => x.Value)
+ .Select(x => x.Key)
+ .Select(x => x.Type)
+ .ToArray();
+ }
+ var stream = await ApiClient.PostStream("api/admin/system/diagnose", payload);
+
await DownloadService.DownloadStream("diagnose.zip", stream);
}
-
- private async Task Load(LazyLoader arg)
+ private bool DropdownOpen = false;
+ private bool AllSelected = true;
+ private Dictionary AvailableProviders;
+
+ private async Task ToggleDropDown()
{
- // AvailableProviders = (await ApiClient.GetJson("api/admin/system/diagnose/available")).AvailableProviders;
+ DropdownOpen = !DropdownOpen;
+
+ await InvokeAsync(StateHasChanged);
}
+ private async Task Load(LazyLoader arg)
+ {
+ AvailableProviders = (await ApiClient.GetJson("api/admin/system/diagnose/available"))
+ .ToDictionary(x => x, _ => true);
+ }
-
-
-
+ private bool SelectAll
+ {
+ get => AvailableProviders.Values.All(v => v);
+ set
+ {
+ // flip every entry to the new value
+ var keys = AvailableProviders.Keys.ToList();
+ foreach (var k in keys)
+ {
+ AvailableProviders[k] = value;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/Moonlight.Shared/Http/Responses/Admin/Sys/DiagnoseProvideResponse.cs b/Moonlight.Shared/Http/Responses/Admin/Sys/DiagnoseProvideResponse.cs
new file mode 100644
index 00000000..e1882266
--- /dev/null
+++ b/Moonlight.Shared/Http/Responses/Admin/Sys/DiagnoseProvideResponse.cs
@@ -0,0 +1,8 @@
+namespace Moonlight.Shared.Http.Responses.Admin.Sys;
+
+public class DiagnoseProvideResponse
+{
+ public string Name { get; set; }
+
+ public string Type { get; set; }
+}
\ 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
deleted file mode 100644
index a32fe302..00000000
--- a/Moonlight.Shared/Http/Responses/Admin/Sys/SystemAvailableDiagnoseProviderResponse.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index dd552700..00000000
--- a/Moonlight.Shared/Misc/DiagnoseProvider.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Moonlight.Shared.Misc;
-
-public class DiagnoseProvider
-{
- public string Name { get; set; }
-
- public string Type { get; set; }
-}
\ No newline at end of file
From c49b0005215d21aad0aa11d771a972d9eb63e83a Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Wed, 14 May 2025 20:15:07 +0200
Subject: [PATCH 11/14] Used CamelCase Formatter in Diagnose ui
---
Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
index 8b84853b..aa35a00b 100644
--- a/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
+++ b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
@@ -42,7 +42,7 @@
{
-
+
}
From eab03d7f5af1b262453112cd90cf4bf122893a30 Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Thu, 15 May 2025 14:09:16 +0200
Subject: [PATCH 12/14] cleaned up diagnose feature
---
.../Http/Controllers/Admin/Sys/SystemController.cs | 6 ------
.../Diagnose/CoreConfigDiagnoseProvider.cs | 3 ---
Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs | 1 -
Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs | 7 -------
Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs | 8 --------
Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs | 8 --------
Moonlight.ApiServer/Services/DiagnoseService.cs | 4 ----
7 files changed, 37 deletions(-)
delete mode 100644 Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs
delete mode 100644 Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
delete mode 100644 Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs
diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
index b2ad01ae..e69efc8f 100644
--- a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
+++ b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/SystemController.cs
@@ -1,12 +1,6 @@
-using System.IO.Compression;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Logging.Console;
using MoonCore.Attributes;
-using MoonCore.Exceptions;
-using MoonCore.Helpers;
-using Moonlight.ApiServer.Helpers;
using Moonlight.ApiServer.Interfaces;
-using Moonlight.ApiServer.Models.Diagnose;
using Moonlight.ApiServer.Services;
using Moonlight.Shared.Http.Responses.Admin.Sys;
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
index b1c8d3f8..29275823 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
@@ -1,11 +1,8 @@
using System.IO.Compression;
-using System.Text;
using System.Text.Json;
-using MoonCore.Helpers;
using Moonlight.ApiServer.Configuration;
using Moonlight.ApiServer.Extensions;
using Moonlight.ApiServer.Interfaces;
-using Moonlight.ApiServer.Models.Diagnose;
namespace Moonlight.ApiServer.Implementations.Diagnose;
diff --git a/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs b/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
index daf6d875..5a4a9cf2 100644
--- a/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Interfaces/IDiagnoseProvider.cs
@@ -1,5 +1,4 @@
using System.IO.Compression;
-using Moonlight.ApiServer.Models.Diagnose;
namespace Moonlight.ApiServer.Interfaces;
diff --git a/Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs b/Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs
deleted file mode 100644
index 85bda05a..00000000
--- a/Moonlight.ApiServer/Models/Diagnose/DiagnoseDirectory.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Moonlight.ApiServer.Models.Diagnose;
-
-public class DiagnoseDirectory : DiagnoseEntry
-{
- public List Children { get; set; } = new();
- public override bool IsDirectory => true;
-}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs b/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
deleted file mode 100644
index f83d4670..00000000
--- a/Moonlight.ApiServer/Models/Diagnose/DiagnoseEntry.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Moonlight.ApiServer.Models.Diagnose;
-
-public abstract class DiagnoseEntry
-{
- public required string Name { get; set; } = "";
-
- public abstract bool IsDirectory { get; }
-}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs b/Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs
deleted file mode 100644
index dfeeb3aa..00000000
--- a/Moonlight.ApiServer/Models/Diagnose/DiagnoseFile.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Moonlight.ApiServer.Models.Diagnose;
-
-public class DiagnoseFile : DiagnoseEntry
-{
- public Func GetContent = () => [];
-
- public override bool IsDirectory => false;
-}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Services/DiagnoseService.cs b/Moonlight.ApiServer/Services/DiagnoseService.cs
index 635a3a1a..01a6b4ec 100644
--- a/Moonlight.ApiServer/Services/DiagnoseService.cs
+++ b/Moonlight.ApiServer/Services/DiagnoseService.cs
@@ -1,11 +1,7 @@
-using MoonCore.Helpers;
using Moonlight.ApiServer.Interfaces;
-using Moonlight.ApiServer.Models.Diagnose;
using System.IO.Compression;
-using System.Text;
using MoonCore.Attributes;
using Moonlight.Shared.Http.Responses.Admin.Sys;
-using Moonlight.Shared.Misc;
namespace Moonlight.ApiServer.Services;
From f87e4a08008af4f6a6dc434230ff0f8841403555 Mon Sep 17 00:00:00 2001
From: mxritzdev
Date: Thu, 15 May 2025 14:15:44 +0200
Subject: [PATCH 13/14] censored client id config diagnose
---
.../Implementations/Diagnose/CoreConfigDiagnoseProvider.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
index 29275823..e0b1480a 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
@@ -42,6 +42,8 @@ public class CoreConfigDiagnoseProvider : IDiagnoseProvider
config.Authentication.OAuth2.Secret = CheckForNullOrEmpty(config.Authentication.OAuth2.Secret);
config.Authentication.Secret = CheckForNullOrEmpty(config.Authentication.Secret);
+
+ config.Authentication.OAuth2.ClientId = CheckForNullOrEmpty(config.Authentication.OAuth2.ClientId);
await archive.AddText("core/config.txt",
JsonSerializer.Serialize(config, new JsonSerializerOptions() { WriteIndented = true }));
From 255bfba9e34d6d84ebd6abc00aaec76fb84303b8 Mon Sep 17 00:00:00 2001
From: ChiaraBm
Date: Sat, 17 May 2025 19:38:36 +0200
Subject: [PATCH 14/14] Cleaned up diagnose system. Fixed smaller
inconsistencies
---
.../Admin/Sys/DiagnoseController.cs | 22 ++--
.../Diagnose/CoreConfigDiagnoseProvider.cs | 26 ++--
.../Diagnose/LogsDiagnoseProvider.cs | 20 ++-
.../Services/DiagnoseService.cs | 75 ++++++-----
.../UI/Views/Admin/Sys/Diagnose.razor | 117 ++++++++++--------
.../Admin/Sys/GenerateDiagnoseRequest.cs | 6 +
.../Admin/Sys/DiagnoseProvideResponse.cs | 1 -
7 files changed, 153 insertions(+), 114 deletions(-)
create mode 100644 Moonlight.Shared/Http/Requests/Admin/Sys/GenerateDiagnoseRequest.cs
diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs
index c541d877..94ae9d51 100644
--- a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs
+++ b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/DiagnoseController.cs
@@ -10,6 +10,7 @@ namespace Moonlight.ApiServer.Http.Controllers.Admin.Sys;
[ApiController]
[Route("api/admin/system/diagnose")]
+[RequirePermission("admin.system.diagnose")]
public class DiagnoseController : Controller
{
private readonly DiagnoseService DiagnoseService;
@@ -20,20 +21,21 @@ public class DiagnoseController : Controller
}
[HttpPost]
- [RequirePermission("admin.system.diagnose")]
- public async Task Diagnose([FromBody] string[]? requestedDiagnoseProviders = null)
+ public async Task Diagnose([FromBody] GenerateDiagnoseRequest request)
{
- var stream = new MemoryStream();
+ var stream = await DiagnoseService.GenerateDiagnose(request.Providers);
- await DiagnoseService.GenerateDiagnose(stream, requestedDiagnoseProviders);
-
- return File(stream, "application/zip", "diagnose.zip");
+ await Results.Stream(
+ stream,
+ contentType: "application/zip",
+ fileDownloadName: "diagnose.zip"
+ )
+ .ExecuteAsync(HttpContext);
}
- [HttpGet("available")]
- [RequirePermission("admin.system.diagnose")]
- public async Task GetAvailable()
+ [HttpGet("providers")]
+ public async Task GetProviders()
{
- return await DiagnoseService.GetAvailable();
+ return await DiagnoseService.GetProviders();
}
}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
index e0b1480a..689148aa 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/CoreConfigDiagnoseProvider.cs
@@ -24,28 +24,34 @@ public class CoreConfigDiagnoseProvider : IDiagnoseProvider
public async Task ModifyZipArchive(ZipArchive archive)
{
-
var json = JsonSerializer.Serialize(Config);
- var config = JsonSerializer.Deserialize(json);
+ var config = JsonSerializer.Deserialize(json);
if (config == null)
{
- await archive.AddText("core/config.txt","Could not fetch config.");
-
+ await archive.AddText("core/config.txt", "Could not fetch config.");
return;
}
-
+
config.Database.Password = CheckForNullOrEmpty(config.Database.Password);
-
+
config.Authentication.OAuth2.ClientSecret = CheckForNullOrEmpty(config.Authentication.OAuth2.ClientSecret);
-
+
config.Authentication.OAuth2.Secret = CheckForNullOrEmpty(config.Authentication.OAuth2.Secret);
config.Authentication.Secret = CheckForNullOrEmpty(config.Authentication.Secret);
-
+
config.Authentication.OAuth2.ClientId = CheckForNullOrEmpty(config.Authentication.OAuth2.ClientId);
- await archive.AddText("core/config.txt",
- JsonSerializer.Serialize(config, new JsonSerializerOptions() { WriteIndented = true }));
+ await archive.AddText(
+ "core/config.txt",
+ JsonSerializer.Serialize(
+ config,
+ new JsonSerializerOptions()
+ {
+ WriteIndented = true
+ }
+ )
+ );
}
}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Implementations/Diagnose/LogsDiagnoseProvider.cs b/Moonlight.ApiServer/Implementations/Diagnose/LogsDiagnoseProvider.cs
index c731dd3b..0ef1e82b 100644
--- a/Moonlight.ApiServer/Implementations/Diagnose/LogsDiagnoseProvider.cs
+++ b/Moonlight.ApiServer/Implementations/Diagnose/LogsDiagnoseProvider.cs
@@ -1,6 +1,4 @@
using System.IO.Compression;
-using System.Text;
-using MoonCore.Helpers;
using Moonlight.ApiServer.Extensions;
using Moonlight.ApiServer.Interfaces;
@@ -10,15 +8,15 @@ public class LogsDiagnoseProvider : IDiagnoseProvider
{
public async Task ModifyZipArchive(ZipArchive archive)
{
+ var path = Path.Combine("storage", "logs", "latest.log");
- var logs = await File.ReadAllTextAsync(PathBuilder.File("storage", "logs", "latest.log"));
-
- if (string.IsNullOrEmpty(logs))
- {
- await archive.AddText("logs.txt", "Could not read the logs");
- return;
- }
-
- await archive.AddText("logs.txt", logs);
+ if (!File.Exists(path))
+ {
+ await archive.AddText("logs.txt", "Logs file latest.log has not been found");
+ return;
+ }
+
+ var logsContent = await File.ReadAllTextAsync(path);
+ await archive.AddText("logs.txt", logsContent);
}
}
\ No newline at end of file
diff --git a/Moonlight.ApiServer/Services/DiagnoseService.cs b/Moonlight.ApiServer/Services/DiagnoseService.cs
index 01a6b4ec..a5844b04 100644
--- a/Moonlight.ApiServer/Services/DiagnoseService.cs
+++ b/Moonlight.ApiServer/Services/DiagnoseService.cs
@@ -1,6 +1,7 @@
using Moonlight.ApiServer.Interfaces;
using System.IO.Compression;
using MoonCore.Attributes;
+using MoonCore.Exceptions;
using Moonlight.Shared.Http.Responses.Admin.Sys;
namespace Moonlight.ApiServer.Services;
@@ -9,13 +10,18 @@ namespace Moonlight.ApiServer.Services;
public class DiagnoseService
{
private readonly IEnumerable DiagnoseProviders;
+ private readonly ILogger Logger;
- public DiagnoseService(IEnumerable diagnoseProviders)
+ public DiagnoseService(
+ IEnumerable diagnoseProviders,
+ ILogger logger
+ )
{
DiagnoseProviders = diagnoseProviders;
+ Logger = logger;
}
- public async Task GetAvailable()
+ public Task GetProviders()
{
var availableProviders = new List();
@@ -26,55 +32,64 @@ public class DiagnoseService
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 DiagnoseProvideResponse()
- {
- Name = name,
- Type = type
- });
+ if (type == null)
+ continue;
+
+ availableProviders.Add(new DiagnoseProvideResponse()
+ {
+ Name = name,
+ Type = type
+ });
}
- return availableProviders.ToArray();
+ return Task.FromResult(
+ availableProviders.ToArray()
+ );
}
- public async Task GenerateDiagnose(Stream outputStream, string[]? requestedProviders)
+ public async Task GenerateDiagnose(string[] requestedProviders)
{
IDiagnoseProvider[] providers;
-
- if (requestedProviders != null && requestedProviders.Length > 0)
+
+ if (requestedProviders.Length == 0)
+ providers = DiagnoseProviders.ToArray();
+ else
{
- var requesteDiagnoseProviders = new List();
+ var foundProviders = new List();
foreach (var requestedProvider in requestedProviders)
{
var provider = DiagnoseProviders.FirstOrDefault(x => x.GetType().FullName == requestedProvider);
- if (provider != null)
- requesteDiagnoseProviders.Add(provider);
+ if (provider == null)
+ continue;
+
+ foundProviders.Add(provider);
}
- providers = requesteDiagnoseProviders.ToArray();
- }
- else
- {
- providers = DiagnoseProviders.ToArray();
+ providers = foundProviders.ToArray();
}
try
{
- using (var zip = new ZipArchive(outputStream, ZipArchiveMode.Create, leaveOpen: true))
- {
- foreach (var provider in providers)
- {
- await provider.ModifyZipArchive(zip);
- }
- }
+ var outputStream = new MemoryStream();
+ var zipArchive = new ZipArchive(outputStream, ZipArchiveMode.Create, leaveOpen: true);
- outputStream.Seek(0, SeekOrigin.Begin);
+ foreach (var provider in providers)
+ {
+ await provider.ModifyZipArchive(zipArchive);
+ }
+
+ zipArchive.Dispose();
+
+ outputStream.Position = 0;
+ return outputStream;
}
- catch (Exception ex)
+ catch (Exception e)
{
- throw new Exception($"An unknown error occured while building the Diagnose: {ex.Message}");
+ Logger.LogError("An unhandled error occured while generated the diagnose file: {e}", e);
+
+ throw new HttpApiException("An unhandled error occured while generating the diagnose file", 500);
}
}
}
\ No newline at end of file
diff --git a/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
index aa35a00b..0a544f41 100644
--- a/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
+++ b/Moonlight.Client/UI/Views/Admin/Sys/Diagnose.razor
@@ -2,8 +2,8 @@
@using MoonCore.Attributes
@using MoonCore.Helpers
+@using Moonlight.Shared.Http.Requests.Admin.Sys
@using Moonlight.Shared.Http.Responses.Admin.Sys
-@using Moonlight.Shared.Misc
@attribute [RequirePermission("admin.system.diagnose")]
@@ -11,7 +11,7 @@
@inject DownloadService DownloadService
-
+
@@ -22,27 +22,43 @@
If you're experiencing issues or need help via our Discord, you're in the right place here!
- By pressing the button below, Moonlight will run all available diagnostic checks and package the results into a
+ By pressing the button below, Moonlight will run all available diagnostic checks and package the results
+ into a
downloadable zip file.
- The report includes useful information about your system, plugins, and environment, making it easier to identify problems or share with support.
+ The report includes useful information about your system, plugins, and environment, making it easier to
+ identify problems or share with support.