@@ -99,7 +99,9 @@ public class OSUtility
99
99
private static readonly object locker = new ( ) ;
100
100
101
101
private static PerformanceCounter windowsCpuCounter ;
102
- private static float windowsCpuUsage ;
102
+ private static PerformanceCounter windowsDiskIopsCounter ;
103
+ private static float windowsCpuPercent ;
104
+ private static float windowsDiskIopsPercent ;
103
105
private static float networkUsage = - 1.0f ;
104
106
105
107
private static bool isWindows ;
@@ -488,18 +490,18 @@ public static bool GetCpuUsage(out float percentUsed)
488
490
// capture windows cpu in background
489
491
System . Threading . Tasks . Task . Run ( async ( ) =>
490
492
{
491
- windowsCpuUsage = Math . Clamp ( windowsCpuCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
493
+ windowsCpuPercent = Math . Clamp ( windowsCpuCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
492
494
while ( ! Environment . HasShutdownStarted )
493
495
{
494
496
await System . Threading . Tasks . Task . Delay ( 1000 ) ;
495
- windowsCpuUsage = Math . Clamp ( windowsCpuCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
497
+ windowsCpuPercent = Math . Clamp ( windowsCpuCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
496
498
}
497
499
} ) ;
498
500
}
499
501
}
500
502
}
501
503
502
- percentUsed = windowsCpuUsage ;
504
+ percentUsed = windowsCpuPercent ;
503
505
//string output = StartProcessAndWait(60000, "wmic", "cpu get loadpercentage", out _, LogLevel.Trace);
504
506
//string[] lines = output.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
505
507
//if (lines.Length > 1 && float.TryParse(lines[^1], NumberStyles.None, CultureInfo.InvariantCulture, out percentUsed))
@@ -511,6 +513,10 @@ public static bool GetCpuUsage(out float percentUsed)
511
513
}
512
514
else if ( isLinux )
513
515
{
516
+ // Linux 5.10.102.1-microsoft-standard-WSL2 (MACHINE_NAME) 04/24/22 _x86_64_ (24 CPU)
517
+ //
518
+ // 14:19:43 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
519
+ // 14:19:43 all 0.00 0.00 0.02 0.00 0.00 0.00 0.00 0.00 0.00 99.97
514
520
string output = StartProcessAndWait ( 60000 , "mpstat" , string . Empty , out _ , LogLevel . Trace ) ;
515
521
string [ ] lines = output . Split ( '\n ' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries ) ;
516
522
if ( lines . Length > 1 )
@@ -592,6 +598,66 @@ public static bool GetNetworkUsage(out float percentUsed)
592
598
return true ;
593
599
}
594
600
601
+ /// <summary>
602
+ /// Get current percentage of max iops used
603
+ /// </summary>
604
+ /// <param name="percentUsed">Percent of max iops used (0-1, maximum number determined from each drive)</param>
605
+ /// <returns>True if max iops percented could be determined, false otherwise</returns>
606
+ public static bool GetDiskIopsUsage ( out float percentUsed )
607
+ {
608
+ percentUsed = 0.0f ;
609
+ if ( isWindows )
610
+ {
611
+ if ( windowsDiskIopsCounter is null )
612
+ {
613
+ lock ( locker )
614
+ {
615
+ if ( windowsDiskIopsCounter is null )
616
+ {
617
+ windowsDiskIopsCounter = new PerformanceCounter ( "PhysicalDisk" , "% Disk Time" , "_Total" ) ;
618
+
619
+ // capture disk io in background
620
+ System . Threading . Tasks . Task . Run ( async ( ) =>
621
+ {
622
+ windowsDiskIopsPercent = Math . Clamp ( windowsDiskIopsCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
623
+ while ( ! Environment . HasShutdownStarted )
624
+ {
625
+ await System . Threading . Tasks . Task . Delay ( 1000 ) ;
626
+ windowsDiskIopsPercent = Math . Clamp ( windowsDiskIopsCounter . NextValue ( ) * 0.01f , 0.0f , 1.0f ) ;
627
+ }
628
+ } ) ;
629
+ }
630
+ }
631
+ }
632
+
633
+ percentUsed = windowsDiskIopsPercent ;
634
+ return true ;
635
+ }
636
+ else if ( isLinux )
637
+ {
638
+ //Linux 5.10.102.1-microsoft-standard-WSL2 (MACHINE_NAME) 04/24/22 _x86_64_ (24 CPU)
639
+ //
640
+ //Device tps kB/s rqm/s await areq-sz aqu-sz %util
641
+ //sda 11.07 5598.69 0.45 0.55 505.97 0.01 2.79
642
+ //sdb 0.95 61.60 0.48 0.16 64.66 0.00 0.03
643
+ //sdc 3.04 160.40 3.20 0.48 52.75 0.00 0.13
644
+ string output = StartProcessAndWait ( 60000 , "iostat" , "-dxs" , out _ , LogLevel . Trace ) ;
645
+ string [ ] lines = output . Split ( '\n ' , StringSplitOptions . RemoveEmptyEntries | StringSplitOptions . TrimEntries ) ;
646
+ float maxValue = 0.0f ;
647
+ foreach ( string line in lines . Skip ( 2 ) ) // blank line will be trimmed out
648
+ {
649
+ int pos = line . LastIndexOf ( ' ' ) ;
650
+ if ( pos > 0 && float . TryParse ( line [ pos ..] . Trim ( ) , NumberStyles . AllowDecimalPoint , CultureInfo . InvariantCulture , out float parsedValue ) )
651
+ {
652
+ maxValue = Math . Max ( maxValue , parsedValue ) ;
653
+ }
654
+ }
655
+ percentUsed = Math . Clamp ( maxValue * 0.01f , 0.0f , 1.0f ) ;
656
+ return true ;
657
+ }
658
+ return false ;
659
+ }
660
+
595
661
/// <summary>
596
662
/// Easy way to execute processes. If the process has not finished after 60 seconds, it is forced killed.
597
663
/// </summary>
0 commit comments