2025-07-02 16:06:50 +03:00
|
|
|
// File: Services/ProcessMonitor.cs
|
|
|
|
|
2025-06-30 18:15:07 +03:00
|
|
|
using Microsoft.Extensions.Options;
|
2025-07-02 16:06:50 +03:00
|
|
|
using System.Runtime.Versioning;
|
2025-06-30 18:15:07 +03:00
|
|
|
using WebmrAPI.Configuration;
|
2025-07-03 15:22:40 +03:00
|
|
|
using WebmrAPI.Exceptions;
|
2025-06-30 18:15:07 +03:00
|
|
|
using WebmrAPI.Models;
|
2025-07-03 15:22:40 +03:00
|
|
|
using WebmrAPI.Services.Scanners;
|
|
|
|
using WebmrAPI.Utils;
|
2025-06-30 18:15:07 +03:00
|
|
|
|
|
|
|
namespace WebmrAPI.Services
|
|
|
|
{
|
2025-07-02 16:06:50 +03:00
|
|
|
[SupportedOSPlatform("windows")]
|
2025-07-03 20:01:19 +03:00
|
|
|
public class ProcessMonitor : BackgroundService
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
|
|
|
private readonly ILogger<ProcessMonitor> _logger;
|
2025-07-03 15:22:40 +03:00
|
|
|
private readonly MonitoringSettings _config;
|
|
|
|
private LazyConcurrentContainer<ProcessInfo> _processes = new();
|
|
|
|
private ScanProvider _provider;
|
2025-06-30 18:15:07 +03:00
|
|
|
|
2025-07-03 15:22:40 +03:00
|
|
|
public ILogger<ProcessMonitor> Logger { get => _logger; }
|
|
|
|
public MonitoringSettings Config { get => _config; }
|
|
|
|
public LazyConcurrentContainer<ProcessInfo> Processes { get => _processes; }
|
2025-06-30 18:15:07 +03:00
|
|
|
|
2025-07-03 15:22:40 +03:00
|
|
|
public IEnumerable<ProcessBaseInfo>? GetBufferedProcesses()
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
2025-07-03 15:22:40 +03:00
|
|
|
return _processes.Values;
|
2025-07-02 16:06:50 +03:00
|
|
|
}
|
|
|
|
|
2025-07-03 20:01:19 +03:00
|
|
|
async public Task<ProcessInfo?> GetProcessDetails(int pid, ScanTarget target = ScanTarget.ProcessDetails)
|
2025-07-02 16:06:50 +03:00
|
|
|
{
|
2025-07-03 15:22:40 +03:00
|
|
|
if (_processes.Container != null && _processes.Container.TryGetValue(pid, out var info))
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
2025-07-03 15:22:40 +03:00
|
|
|
try
|
|
|
|
{
|
2025-07-03 20:01:19 +03:00
|
|
|
await _provider.CreateScanTask(info, target).ScanAsync();
|
2025-07-03 15:22:40 +03:00
|
|
|
_logger.LogInformation($"Scan details of the process {info.Name} (PID: {info.PID}) was completed.");
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
catch (ProcessMonitorException ex)
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
2025-07-03 15:22:40 +03:00
|
|
|
_logger.LogWarning(ex.Message);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
_logger.LogError($"Unhandled error during scanning of the process {info.Name} (PID: {info.PID}): {ex.Message}");
|
2025-06-30 18:15:07 +03:00
|
|
|
}
|
|
|
|
}
|
2025-07-03 15:22:40 +03:00
|
|
|
|
|
|
|
return null;
|
2025-06-30 18:15:07 +03:00
|
|
|
}
|
|
|
|
|
2025-07-02 16:06:50 +03:00
|
|
|
public ProcessMonitor(ILogger<ProcessMonitor> logger, IOptions<AppSettings> settings)
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
|
|
|
_logger = logger;
|
2025-07-02 16:06:50 +03:00
|
|
|
_config = settings.Value.Monitoring;
|
2025-07-03 15:22:40 +03:00
|
|
|
_provider = new(this);
|
2025-06-30 18:15:07 +03:00
|
|
|
}
|
2025-07-03 20:01:19 +03:00
|
|
|
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
2025-07-02 16:06:50 +03:00
|
|
|
_logger.LogInformation($"ProcessMonitor started. Scan interval: {_config.ProcessScanInterval} seconds.");
|
2025-06-30 18:15:07 +03:00
|
|
|
|
2025-07-03 20:01:19 +03:00
|
|
|
await ScanAsync();
|
|
|
|
|
|
|
|
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(_config.ProcessScanInterval));
|
|
|
|
try
|
|
|
|
{
|
|
|
|
while (await timer.WaitForNextTickAsync(stoppingToken))
|
|
|
|
{
|
|
|
|
await ScanAsync();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (OperationCanceledException)
|
|
|
|
{
|
|
|
|
_logger.LogInformation("ProcessMonitor is stopping due to cancellation.");
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
_logger.LogError(ex, "ProcessMonitor encountered an unhandled exception and is stopping.");
|
|
|
|
}
|
2025-07-02 16:06:50 +03:00
|
|
|
}
|
2025-06-30 18:15:07 +03:00
|
|
|
|
2025-07-03 20:01:19 +03:00
|
|
|
private async Task ScanAsync()
|
2025-07-02 16:06:50 +03:00
|
|
|
{
|
|
|
|
_logger.LogDebug("Initiating process scan...");
|
|
|
|
try
|
|
|
|
{
|
2025-07-03 20:01:19 +03:00
|
|
|
await _provider.CreateScanTask().ScanAsync();
|
2025-07-03 15:22:40 +03:00
|
|
|
_logger.LogInformation($"Process buffer updated, contains {Processes.Container?.Count} processes.");
|
2025-06-30 18:15:07 +03:00
|
|
|
}
|
2025-07-03 15:22:40 +03:00
|
|
|
catch (ProcessMonitorException ex)
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
2025-07-03 15:22:40 +03:00
|
|
|
_logger.LogWarning(ex.Message);
|
2025-06-30 18:15:07 +03:00
|
|
|
}
|
2025-07-02 16:06:50 +03:00
|
|
|
catch (Exception ex)
|
2025-06-30 18:15:07 +03:00
|
|
|
{
|
2025-07-03 15:22:40 +03:00
|
|
|
_logger.LogError($"Unhandled error during process monitoring cycle: {ex.Message}");
|
2025-06-30 18:15:07 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-07-02 16:06:50 +03:00
|
|
|
}
|