add SystemInfoService, increase API to 3

This commit is contained in:
Stanley Dimant
2022-07-06 11:37:06 +02:00
parent 64f6380294
commit f307c9c486
7 changed files with 184 additions and 20 deletions

View File

@@ -8,7 +8,7 @@ namespace MareSynchronos.API
{ {
public class API public class API
{ {
public const int Version = 2; public const int Version = 3;
} }
public class FilesHubAPI public class FilesHubAPI
@@ -28,6 +28,8 @@ namespace MareSynchronos.API
{ {
public const string Path = "/heartbeat"; public const string Path = "/heartbeat";
public const string InvokeHeartbeat = "Heartbeat"; public const string InvokeHeartbeat = "Heartbeat";
public const string InvokeGetSystemInfo = "GetSystemInfo";
public const string OnUpdateSystemInfo = "OnUpdateSystemInfo";
} }
public class AdminHubAPI public class AdminHubAPI
@@ -64,7 +66,6 @@ namespace MareSynchronos.API
public const string InvokeGetPairedClients = "GetPairedClients"; public const string InvokeGetPairedClients = "GetPairedClients";
public const string SendDeleteAccount = "DeleteAccount"; public const string SendDeleteAccount = "DeleteAccount";
public const string OnUsersOnline = "UsersOnline";
public const string OnUpdateClientPairs = "UpdateClientPairs"; public const string OnUpdateClientPairs = "UpdateClientPairs";
public const string OnReceiveCharacterData = "ReceiveCharacterData"; public const string OnReceiveCharacterData = "ReceiveCharacterData";
public const string OnRemoveOnlinePairedPlayer = "RemoveOnlinePairedPlayer"; public const string OnRemoveOnlinePairedPlayer = "RemoveOnlinePairedPlayer";

View File

@@ -8,6 +8,5 @@ namespace MareSynchronos.API
public string GlamourerData { get; set; } public string GlamourerData { get; set; }
public string ManipulationData { get; set; } public string ManipulationData { get; set; }
public string Hash { get; set; } public string Hash { get; set; }
public int JobId { get; set; }
} }
} }

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MareSynchronos.API
{
public record SystemInfoDto
{
public double CpuUsage { get; set; }
public long CacheUsage { get; set; }
public int UploadedFiles { get; set; }
public double NetworkIn { get; set; }
public double NetworkOut { get; set; }
public int OnlineUsers { get; set; }
public long RAMUsage { get; set; }
}
}

View File

