Skip to content

Commit 45ce0d9

Browse files
committed
Allow query network usage
1 parent 72024a1 commit 45ce0d9

File tree

3 files changed

+105
-7
lines changed

3 files changed

+105
-7
lines changed

IPBanCore/Core/Utility/OSUtility.cs

Lines changed: 97 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,16 @@ public class OSUtility
9696
public static bool UsesYumPackageManager { get; private set; }
9797

9898
private static readonly string tempFolder;
99+
private static readonly object locker = new();
100+
101+
private static PerformanceCounter windowsCpuCounter;
102+
private static float windowsCpuUsage;
103+
private static float networkUsage = -1.0f;
99104

100105
private static bool isWindows;
101106
private static bool isLinux;
102107
private static bool isMac;
103108

104-
105109
private static readonly string processVerb;
106110

107111
static OSUtility()
@@ -473,13 +477,37 @@ public static bool GetCpuUsage(out float percentUsed)
473477
percentUsed = 0.0f;
474478
if (isWindows)
475479
{
476-
string output = StartProcessAndWait(60000, "wmic", "cpu get loadpercentage", out _, LogLevel.Trace);
477-
string[] lines = output.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
478-
if (lines.Length > 1 && float.TryParse(lines[^1], NumberStyles.None, CultureInfo.InvariantCulture, out percentUsed))
480+
if (windowsCpuCounter is null)
479481
{
480-
percentUsed *= 0.01f;
481-
return true;
482+
lock (locker)
483+
{
484+
if (windowsCpuCounter is null)
485+
{
486+
windowsCpuCounter = new PerformanceCounter("Processor Information", "% Processor Utility", "_Total");
487+
488+
// capture windows cpu in background
489+
System.Threading.Tasks.Task.Run(async () =>
490+
{
491+
windowsCpuUsage = Math.Clamp(windowsCpuCounter.NextValue() * 0.01f, 0.0f, 1.0f);
492+
while (!Environment.HasShutdownStarted)
493+
{
494+
await System.Threading.Tasks.Task.Delay(1000);
495+
windowsCpuUsage = Math.Clamp(windowsCpuCounter.NextValue() * 0.01f, 0.0f, 1.0f);
496+
}
497+
});
498+
}
499+
}
482500
}
501+
502+
percentUsed = windowsCpuUsage;
503+
//string output = StartProcessAndWait(60000, "wmic", "cpu get loadpercentage", out _, LogLevel.Trace);
504+
//string[] lines = output.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
505+
//if (lines.Length > 1 && float.TryParse(lines[^1], NumberStyles.None, CultureInfo.InvariantCulture, out percentUsed))
506+
//{
507+
//percentUsed *= 0.01f;
508+
//return true;
509+
//}
510+
return true;
483511
}
484512
else if (isLinux)
485513
{
@@ -493,7 +521,7 @@ public static bool GetCpuUsage(out float percentUsed)
493521
string piece = lines[^1][pos..].Trim();
494522
if (pos > 0 && float.TryParse(piece, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out percentUsed))
495523
{
496-
percentUsed = 1.0f - (0.01f * percentUsed);
524+
percentUsed = Math.Clamp(1.0f - (0.01f * percentUsed), 0.0f, 1.0f);
497525
return true;
498526
}
499527
}
@@ -502,6 +530,68 @@ public static bool GetCpuUsage(out float percentUsed)
502530
return false;
503531
}
504532

533+
/// <summary>
534+
/// Get system network usage
535+
/// </summary>
536+
/// <param name="percentUsed">Percent of system network used, 0-1</param>
537+
/// <returns>True if network usage could be determined, false otherwise</returns>
538+
public static bool GetNetworkUsage(out float percentUsed)
539+
{
540+
if (networkUsage < 0.0f)
541+
{
542+
lock (locker)
543+
{
544+
if (networkUsage < 0.0f)
545+
{
546+
networkUsage = 0.0f;
547+
548+
// capture network usage in background
549+
System.Threading.Tasks.Task.Run(async () =>
550+
{
551+
System.Net.NetworkInformation.NetworkInterface[] nics = null;
552+
long[] prevTransfer = null;
553+
double[] maxSpeeds = null;
554+
while (!Environment.HasShutdownStarted)
555+
{
556+
if (nics is null)
557+
{
558+
try
559+
{
560+
nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces().Where(n => n.NetworkInterfaceType == System.Net.NetworkInformation.NetworkInterfaceType.Ethernet).ToArray();
561+
prevTransfer = new long[nics.Length];
562+
maxSpeeds = new double[nics.Length];
563+
for (int i = 0; i < nics.Length; i++)
564+
{
565+
prevTransfer[i] = nics[i].GetIPStatistics().BytesReceived + nics[i].GetIPStatistics().BytesSent;
566+
maxSpeeds[i] = (double)(nics[i].Speed / 8);
567+
}
568+
}
569+
catch
570+
{
571+
// non-fatal, try again later
572+
}
573+
}
574+
await System.Threading.Tasks.Task.Delay(1000);
575+
if (nics is not null)
576+
{
577+
float percent = 0.0f;
578+
for (int i = 0; i < nics.Length; i++)
579+
{
580+
long currentTransfer = nics[i].GetIPStatistics().BytesReceived + nics[i].GetIPStatistics().BytesSent;
581+
percent = (float)Math.Max(percent, (double)(currentTransfer - prevTransfer[i]) / maxSpeeds[i]);
582+
prevTransfer[i] = currentTransfer;
583+
}
584+
networkUsage = Math.Clamp(percent, 0.0f, 1.0f);
585+
}
586+
}
587+
});
588+
}
589+
}
590+
}
591+
percentUsed = networkUsage;
592+
return true;
593+
}
594+
505595
/// <summary>
506596
/// Easy way to execute processes. If the process has not finished after 60 seconds, it is forced killed.
507597
/// </summary>

IPBanCore/IPBanCore.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
4242
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
4343
<PackageReference Include="NLog" Version="4.7.15" />
44+
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="6.0.1" />
4445
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="6.0.0" />
4546
</ItemGroup>
4647

IPBanTests/IPBanOSTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ public void TestCpuUsage()
6363
Assert.IsTrue(percentUsed >= 0.0f && percentUsed <= 1.0f);
6464
}
6565

66+
[Test]
67+
public void TestNetworkUsage()
68+
{
69+
Assert.IsTrue(OSUtility.GetNetworkUsage(out float percentUsed));
70+
Assert.IsTrue(percentUsed >= 0.0f && percentUsed <= 1.0f);
71+
}
72+
6673
[Test]
6774
public void TestGetMacAddress()
6875
{

0 commit comments

Comments
 (0)