mirror of
https://github.com/webmin/webmin.git
synced 2026-08-07 16:30:38 +01:00
Fix to replace vmstat with /proc sampler for same output with much lower overhead
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
* Fix the printing of the bottom button row in the form column table
|
||||
* Fix to recommend Perl `Sys::Syslog` module #2557
|
||||
* Fix to avoid using short hostname in HTTPS redirects when an FQDN is available
|
||||
* Fix to use _/proc_ sampler instead of `vmstat` for the same output with much lower overhead
|
||||
* Fix to query specific fields in FreeBSD memory stats collection, cutting CPU use by 80%
|
||||
* Add a complete overhaul of `var_dump` subroutine, which is now fully portable
|
||||
* Update the Authentic theme to the latest version with various fixes:
|
||||
|
||||
@@ -754,31 +754,65 @@ return (\@cpu, \@fans);
|
||||
}
|
||||
|
||||
# get_cpu_io_usage()
|
||||
# Returns a list containing CPU user, kernel, idle, io and VM time, and IO
|
||||
# blocks in and out
|
||||
# Returns a list of "us", "sy", "id", "wa", "st", "bi", "bo" that match `vmstat`
|
||||
# output by using /proc with much lower overhead
|
||||
sub get_cpu_io_usage
|
||||
{
|
||||
my ($nodelay) = @_;
|
||||
my $interval;
|
||||
$interval = " 1 2"
|
||||
if (!$nodelay);
|
||||
my ($out, @lines, @w);
|
||||
if (&has_command("vmstat")) {
|
||||
$out = &backquote_command("vmstat$interval 2>/dev/null");
|
||||
@lines = split(/\r?\n/, $out);
|
||||
@w = split(/\s+/, $lines[$#lines]);
|
||||
shift(@w) if ($w[0] eq '');
|
||||
if ($w[8] =~ /^\d+$/ && $w[9] =~ /^\d+$/) {
|
||||
return ( @w[12..16], $w[8], $w[9] );
|
||||
}
|
||||
} elsif (&has_command("dstat")) {
|
||||
$out = &backquote_command("dstat 1 1 2>/dev/null");
|
||||
@lines = split(/\r?\n/, $out);
|
||||
@w = split(/[\s|]+/, $lines[$#lines]);
|
||||
shift(@w) if ($w[0] eq '');
|
||||
return( @w[0..4], @w[6..7]);
|
||||
}
|
||||
return undef;
|
||||
# Read CPU counters from /proc/stat, the first "cpu" line
|
||||
my $read_cpu = sub {
|
||||
open(my $fh, '<', '/proc/stat') or return;
|
||||
my $line = <$fh>;
|
||||
close($fh);
|
||||
return unless defined $line && $line =~ /^cpu\s+/;
|
||||
my @v = split /\s+/, $line; shift @v;
|
||||
push @v, (0) x (8-@v) if @v < 8;
|
||||
return @v[0..7];
|
||||
};
|
||||
|
||||
# Read pgpgin/pgpgout from /proc/vmstat (in KB). Note, that all modern kernels,
|
||||
# /proc/vmstat pgpgin/pgpgout are KiB (scale=1); not as *pages*, so no need to
|
||||
# convert deltas
|
||||
my $read_io = sub {
|
||||
open(my $fh, '<', '/proc/vmstat') or return (undef, undef);
|
||||
my ($in, $out);
|
||||
while (my $l = <$fh>) {
|
||||
$in = $1 if !defined $in && $l =~ /^pgpgin\s+(\d+)/;
|
||||
$out = $1 if !defined $out && $l =~ /^pgpgout\s+(\d+)/;
|
||||
last if defined $in && defined $out;
|
||||
}
|
||||
close($fh);
|
||||
return ($in, $out); # KB on kernels 2.6.18+; no conversion needed
|
||||
};
|
||||
|
||||
# Sample A
|
||||
my @cb = $read_cpu->() or return;
|
||||
my ($pgin_b, $pgout_b) = $read_io->();
|
||||
|
||||
# Sleep half a second
|
||||
select(undef, undef, undef, 0.5);
|
||||
|
||||
# Sample B
|
||||
my @ca = $read_cpu->() or return;
|
||||
my ($pgin_a, $pgout_a) = $read_io->();
|
||||
|
||||
# CPU percentages as in vmstat
|
||||
my @d = map { $ca[$_] - $cb[$_] } 0..7;
|
||||
for (@d) { $_ = 0 if $_ < 0 }
|
||||
my $tot = 0; $tot += $_ for @d[0..7];
|
||||
return if !$tot;
|
||||
|
||||
# Calculate percentages
|
||||
my $us = int( (($d[0] + $d[1]) / $tot) * 100 ); # user+nice
|
||||
my $sy = int( (($d[2] + $d[5] + $d[6]) / $tot) * 100 ); # system+irq+softirq
|
||||
my $id = int( ( $d[3] / $tot ) * 100 ); # idle
|
||||
my $wa = int( ( $d[4] / $tot ) * 100 ); # iowait
|
||||
my $st = int( ( $d[7] / $tot ) * 100 ); # steal
|
||||
|
||||
# Calculate bi/bo in KiB/s over half a second
|
||||
my ($bi, $bo) = (0, 0);
|
||||
$bi = int( (($pgin_a // 0) - ($pgin_b // 0)) / 0.5 );
|
||||
$bo = int( (($pgout_a // 0) - ($pgout_b // 0)) / 0.5 );
|
||||
return ($us, $sy, $id, $wa, $st, $bi, $bo);
|
||||
}
|
||||
|
||||
# has_disk_stats()
|
||||
|
||||
Reference in New Issue
Block a user