Skip to content
Snippets Groups Projects
Commit 63e394d8 authored by Niko Ehrenfeuchter's avatar Niko Ehrenfeuchter :keyboard:
Browse files

Extend Monitoring.Cpu with field initializers and timeout on violation.

parent 02502089
No related branches found
No related tags found
No related merge requests found
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Timers;
using NLog;
using Timer = System.Timers.Timer;
namespace ATxCommon.Monitoring
{
......@@ -13,26 +15,78 @@ namespace ATxCommon.Monitoring
private readonly Timer _monitoringTimer;
private readonly PerformanceCounter _cpuCounter;
private readonly float[] _loadReadings = {0F, 0F, 0F, 0F};
private float _load;
private int _interval;
private int _limit;
private int _behaving;
private int _probation;
private bool _enabled;
public float Load() => _load;
public int Interval {
get => _interval;
set {
_interval = value;
_monitoringTimer.Interval = value;
Log.Debug("CPU monitoring interval: {0}", _interval);
}
}
public int Limit {
get => _limit;
set {
_limit = value;
Log.Debug("CPU monitoring limit: {0}", _limit);
}
}
public int Probation {
get => _probation;
set {
_probation = value;
Log.Debug("CPU monitoring probation cycles when violating limit: {0}", _probation);
}
}
public bool Enabled {
get => _enabled;
set => EnableTimer(value);
}
public Cpu() {
_interval = 250;
_limit = 25;
_probation = 40;
Log.Debug("Initializing CPU monitoring...");
try {
_cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
_monitoringTimer = new Timer(250);
Log.Debug("CPU monitoring initializing PerformanceCounter (takes 1s)...");
_cpuCounter.NextValue();
Thread.Sleep(1000);
Log.Debug("CPU monitoring current load: {0}", _cpuCounter.NextValue());
// _monitoringTimer = new Timer(_interval);
_monitoringTimer = new Timer(_interval);
_monitoringTimer.Elapsed += UpdateCpuLoad;
_monitoringTimer.Enabled = true;
}
catch (Exception ex) {
Log.Error("Initializing CPU monitoring completed ({1}): {0}", ex.Message, ex.GetType());
catch (Exception) {
Log.Error("Initializing CPU monitoring failed!");
throw;
}
Log.Debug("Initializing CPU monitoring completed.");
}
private void EnableTimer(bool enabled) {
Log.Debug("{0} CPU monitoring.", enabled ? "Enabling" : "Disabling");
_monitoringTimer.Enabled = enabled;
_enabled = enabled;
}
private void UpdateCpuLoad(object sender, ElapsedEventArgs e) {
_monitoringTimer.Enabled = false;
try {
......@@ -42,6 +96,22 @@ namespace ATxCommon.Monitoring
_loadReadings[3] = _cpuCounter.NextValue();
_load = _loadReadings.Average();
Log.Trace("load values: {0}, average: {1}", string.Join(", ", _loadReadings), _load);
if (_loadReadings[3] > _limit) {
Log.Debug("CPU load ({0}) violating limit ({1})!", _loadReadings[3], _limit);
_behaving = 0;
// TODO: fire callback for violating load limit
} else {
_behaving++;
if (_behaving == _probation) {
Log.Debug("CPU load below limit for {0} cycles, yay!", _probation);
// TODO: fire callback for load behaving well
} else if (_behaving > _probation) {
Log.Debug("CPU load behaving well since {0} cycles.", _behaving);
} else if (_behaving < 0) {
Log.Warn("Integer wrap around happened, resetting probation counter!");
_behaving = 0;
}
}
}
catch (Exception ex) {
Log.Error("UpdateCpuLoad failed: {0}", ex.Message);
......
......@@ -380,14 +380,32 @@ namespace ATxService
_mainTimer.Elapsed += OnTimedEvent;
_mainTimer.Enabled = true;
_cpu = new Cpu();
}
catch (Exception ex) {
Log.Error("Error in OnStart(): {0}", ex.Message);
throw;
}
try {
_cpu = new Cpu {
Interval = 250,
Limit = 25,
Probation = 16,
Enabled = true
};
}
catch (UnauthorizedAccessException ex) {
Log.Error("Not enough permissions to monitor the CPU load.\nMake sure the " +
"service account is a member of the [Performance Monitor Users] " +
"system group.\nError message was: {0}", ex.Message);
throw;
}
catch (Exception ex) {
Log.Error("Unexpected error initializing CPU monitoring: {0}", ex.Message);
throw;
}
// read the build timestamp from the resources:
var buildTimestamp = Properties.Resources.BuildDate.Trim();
var buildCommitName = Properties.Resources.BuildCommit.Trim();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment