Added small system overview

This commit is contained in:
2025-12-25 21:55:46 +01:00
parent a2d4edc0e5
commit ca69d410f2
9 changed files with 422 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
using System.Runtime.InteropServices;
namespace Moonlight.Api.Helpers;
public class OsHelper
{
public static string GetName()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return GetWindowsVersion();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
return GetLinuxVersion();
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
return "Goofy OS";
return "Unknown OS";
}
private static string GetWindowsVersion()
{
var version = Environment.OSVersion.Version;
// Windows 11 is version 10.0 build 22000+
if (version.Major == 10 && version.Build >= 22000)
return $"Windows 11 ({version.Build})";
if (version.Major == 10)
return $"Windows 10 ({version.Build})";
if (version.Major == 6 && version.Minor == 3)
return "Windows 8.1";
if (version.Major == 6 && version.Minor == 2)
return "Windows 8";
if (version.Major == 6 && version.Minor == 1)
return "Windows 7";
return $"Windows {version.Major}.{version.Minor}";
}
private static string GetLinuxVersion()
{
try
{
// Read /etc/os-release, should work everywhere
if (File.Exists("/etc/os-release"))
{
var lines = File.ReadAllLines("/etc/os-release");
string? name = null;
string? version = null;
foreach (var line in lines)
{
if (line.StartsWith("NAME="))
name = line.Substring(5).Trim('"');
else if (line.StartsWith("VERSION_ID="))
version = line.Substring(11).Trim('"');
}
if (!string.IsNullOrEmpty(name))
{
return string.IsNullOrEmpty(version) ? name : $"{name} {version}";
}
}
//If for some weird reason it still uses lsb release
if (File.Exists("/etc/lsb-release"))
{
var lines = File.ReadAllLines("/etc/lsb-release");
string? name = null;
string? version = null;
foreach (var line in lines)
{
if (line.StartsWith("DISTRIB_ID="))
name = line.Substring(11);
else if (line.StartsWith("DISTRIB_RELEASE="))
version = line.Substring(16);
}
if (!string.IsNullOrEmpty(name))
{
return string.IsNullOrEmpty(version) ? name : $"{name} {version}";
}
}
}
catch
{
// Ignore
}
// Fallback
return $"Linux {Environment.OSVersion.Version}";
}
}

View File

@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
using Moonlight.Api.Services;
using Moonlight.Shared.Http.Responses.Admin;
namespace Moonlight.Api.Http.Controllers.Admin;
[ApiController]
[Route("api/admin/system")]
public class SystemController : Controller
{
private readonly ApplicationService ApplicationService;
public SystemController(ApplicationService applicationService)
{
ApplicationService = applicationService;
}
[HttpGet("info")]
public async Task<ActionResult<SystemInfoResponse>> GetInfoAsync()
{
var cpuUsage = await ApplicationService.GetCpuUsageAsync();
var memoryUsage = await ApplicationService.GetMemoryUsageAsync();
return new SystemInfoResponse(
cpuUsage,
memoryUsage,
ApplicationService.OperatingSystem,
DateTimeOffset.UtcNow - ApplicationService.StartedAt,
ApplicationService.VersionName,
ApplicationService.IsUpToDate
);
}
}

View File

@@ -0,0 +1,64 @@
using System.Diagnostics;
using Microsoft.Extensions.Hosting;
using Moonlight.Api.Helpers;
namespace Moonlight.Api.Services;
public class ApplicationService : IHostedLifecycleService
{
public DateTimeOffset StartedAt { get; private set; }
public string VersionName { get; private set; } = "N/A";
public bool IsUpToDate { get; set; } = true;
public string OperatingSystem { get; private set; } = "N/A";
public Task<long> GetMemoryUsageAsync()
{
using var currentProcess = Process.GetCurrentProcess();
return Task.FromResult(currentProcess.WorkingSet64);
}
public async Task<double> GetCpuUsageAsync()
{
using var currentProcess = Process.GetCurrentProcess();
// Get initial values
var startCpuTime = currentProcess.TotalProcessorTime;
var startTime = DateTime.UtcNow;
// Wait a bit to calculate the diff
await Task.Delay(500);
// New values
var endCpuTime = currentProcess.TotalProcessorTime;
var endTime = DateTime.UtcNow;
// Calculate CPU usage
var cpuUsedMs = (endCpuTime - startCpuTime).TotalMilliseconds;
var totalMsPassed = (endTime - startTime).TotalMilliseconds;
var cpuUsagePercent = (cpuUsedMs / (Environment.ProcessorCount * totalMsPassed)) * 100;
return Math.Round(cpuUsagePercent, 2);
}
public async Task StartedAsync(CancellationToken cancellationToken)
{
StartedAt = DateTimeOffset.UtcNow;
// TODO: Update / version check
VersionName = "v2.1.0 (a2d4edc0e5)";
IsUpToDate = true;
OperatingSystem = OsHelper.GetName();
}
#region Unused
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StartingAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StoppedAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StoppingAsync(CancellationToken cancellationToken) => Task.CompletedTask;
#endregion
}

View File

@@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Moonlight.Shared.Http;
using Moonlight.Api.Helpers;
using Moonlight.Api.Services;
namespace Moonlight.Api.Startup;
@@ -19,6 +20,9 @@ public partial class Startup
builder.Logging.ClearProviders();
builder.Logging.AddConsole(options => { options.FormatterName = nameof(AppConsoleFormatter); });
builder.Logging.AddConsoleFormatter<AppConsoleFormatter, ConsoleFormatterOptions>();
builder.Services.AddSingleton<ApplicationService>();
builder.Services.AddHostedService(sp => sp.GetRequiredService<ApplicationService>());
}
private static void UseBase(WebApplication application)