3d47fc1439
- Created ResourceHub.cs for SignalR group management. - Developed a modern web dashboard using Tailwind CSS for responsive design. - Implemented real-time updates with SignalR for CPU, Memory, GPU, and Network usage. - Added REST API endpoints for resource information and process management. - Integrated process management features to view and terminate high-usage processes. - Enhanced UI with loading spinners, notifications, and responsive tables. - Included performance charts for historical CPU and Memory usage. - Configured Swagger UI for API documentation. - Established security features including process kill restrictions and API key authentication.
138 lines
5.8 KiB
C#
138 lines
5.8 KiB
C#
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using ResourceMonitorService.Configuration;
|
|
using ResourceMonitorService.Services;
|
|
using ResourceMonitorService.Hubs;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace ResourceMonitorService
|
|
{
|
|
public class Worker : BackgroundService
|
|
{
|
|
private readonly ILogger<Worker> _logger;
|
|
private readonly IResourceMonitorService _resourceMonitorService;
|
|
private readonly IGameDetectionService _gameDetectionService;
|
|
private readonly IAlertService _alertService;
|
|
private readonly MonitoringSettings _monitoringSettings;
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
|
public Worker(
|
|
ILogger<Worker> logger,
|
|
IResourceMonitorService resourceMonitorService,
|
|
IGameDetectionService gameDetectionService,
|
|
IAlertService alertService,
|
|
IOptions<MonitoringSettings> monitoringSettings,
|
|
IServiceProvider serviceProvider)
|
|
{
|
|
_logger = logger;
|
|
_resourceMonitorService = resourceMonitorService;
|
|
_gameDetectionService = gameDetectionService;
|
|
_alertService = alertService;
|
|
_monitoringSettings = monitoringSettings.Value;
|
|
_serviceProvider = serviceProvider;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
_logger.LogInformation("Resource Monitor background service starting...");
|
|
await BackgroundMonitoringLoop(stoppingToken);
|
|
}
|
|
|
|
private async Task BackgroundMonitoringLoop(CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogInformation("Background monitoring started");
|
|
int errorCount = 0;
|
|
int successfulCycles = 0;
|
|
|
|
while (!cancellationToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
// Get current resource usage
|
|
var resourceUsage = await _resourceMonitorService.GetResourceUsageAsync();
|
|
|
|
// Add current game info if game detection is enabled
|
|
if (_monitoringSettings.EnableGameDetection)
|
|
{
|
|
try
|
|
{
|
|
resourceUsage.RunningGame = await _gameDetectionService.GetCurrentlyRunningGameAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Only log game detection errors occasionally to avoid spam
|
|
if (errorCount % 12 == 0) // Every minute if 5-second intervals
|
|
{
|
|
_logger.LogDebug("Game detection error (suppressed): {Message}", ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for alerts
|
|
if (_monitoringSettings.EnableAlerts)
|
|
{
|
|
await _alertService.CheckAndGenerateAlertsAsync(resourceUsage);
|
|
}
|
|
|
|
// Send real-time updates via SignalR
|
|
try
|
|
{
|
|
using var scope = _serviceProvider.CreateScope();
|
|
var hubContext = scope.ServiceProvider.GetService<IHubContext<ResourceHub>>();
|
|
if (hubContext != null)
|
|
{
|
|
await hubContext.Clients.All.SendAsync("ResourceUpdate", resourceUsage, cancellationToken);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogDebug("SignalR broadcast error: {Message}", ex.Message);
|
|
}
|
|
|
|
successfulCycles++;
|
|
|
|
// Log performance metrics occasionally
|
|
if (successfulCycles % 4 == 0) // Every 60 seconds with 15-second intervals
|
|
{
|
|
_logger.LogDebug("Performance: CPU: {CpuUsage:F1}%, Memory: {MemoryUsage:F1}%, GPU: {GpuUsage}%",
|
|
resourceUsage.CPU.Usage,
|
|
resourceUsage.Memory.UsagePercentage,
|
|
resourceUsage.GPU.Usage);
|
|
}
|
|
|
|
// Log successful monitoring occasionally for health verification
|
|
if (successfulCycles % 120 == 0) // Every 10 minutes
|
|
{
|
|
_logger.LogInformation("Background monitoring healthy - completed {SuccessfulCycles} cycles", successfulCycles);
|
|
}
|
|
|
|
errorCount = 0; // Reset error count on success
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorCount++;
|
|
|
|
// Only log errors occasionally to avoid spam, but always log the first few
|
|
if (errorCount <= 3 || errorCount % 12 == 0)
|
|
{
|
|
_logger.LogError(ex, "Error in background monitoring loop (occurrence #{ErrorCount})", errorCount);
|
|
}
|
|
|
|
// If too many consecutive errors, increase delay
|
|
if (errorCount > 10)
|
|
{
|
|
await Task.Delay(_monitoringSettings.UpdateIntervalMs * 2, cancellationToken);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
await Task.Delay(_monitoringSettings.UpdateIntervalMs, cancellationToken);
|
|
}
|
|
|
|
_logger.LogInformation("Background monitoring stopped after {SuccessfulCycles} successful cycles", successfulCycles);
|
|
}
|
|
}
|
|
}
|