diff --git a/Configuration/MonitoringSettings.cs b/Configuration/MonitoringSettings.cs index 2a22d0c..c890d66 100644 --- a/Configuration/MonitoringSettings.cs +++ b/Configuration/MonitoringSettings.cs @@ -8,6 +8,7 @@ namespace ResourceMonitorService.Configuration public bool EnableDiskMonitoring { get; set; } = true; public bool EnableTemperatureMonitoring { get; set; } = true; public bool EnableProcessMonitoring { get; set; } = true; + public bool EnableDetailedCpuCoreMonitoring { get; set; } = false; // Disable by default for better performance public bool EnableGameDetection { get; set; } = true; public bool EnableAlerts { get; set; } = true; public int MaxProcessesToTrack { get; set; } = 10; diff --git a/Services/ResourceMonitorService.cs b/Services/ResourceMonitorService.cs index d34228e..05abd64 100644 --- a/Services/ResourceMonitorService.cs +++ b/Services/ResourceMonitorService.cs @@ -96,32 +96,26 @@ namespace ResourceMonitorService.Services { var timestamp = DateTime.Now; - var tasks = new List - { - Task.Run(async () => await GetCpuUsageAsync()), - Task.Run(async () => await GetMemoryUsageAsync()) - }; + // Execute all monitoring tasks in parallel and capture results + var cpuTask = GetCpuUsageAsync(); + var memoryTask = GetMemoryUsageAsync(); + var gpuTask = _settings.EnableGpuMonitoring ? GetGpuUsageAsync() : Task.FromResult(new GpuUsage()); + var diskTask = _settings.EnableDiskMonitoring ? GetDiskUsageAsync() : Task.FromResult(new List()); + var processTask = _settings.EnableProcessMonitoring ? GetTopProcessesAsync(_settings.MaxProcessesToTrack) : Task.FromResult(new List()); + var temperatureTask = _settings.EnableTemperatureMonitoring ? GetTemperatureInfoAsync() : Task.FromResult(new TemperatureInfo()); - if (_settings.EnableGpuMonitoring) - tasks.Add(Task.Run(async () => await GetGpuUsageAsync())); - - if (_settings.EnableDiskMonitoring) - tasks.Add(Task.Run(async () => await GetDiskUsageAsync())); - - if (_settings.EnableProcessMonitoring) - tasks.Add(Task.Run(async () => await GetTopProcessesAsync(_settings.MaxProcessesToTrack))); - - await Task.WhenAll(tasks); + // Wait for all tasks to complete + await Task.WhenAll(cpuTask, memoryTask, gpuTask, diskTask, processTask, temperatureTask); return new ResourceUsage { Timestamp = timestamp, - CPU = await GetCpuUsageAsync(), - Memory = await GetMemoryUsageAsync(), - GPU = _settings.EnableGpuMonitoring ? await GetGpuUsageAsync() : new GpuUsage(), - Disks = _settings.EnableDiskMonitoring ? await GetDiskUsageAsync() : new List(), - TopProcesses = _settings.EnableProcessMonitoring ? await GetTopProcessesAsync(_settings.MaxProcessesToTrack) : new List(), - Temperature = _settings.EnableTemperatureMonitoring ? await GetTemperatureInfoAsync() : new TemperatureInfo() + CPU = await cpuTask, + Memory = await memoryTask, + GPU = await gpuTask, + Disks = await diskTask, + TopProcesses = await processTask, + Temperature = await temperatureTask }; } @@ -136,20 +130,23 @@ namespace ResourceMonitorService.Services #pragma warning disable CA1416 // Validate platform compatibility var usage = _counters.TryGetValue("cpu", out var cpuCounter) ? cpuCounter.NextValue() : 0f; - // Get per-core usage + // Get per-core usage (only if enabled for performance) var coreUsages = new List(); - for (int i = 0; i < Environment.ProcessorCount; i++) + if (_settings.EnableDetailedCpuCoreMonitoring) { - try + for (int i = 0; i < Environment.ProcessorCount; i++) { - using var coreCounter = new PerformanceCounter("Processor", "% Processor Time", i.ToString()); - coreCounter.NextValue(); - Thread.Sleep(100); // Small delay for accurate reading - coreUsages.Add(coreCounter.NextValue()); - } - catch - { - coreUsages.Add(0f); + try + { + using var coreCounter = new PerformanceCounter("Processor", "% Processor Time", i.ToString()); + coreCounter.NextValue(); + Thread.Sleep(50); // Reduced delay for faster reading while maintaining accuracy + coreUsages.Add(coreCounter.NextValue()); + } + catch + { + coreUsages.Add(0f); + } } } diff --git a/Services/TelegramNotificationService.cs b/Services/TelegramNotificationService.cs index 15729e2..f3f402c 100644 --- a/Services/TelegramNotificationService.cs +++ b/Services/TelegramNotificationService.cs @@ -77,6 +77,15 @@ namespace ResourceMonitorService.Services return; } + // Ignore alerts from svchost processes + if (alert.Component.Contains("svchost", StringComparison.OrdinalIgnoreCase) || + alert.Message.Contains("svchost", StringComparison.OrdinalIgnoreCase)) + { + _logger.LogInformation("Skipping Telegram alert for svchost process: {Component} - {Message}", + alert.Component, alert.Message); + return; + } + var message = FormatAlertMessage(alert, _telegramSettings.MessageTemplate); foreach (var chatId in _telegramSettings.ChatIds) @@ -110,6 +119,15 @@ namespace ResourceMonitorService.Services if (_botClient == null || !_telegramSettings.IsEnabled || !_telegramSettings.SendResolutionNotifications) return; + // Ignore alerts from svchost processes + if (alert.Component.Contains("svchost", StringComparison.OrdinalIgnoreCase) || + alert.Message.Contains("svchost", StringComparison.OrdinalIgnoreCase)) + { + _logger.LogInformation("Skipping Telegram resolution notification for svchost process: {Component} - {Message}", + alert.Component, alert.Message); + return; + } + var message = FormatAlertMessage(alert, _telegramSettings.ResolutionTemplate); foreach (var chatId in _telegramSettings.ChatIds) diff --git a/appsettings.json b/appsettings.json index 1c7ea63..8c7bfc2 100644 --- a/appsettings.json +++ b/appsettings.json @@ -22,13 +22,14 @@ "BasePath": "/api" }, "MonitoringSettings": { - "UpdateIntervalMs": 120000, + "UpdateIntervalMs": 60000, "DataRetentionDays": 7, "EnableGpuMonitoring": true, "EnableDiskMonitoring": true, "EnableNetworkMonitoring": true, "EnableTemperatureMonitoring": true, "EnableProcessMonitoring": true, + "EnableDetailedCpuCoreMonitoring": false, "EnableGameDetection": true, "EnableAlerts": true, "MaxProcessesToTrack": 10, diff --git a/install-service.ps1 b/install-service.ps1 index 79ccafc..26f2827 100644 --- a/install-service.ps1 +++ b/install-service.ps1 @@ -77,6 +77,25 @@ try { exit 1 } +# Check if service is currently running and stop it before building +Write-Host "Checking for existing service..." +try { + $existingService = Get-Service -Name $SERVICE_NAME -ErrorAction SilentlyContinue + if ($existingService) { + Write-Host "Found existing service: $($existingService.Status)" -ForegroundColor Yellow + if ($existingService.Status -eq "Running") { + Write-Host "Stopping running service before build..." + Stop-Service -Name $SERVICE_NAME -Force -ErrorAction Stop + Write-Host "Service stopped successfully" -ForegroundColor Green + Start-Sleep -Seconds 2 # Give it a moment to fully stop + } + } else { + Write-Host "No existing service found" -ForegroundColor Gray + } +} catch { + Write-Host "Warning: Could not check existing service status: $($_.Exception.Message)" -ForegroundColor Yellow +} + # Build the service in release mode Write-Host "Building service..." try { diff --git a/quick-test.ps1 b/quick-test.ps1 new file mode 100644 index 0000000..2e6613a --- /dev/null +++ b/quick-test.ps1 @@ -0,0 +1,27 @@ +# Quick API Test Command +# Run this after starting the service with: dotnet run + +$stopwatch = [System.Diagnostics.Stopwatch]::StartNew() +try { + $response = Invoke-WebRequest -Uri "http://localhost:5000/api/resource/usage" -UseBasicParsing + $stopwatch.Stop() + $content = $response.Content | ConvertFrom-Json + + Write-Host "✅ API Response Time: $($stopwatch.ElapsedMilliseconds)ms" -ForegroundColor Green + Write-Host " Status: $($response.StatusCode)" -ForegroundColor Cyan + Write-Host " CPU Usage: $($content.CPU.Usage)%" -ForegroundColor White + Write-Host " Memory Usage: $($content.Memory.UsagePercentage)%" -ForegroundColor White + Write-Host " Core Count: $($content.CPU.CoreUsages.Length)" -ForegroundColor White + + if ($stopwatch.ElapsedMilliseconds -lt 1000) { + Write-Host "🚀 Excellent performance!" -ForegroundColor Green + } elseif ($stopwatch.ElapsedMilliseconds -lt 2000) { + Write-Host "✅ Good performance" -ForegroundColor Yellow + } else { + Write-Host "⚠️ Could be faster" -ForegroundColor Red + } +} +catch { + $stopwatch.Stop() + Write-Host "❌ Error after $($stopwatch.ElapsedMilliseconds)ms: $($_.Exception.Message)" -ForegroundColor Red +} diff --git a/test-performance.ps1 b/test-performance.ps1 new file mode 100644 index 0000000..444500a --- /dev/null +++ b/test-performance.ps1 @@ -0,0 +1,56 @@ +# Performance test script for ResourceUsage API +Write-Host "Waiting for service to start..." -ForegroundColor Yellow +Start-Sleep -Seconds 5 + +Write-Host "Testing API response time..." -ForegroundColor Green +$times = @() +$errors = 0 + +for ($i = 1; $i -le 5; $i++) { + $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + try { + $response = Invoke-WebRequest -Uri "http://localhost:5000/api/resource/usage" -UseBasicParsing -TimeoutSec 30 + $stopwatch.Stop() + $time = $stopwatch.ElapsedMilliseconds + $times += $time + Write-Host "Test $i - Response time: ${time}ms - Status: $($response.StatusCode)" -ForegroundColor Cyan + + # Show first response content for verification + if ($i -eq 1) { + $jsonContent = $response.Content | ConvertFrom-Json + Write-Host "Sample response - CPU Usage: $($jsonContent.CPU.Usage)%" -ForegroundColor White + } + } + catch { + $stopwatch.Stop() + $errors++ + Write-Host "Test $i - Error after $($stopwatch.ElapsedMilliseconds)ms: $($_.Exception.Message)" -ForegroundColor Red + } + + if ($i -lt 5) { + Start-Sleep -Seconds 2 + } +} + +if ($times.Count -gt 0) { + $avgTime = ($times | Measure-Object -Average).Average + $minTime = ($times | Measure-Object -Minimum).Minimum + $maxTime = ($times | Measure-Object -Maximum).Maximum + + Write-Host "`nPerformance Results:" -ForegroundColor Green + Write-Host " Average response time: $([math]::Round($avgTime, 2))ms" -ForegroundColor White + Write-Host " Minimum response time: ${minTime}ms" -ForegroundColor White + Write-Host " Maximum response time: ${maxTime}ms" -ForegroundColor White + Write-Host " Successful requests: $($times.Count)/5" -ForegroundColor White + Write-Host " Failed requests: $errors/5" -ForegroundColor White + + if ($avgTime -lt 1000) { + Write-Host "✅ Performance looks good!" -ForegroundColor Green + } elseif ($avgTime -lt 3000) { + Write-Host "⚠️ Performance is acceptable but could be better" -ForegroundColor Yellow + } else { + Write-Host "❌ Performance needs improvement" -ForegroundColor Red + } +} else { + Write-Host "❌ All requests failed!" -ForegroundColor Red +} diff --git a/wwwroot/index.html b/wwwroot/index.html index f593c88..867318e 100644 --- a/wwwroot/index.html +++ b/wwwroot/index.html @@ -140,6 +140,7 @@ Process CPU % Memory + Memory % Action diff --git a/wwwroot/js/dashboard.js b/wwwroot/js/dashboard.js index f71b9b0..336f9d3 100644 --- a/wwwroot/js/dashboard.js +++ b/wwwroot/js/dashboard.js @@ -428,7 +428,7 @@ class ResourceDashboard { if (!processes || !Array.isArray(processes)) { const row = document.createElement('tr'); - row.innerHTML = 'No process data available'; + row.innerHTML = 'No process data available'; tableBody.appendChild(row); return; } @@ -448,6 +448,7 @@ class ResourceDashboard { const processId = process.processId || 0; const cpuUsage = process.cpuUsage || 0; const memoryUsage = process.memoryUsage || 0; + const memoryUsagePercentage = process.memoryUsagePercentage || 0; row.innerHTML = ` @@ -462,6 +463,9 @@ class ResourceDashboard { ${(memoryUsage / 1024 / 1024).toFixed(1)} MB + + ${memoryUsagePercentage.toFixed(1)}% +