diff --git a/MoonlightServers.Daemon/App/Configuration/AppConfiguration.cs b/MoonlightServers.Daemon/App/Configuration/AppConfiguration.cs new file mode 100644 index 0000000..8e51b53 --- /dev/null +++ b/MoonlightServers.Daemon/App/Configuration/AppConfiguration.cs @@ -0,0 +1,6 @@ +namespace MoonlightServers.Daemon.App.Configuration; + +public class AppConfiguration +{ + +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/App/Helpers/HostHelper.cs b/MoonlightServers.Daemon/App/Helpers/HostHelper.cs new file mode 100644 index 0000000..707b0d7 --- /dev/null +++ b/MoonlightServers.Daemon/App/Helpers/HostHelper.cs @@ -0,0 +1,109 @@ +using System.Globalization; +using Mono.Unix.Native; +using MoonCore.Attributes; + +namespace MoonlightServers.Daemon.App.Helpers; + +[Singleton] +public class HostHelper +{ + public async Task GetCpuModel() + { + var lines = await File.ReadAllLinesAsync("/proc/cpuinfo"); + + foreach (var line in lines) + { + if (line.StartsWith("model name")) + return line.Split(":")[1].Trim(); + } + + return "Unknown processor"; + } + + public async Task GetCpuUsage() + { + var linesBefore = await File.ReadAllLinesAsync("/proc/stat"); + await Task.Delay(1000); // Wait for 1 second + var linesAfter = await File.ReadAllLinesAsync("/proc/stat"); + + var cpuDataBefore = linesBefore + .Where(line => line.StartsWith("cpu")) + .Select(line => line.Split([" "], StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(long.Parse) + .ToArray()) + .ToList(); + + var cpuDataAfter = linesAfter + .Where(line => line.StartsWith("cpu")) + .Select(line => line.Split([" "], StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(long.Parse) + .ToArray()) + .ToList(); + + var numCores = Environment.ProcessorCount; + var cpuUsagePerCore = new double[numCores]; + + for (var i = 0; i < numCores; i++) + { + var beforeIdle = cpuDataBefore[i][3]; + var beforeTotal = cpuDataBefore[i].Sum(); + var afterIdle = cpuDataAfter[i][3]; + var afterTotal = cpuDataAfter[i].Sum(); + + double idleDelta = afterIdle - beforeIdle; + double totalDelta = afterTotal - beforeTotal; + + var usage = 100.0 * (1.0 - idleDelta / totalDelta); + cpuUsagePerCore[i] = usage; + } + + return cpuUsagePerCore; + } + + public async Task GetUptime() + { + var uptimeText = await File.ReadAllTextAsync("/proc/uptime"); + var values = uptimeText.Split(" "); + var seconds = double.Parse(values[0], CultureInfo.InvariantCulture); + + return TimeSpan.FromSeconds(seconds); + } + + public async Task GetMemoryDetails() + { + var result = new long[6]; + + var memInfoText = await File.ReadAllLinesAsync("/proc/meminfo"); + + foreach (var line in memInfoText) + { + if (line.StartsWith("MemTotal:")) + result[0] = 1024 * long.Parse(line.Replace("MemTotal:", "").Replace("kB", "").Trim()); + + if (line.StartsWith("MemFree:")) + result[1] = 1024 * long.Parse(line.Replace("MemFree:", "").Replace("kB", "").Trim()); + + if (line.StartsWith("MemAvailable:")) + result[2] = 1024 * long.Parse(line.Replace("MemAvailable:", "").Replace("kB", "").Trim()); + + if (line.StartsWith("Cached:")) + result[3] = 1024 * long.Parse(line.Replace("Cached:", "").Replace("kB", "").Trim()); + + if (line.StartsWith("SwapTotal:")) + result[4] = 1024 * long.Parse(line.Replace("SwapTotal:", "").Replace("kB", "").Trim()); + + if (line.StartsWith("SwapFree:")) + result[5] = 1024 * long.Parse(line.Replace("SwapFree:", "").Replace("kB", "").Trim()); + } + + return result; + } + + public async Task GetDiskUsage() // 0, Total size - 1, Free size, - 3, Total inodes - 4, free inodes + { + var sysCallRes = Syscall.statvfs("/", out var buf); + + if (sysCallRes == -1) + return [0, 0, 0, 0]; + + return [buf.f_blocks * buf.f_frsize, buf.f_bfree * buf.f_frsize, buf.f_files, buf.f_ffree]; + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj b/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj index aa8cb8a..b8b1ba9 100644 --- a/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj +++ b/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj @@ -8,6 +8,8 @@ + + @@ -15,4 +17,14 @@ + + + + + + + + + + diff --git a/MoonlightServers.Daemon/Program.cs b/MoonlightServers.Daemon/Program.cs index 161f695..9818199 100644 --- a/MoonlightServers.Daemon/Program.cs +++ b/MoonlightServers.Daemon/Program.cs @@ -1,44 +1,42 @@ +using MoonCore.Extensions; +using MoonCore.Helpers; +using MoonlightServers.Daemon.App.Helpers; + +var loggerFactory = new LoggerFactory(); + +var loggerProviders = LoggerBuildHelper.BuildFromConfiguration(configuration => +{ + configuration.Console.Enable = true; + configuration.Console.EnableAnsiMode = true; + + configuration.FileLogging.Enable = false; +}); + +loggerFactory.AddProviders(loggerProviders); + +var logger = loggerFactory.CreateLogger("Startup"); + +logger.LogInformation("Starting MoonlightServers Daemon v2.1 Galaxy"); //TODO: Versions + var builder = WebApplication.CreateBuilder(args); -// Add services to the container. -// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); +builder.Logging.ClearProviders(); +builder.Logging.AddProviders(loggerProviders); + +builder.Services.AutoAddServices(); + +builder.Services.AddHttpContextAccessor(); +builder.Services.AddControllers(); var app = builder.Build(); -// Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) -{ - app.UseSwagger(); - app.UseSwaggerUI(); -} +var x = new HostHelper(); -app.UseHttpsRedirection(); +var data = await x.GetDiskUsage(); -var summaries = new[] -{ - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" -}; +logger.LogInformation("Total disk: {value}", Formatter.FormatSize((long)data[0])); +logger.LogInformation("Free disk: {value}", Formatter.FormatSize((long)data[1])); +logger.LogInformation("Total inodes: {value}", data[2]); +logger.LogInformation("Free inodes: {value}", data[3]); -app.MapGet("/weatherforecast", () => - { - var forecast = Enumerable.Range(1, 5).Select(index => - new WeatherForecast - ( - DateOnly.FromDateTime(DateTime.Now.AddDays(index)), - Random.Shared.Next(-20, 55), - summaries[Random.Shared.Next(summaries.Length)] - )) - .ToArray(); - return forecast; - }) - .WithName("GetWeatherForecast") - .WithOpenApi(); - -app.Run(); - -record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) -{ - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); -} \ No newline at end of file +app.Run(); \ No newline at end of file diff --git a/MoonlightServers.Daemon/Properties/launchSettings.json b/MoonlightServers.Daemon/Properties/launchSettings.json index ed6eabe..e346f1a 100644 --- a/MoonlightServers.Daemon/Properties/launchSettings.json +++ b/MoonlightServers.Daemon/Properties/launchSettings.json @@ -3,7 +3,7 @@ "http": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": true, + "launchBrowser": false, "launchUrl": "swagger", "applicationUrl": "http://localhost:5167", "environmentVariables": { diff --git a/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj b/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj index 3a63532..d83c965 100644 --- a/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj +++ b/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj @@ -6,4 +6,10 @@ enable + + + + + +