@@ -1,6 +1,8 @@
using System.Linq; using System;
using System.Linq;
using System.Runtime.ConstrainedExecution; using System.Runtime.ConstrainedExecution;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks; using System.Threading.Tasks;
using MareSynchronos.API; using MareSynchronos.API;
using MareSynchronosServer.Data; using MareSynchronosServer.Data;
@@ -12,15 +14,19 @@ namespace MareSynchronosServer.Hubs
{ {
public class ConnectionHub : BaseHub<ConnectionHub> public class ConnectionHub : BaseHub<ConnectionHub>
{ {
public ConnectionHub(MareDbContext mareDbContext, ILogger<ConnectionHub> logger) : base(mareDbContext, logger) private readonly SystemInfoService _systemInfoService;
public ConnectionHub(MareDbContext mareDbContext, ILogger<ConnectionHub> logger, SystemInfoService systemInfoService) : base(mareDbContext, logger)
{ {
_systemInfoService = systemInfoService;
} }
[HubMethodName(ConnectionHubAPI.InvokeHeartbeat)] [HubMethodName(ConnectionHubAPI.InvokeHeartbeat)]
public async Task<ConnectionDto> Heartbeat() public async Task<ConnectionDto> Heartbeat()
{ {
var userId = Context.User!.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; var userId = Context.User!.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
await Clients.Caller.SendAsync(ConnectionHubAPI.OnUpdateSystemInfo, _systemInfoService.SystemInfoDto);
if (userId != null) if (userId != null)
{ {
@@ -37,5 +43,11 @@ namespace MareSynchronosServer.Hubs
return new ConnectionDto(); return new ConnectionDto();
} }
[HubMethodName(ConnectionHubAPI.InvokeGetSystemInfo)]
public async Task<SystemInfoDto> GetSystemInfo()
{
return _systemInfoService.SystemInfoDto;
}
} }
} }

View File

@@ -65,8 +65,6 @@ namespace MareSynchronosServer.Hubs
.Where(u => otherUsers.Any(e => e == u.User) && u.OtherUser == ownUser && !u.IsPaused).ToListAsync(); .Where(u => otherUsers.Any(e => e == u.User) && u.OtherUser == ownUser && !u.IsPaused).ToListAsync();
await Clients.Users(otherEntries.Select(e => e.User.UID)).SendAsync(UserHubAPI.OnAddOnlinePairedPlayer, ownUser.CharacterIdentification); await Clients.Users(otherEntries.Select(e => e.User.UID)).SendAsync(UserHubAPI.OnAddOnlinePairedPlayer, ownUser.CharacterIdentification);
await Clients.All.SendAsync(UserHubAPI.OnUsersOnline,
await DbContext.Users.CountAsync(u => !string.IsNullOrEmpty(u.CharacterIdentification)));
return otherEntries.Select(e => e.User.CharacterIdentification).Distinct().ToList(); return otherEntries.Select(e => e.User.CharacterIdentification).Distinct().ToList();
} }
@@ -82,22 +80,22 @@ namespace MareSynchronosServer.Hubs
{ {
string userid = AuthenticatedUserId; string userid = AuthenticatedUserId;
var user = GetAuthenticatedUser(); var user = GetAuthenticatedUser();
return DbContext.ClientPairs var pairs = await DbContext.ClientPairs
.Include(u => u.OtherUser) .Include(u => u.OtherUser)
.Include(u => u.User) .Include(u => u.User)
.Where(w => w.User.UID == userid) .Where(w => w.User.UID == userid)
.ToList() .ToListAsync();
.Select(w => return pairs.Select(w =>
{
var otherEntry = OppositeEntry(w.OtherUser.UID);
return new ClientPairDto
{ {
var otherEntry = OppositeEntry(w.OtherUser.UID); IsPaused = w.IsPaused,
return new ClientPairDto OtherUID = w.OtherUser.UID,
{ IsSynced = otherEntry != null,
IsPaused = w.IsPaused, IsPausedFromOthers = otherEntry?.IsPaused ?? false,
OtherUID = w.OtherUser.UID, };
IsSynced = otherEntry != null, }).ToList();
IsPausedFromOthers = otherEntry?.IsPaused ?? false,
};
}).ToList();
} }
public override async Task OnDisconnectedAsync(Exception exception) public override async Task OnDisconnectedAsync(Exception exception)

View File

@@ -38,6 +38,7 @@ namespace MareSynchronosServer
hubOptions.StreamBufferCapacity = 200; hubOptions.StreamBufferCapacity = 200;
}); });
services.AddSingleton<SystemInfoService, SystemInfoService>();
services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>(); services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>();
services.AddDbContext<MareDbContext>(options => services.AddDbContext<MareDbContext>(options =>
@@ -46,6 +47,7 @@ namespace MareSynchronosServer
}); });
services.AddHostedService<FileCleanupService>(); services.AddHostedService<FileCleanupService>();
services.AddHostedService(provider => provider.GetService<SystemInfoService>());
services.AddDatabaseDeveloperPageExceptionFilter(); services.AddDatabaseDeveloperPageExceptionFilter();
services.AddAuthentication(options => services.AddAuthentication(options =>

View File

@@ -0,0 +1,133 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using MareSynchronos.API;
using MareSynchronosServer.Data;
using MareSynchronosServer.Hubs;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace MareSynchronosServer;
public class SystemInfoService : IHostedService, IDisposable
{
private readonly ILogger<SystemInfoService> _logger;
private readonly IServiceProvider _services;
private readonly IConfiguration _configuration;
private readonly IHubContext<ConnectionHub> _hubContext;
private Timer _timer;
public SystemInfoDto SystemInfoDto { get; private set; } = new();
public SystemInfoService(ILogger<SystemInfoService> logger, IServiceProvider services,
IConfiguration configuration, IHubContext<ConnectionHub> hubContext)
{
_logger = logger;
_services = services;
_configuration = configuration;
_hubContext = hubContext;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("System Info Service started");
_timer = new Timer(CalculateCpuUsage, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
private void CalculateCpuUsage(object state)
{
var startTime = DateTime.UtcNow;
double startCpuUsage = 0;
foreach (var process in Process.GetProcesses())
{
try
{
startCpuUsage += process.TotalProcessorTime.TotalMilliseconds;
}
catch { }
}
var networkOut = NetworkInterface.GetAllNetworkInterfaces().Sum(n => n.GetIPStatistics().BytesSent);
var networkIn = NetworkInterface.GetAllNetworkInterfaces().Sum(n => n.GetIPStatistics().BytesReceived);
var stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(TimeSpan.FromSeconds(5));
stopWatch.Stop();
var endTime = DateTime.UtcNow;
double endCpuUsage = 0;
long ramUsage = 0;
foreach (var process in Process.GetProcesses())
{
try
{
endCpuUsage += process.TotalProcessorTime.TotalMilliseconds;
ramUsage += process.WorkingSet64;
}
catch { }
}
var endNetworkOut = NetworkInterface.GetAllNetworkInterfaces().Sum(n => n.GetIPStatistics().BytesSent);
var endNetworkIn = NetworkInterface.GetAllNetworkInterfaces().Sum(n => n.GetIPStatistics().BytesReceived);
var totalMsPassed = (endTime - startTime).TotalMilliseconds;
var totalSPassed = (endTime - startTime).TotalSeconds;
var cpuUsedMs = (endCpuUsage - startCpuUsage);
var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed);
var bytesSent = endNetworkOut - networkOut;
var bytesReceived = endNetworkIn - networkIn;
using var scope = _services.CreateScope();
var dbContext = scope.ServiceProvider.GetService<MareDbContext>()!;
int uploadedFiles = 0;
var loggedInUsers = dbContext.Users.Count(u => !string.IsNullOrEmpty(u.CharacterIdentification));
var localCacheSize = Directory.EnumerateFiles(_configuration["CacheDirectory"])
.Sum(f =>
{
uploadedFiles++;
return new FileInfo(f).Length;
});
var totalNetworkOut = bytesSent / totalSPassed;
var totalNetworkIn = bytesReceived / totalSPassed;
var cpuUsage = cpuUsageTotal * 100;
var usedRAM = Process.GetCurrentProcess().WorkingSet64 + Process.GetProcessesByName("sqlservr").FirstOrDefault()?.WorkingSet64 ?? 0;
SystemInfoDto = new SystemInfoDto()
{
CacheUsage = localCacheSize,
CpuUsage = cpuUsage,
RAMUsage = usedRAM,
NetworkIn = totalNetworkIn,
NetworkOut = totalNetworkOut,
OnlineUsers = loggedInUsers,
UploadedFiles = uploadedFiles
};
_hubContext.Clients.All.SendAsync(ConnectionHubAPI.OnUpdateSystemInfo, SystemInfoDto);
_logger.LogInformation($"CPU:{cpuUsage:0.00}%, RAM Used:{(double)usedRAM / 1024 / 1024 / 1024:0.00}GB, Cache:{(double)localCacheSize / 1024 / 1024 / 1024:0.00}GB, Users:{loggedInUsers}, NetworkIn:{totalNetworkIn / 1024 / 1024:0.00}MB/s, NetworkOut:{totalNetworkOut / 1024 / 1024:0.00}MB/s");
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}