Difference between revisions of "Human readable user beancounters"
(Created page with useful content) |
|||
Line 1: | Line 1: | ||
{{UBC toc}} | {{UBC toc}} | ||
+ | |||
+ | For newbies to openvz it is fairly difficult to understand the meaning of the numbers in '''/proc/user_beancounters''' file. Calculating the values to something understandable for human brain everytime you look at these statistics is much work. I have written a perl script which reformats the output to human-readable values in kbyte and mbyte. | ||
+ | |||
+ | Just be sure you have Perl installed on your HN/VE, copy this script to somewhere on your machine, give it executable rights and start it. The output will be like this: | ||
+ | |||
+ | <pre> | ||
+ | BEANS FOR UID 254 | ||
+ | resource held maxheld barrier limit failcnt | ||
+ | kmemsize 15.14 mb 18.72 mb 150.30 mb 167.00 mb 0 | ||
+ | lockedpages 0 0 16.00 mb 16.00 mb 0 | ||
+ | privvmpages 433.79 mb 544.63 mb 2929.69 mb 3222.66 mb 0 | ||
+ | shmpages 11.58 mb 11.64 mb 512.00 mb 512.00 mb 0 | ||
+ | numproc 84 101 500 500 0 | ||
+ | physpages 278.24 mb 395.75 mb 0 MAX_ULONG 0 | ||
+ | vmguarpages 0 0 244.14 mb MAX_ULONG 0 | ||
+ | oomguarpages 279.66 mb 396.98 mb 122.07 mb MAX_ULONG 0 | ||
+ | numtcpsock 25 53 500 500 0 | ||
+ | numflock 18 22 200 220 0 | ||
+ | numpty 4 4 64 64 0 | ||
+ | numsiginfo 0 11 512 512 0 | ||
+ | tcpsndbuf 569.75 kb 679.25 kb 5.12 mb 10.00 mb 0 | ||
+ | tcprcvbuf 400.00 kb 1.28 mb 5.12 mb 10.00 mb 0 | ||
+ | othersockbuf 213.00 kb 284.25 kb 1.43 mb 3.88 mb 0 | ||
+ | dgramrcvbuf 0.00 kb 8.25 kb 256.00 kb 256.00 kb 0 | ||
+ | numothersock 155 175 500 500 0 | ||
+ | dcachesize 619.68 kb 656.68 kb 4.00 mb 4.12 mb 0 | ||
+ | numfile 2008 2397 9312 9312 0 | ||
+ | numiptent 10 10 128 128 0 | ||
+ | </pre> | ||
+ | |||
+ | The script is the following, just copy and paste: | ||
+ | <source lang=perl> | ||
+ | #!/usr/bin/perl | ||
+ | |||
+ | ############################################################################### | ||
+ | # vzstats.pl | ||
+ | # | ||
+ | # this script reads /proc/user_beancounters on openvz HNs and VEs and displays | ||
+ | # the values in human-readable format (megabytes/kilobytes). | ||
+ | # | ||
+ | # The script can be distributed freely for everybody who finds it usable. | ||
+ | # | ||
+ | # Christian Anton <mail@christiananton.de> 2008-09-18 | ||
+ | |||
+ | |||
+ | |||
+ | open(BEANS,"/proc/user_beancounters"); | ||
+ | chomp ($arch = `uname -m`); | ||
+ | |||
+ | sub check_maxulong { | ||
+ | my $number = shift; | ||
+ | |||
+ | if ($arch eq "x86_64") { | ||
+ | if ($number == 9223372036854775807) { | ||
+ | return 1; | ||
+ | } else { | ||
+ | return undef; | ||
+ | } | ||
+ | } else { | ||
+ | if ($number == 2147483647) { | ||
+ | return 1; | ||
+ | } else { | ||
+ | return undef; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sub recalc_bytes { | ||
+ | my $bytes = shift; | ||
+ | |||
+ | if (defined(&check_maxulong($bytes))) { return "MAX_ULONG"; } | ||
+ | |||
+ | my $kbytes = $bytes / 1024; | ||
+ | my $ret; | ||
+ | |||
+ | # if over 1mb, show mb values | ||
+ | if ($kbytes > 1024) { | ||
+ | my $mbytes = $kbytes / 1024; | ||
+ | $ret = sprintf("%.2f", $mbytes) . " mb"; | ||
+ | return $ret; | ||
+ | } else { | ||
+ | $ret = sprintf("%.2f", $kbytes) . " kb"; | ||
+ | return $ret; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sub recalc_pages { | ||
+ | my $pages = shift; | ||
+ | |||
+ | if ($pages == 0) { return "0"; } | ||
+ | if (defined(&check_maxulong($pages))) { return "MAX_ULONG"; } | ||
+ | |||
+ | my $kbytes = $pages * 4; | ||
+ | my $ret; | ||
+ | |||
+ | if ($kbytes > 1024) { | ||
+ | my $mbytes = $kbytes / 1024; | ||
+ | $ret = sprintf("%.2f", $mbytes) . " mb"; | ||
+ | return $ret; | ||
+ | } else { | ||
+ | $ret = sprintf("%.2f", $kbytes) . " kb"; | ||
+ | return $ret; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sub recalc_nothing { | ||
+ | my $number = shift; | ||
+ | if (defined(&check_maxulong($number))) { return "MAX_ULONG"; } | ||
+ | |||
+ | return $number; | ||
+ | } | ||
+ | |||
+ | sub printline { | ||
+ | my $mode = shift; # 0=normal, 1=bytes, 2=pages | ||
+ | my $ident = shift; | ||
+ | my $held = shift; | ||
+ | my $maxheld = shift; | ||
+ | my $barrier = shift; | ||
+ | my $limit = shift; | ||
+ | my $failcnt = shift; | ||
+ | |||
+ | if ($mode == 0) { | ||
+ | printf ("%-15s",$ident); | ||
+ | printf ("%18s",&recalc_nothing($held)); | ||
+ | printf ("%21s",&recalc_nothing($maxheld)); | ||
+ | printf ("%21s",&recalc_nothing($barrier)); | ||
+ | printf ("%21s",&recalc_nothing($limit)); | ||
+ | printf ("%21s",$failcnt); | ||
+ | print "\n"; | ||
+ | } elsif ($mode == 1) { | ||
+ | printf ("%-15s",$ident); | ||
+ | printf ("%18s",&recalc_bytes($held)); | ||
+ | printf ("%21s",&recalc_bytes($maxheld)); | ||
+ | printf ("%21s",&recalc_bytes($barrier)); | ||
+ | printf ("%21s",&recalc_bytes($limit)); | ||
+ | printf ("%21s",$failcnt); | ||
+ | print "\n"; | ||
+ | } elsif ($mode == 2) { | ||
+ | printf ("%-15s",$ident); | ||
+ | printf ("%18s",&recalc_pages($held)); | ||
+ | printf ("%21s",&recalc_pages($maxheld)); | ||
+ | printf ("%21s",&recalc_pages($barrier)); | ||
+ | printf ("%21s",&recalc_pages($limit)); | ||
+ | printf ("%21s",$failcnt); | ||
+ | print "\n"; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | sub work_line { | ||
+ | my $line = shift; | ||
+ | my $ident = $line; | ||
+ | my $held = $line; | ||
+ | my $maxheld = $line; | ||
+ | my $barrier = $line; | ||
+ | my $limit = $line; | ||
+ | my $failcnt = $line; | ||
+ | |||
+ | |||
+ | |||
+ | $ident =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$1/; | ||
+ | $held =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$2/; | ||
+ | $maxheld =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$3/; | ||
+ | $barrier =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$4/; | ||
+ | $limit =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$5/; | ||
+ | $failcnt =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$6/; | ||
+ | |||
+ | # 0=normal, 1=bytes, 2=pages | ||
+ | if ($ident eq "dummy") { | ||
+ | # do nothing, skip this line | ||
+ | } elsif ($ident =~ /pages/) { | ||
+ | &printline(2,$ident,$held,$maxheld,$barrier,$limit,$failcnt); | ||
+ | } elsif ($ident =~ /^num/) { | ||
+ | &printline(0,$ident,$held,$maxheld,$barrier,$limit,$failcnt); | ||
+ | } else { | ||
+ | &printline(1,$ident,$held,$maxheld,$barrier,$limit,$failcnt); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | sub print_header { | ||
+ | my $uid = shift; | ||
+ | |||
+ | print "#####################################################################################################################\n"; | ||
+ | print "BEANS FOR UID $uid\n"; | ||
+ | print "resource held maxheld barrier limit failcnt\n"; | ||
+ | } | ||
+ | |||
+ | # now eat your beans baby | ||
+ | while (<BEANS>) { | ||
+ | chomp($line = $_); | ||
+ | |||
+ | # skip processing of headline | ||
+ | if ($line =~ /^\s+uid/) { | ||
+ | # do nothing, skip this | ||
+ | } elsif ($line =~ /^Ver/) { | ||
+ | # do nothing, skip this | ||
+ | } elsif ($line =~ /^\s+\d+:\s+kmem/) { | ||
+ | $uid = $line; | ||
+ | $line =~ s/^(\s+)(\d+):/$1/; | ||
+ | $uid =~ s/^(\s+)(\d+):.*$/$2/; | ||
+ | &print_header($uid); | ||
+ | &work_line($line); | ||
+ | } else { | ||
+ | &work_line($line); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | close(BEANS); | ||
+ | </source> |
Revision as of 09:00, 18 September 2008
|
For newbies to openvz it is fairly difficult to understand the meaning of the numbers in /proc/user_beancounters file. Calculating the values to something understandable for human brain everytime you look at these statistics is much work. I have written a perl script which reformats the output to human-readable values in kbyte and mbyte.
Just be sure you have Perl installed on your HN/VE, copy this script to somewhere on your machine, give it executable rights and start it. The output will be like this:
BEANS FOR UID 254 resource held maxheld barrier limit failcnt kmemsize 15.14 mb 18.72 mb 150.30 mb 167.00 mb 0 lockedpages 0 0 16.00 mb 16.00 mb 0 privvmpages 433.79 mb 544.63 mb 2929.69 mb 3222.66 mb 0 shmpages 11.58 mb 11.64 mb 512.00 mb 512.00 mb 0 numproc 84 101 500 500 0 physpages 278.24 mb 395.75 mb 0 MAX_ULONG 0 vmguarpages 0 0 244.14 mb MAX_ULONG 0 oomguarpages 279.66 mb 396.98 mb 122.07 mb MAX_ULONG 0 numtcpsock 25 53 500 500 0 numflock 18 22 200 220 0 numpty 4 4 64 64 0 numsiginfo 0 11 512 512 0 tcpsndbuf 569.75 kb 679.25 kb 5.12 mb 10.00 mb 0 tcprcvbuf 400.00 kb 1.28 mb 5.12 mb 10.00 mb 0 othersockbuf 213.00 kb 284.25 kb 1.43 mb 3.88 mb 0 dgramrcvbuf 0.00 kb 8.25 kb 256.00 kb 256.00 kb 0 numothersock 155 175 500 500 0 dcachesize 619.68 kb 656.68 kb 4.00 mb 4.12 mb 0 numfile 2008 2397 9312 9312 0 numiptent 10 10 128 128 0
The script is the following, just copy and paste:
#!/usr/bin/perl
###############################################################################
# vzstats.pl
#
# this script reads /proc/user_beancounters on openvz HNs and VEs and displays
# the values in human-readable format (megabytes/kilobytes).
#
# The script can be distributed freely for everybody who finds it usable.
#
# Christian Anton <mail@christiananton.de> 2008-09-18
open(BEANS,"/proc/user_beancounters");
chomp ($arch = `uname -m`);
sub check_maxulong {
my $number = shift;
if ($arch eq "x86_64") {
if ($number == 9223372036854775807) {
return 1;
} else {
return undef;
}
} else {
if ($number == 2147483647) {
return 1;
} else {
return undef;
}
}
}
sub recalc_bytes {
my $bytes = shift;
if (defined(&check_maxulong($bytes))) { return "MAX_ULONG"; }
my $kbytes = $bytes / 1024;
my $ret;
# if over 1mb, show mb values
if ($kbytes > 1024) {
my $mbytes = $kbytes / 1024;
$ret = sprintf("%.2f", $mbytes) . " mb";
return $ret;
} else {
$ret = sprintf("%.2f", $kbytes) . " kb";
return $ret;
}
}
sub recalc_pages {
my $pages = shift;
if ($pages == 0) { return "0"; }
if (defined(&check_maxulong($pages))) { return "MAX_ULONG"; }
my $kbytes = $pages * 4;
my $ret;
if ($kbytes > 1024) {
my $mbytes = $kbytes / 1024;
$ret = sprintf("%.2f", $mbytes) . " mb";
return $ret;
} else {
$ret = sprintf("%.2f", $kbytes) . " kb";
return $ret;
}
}
sub recalc_nothing {
my $number = shift;
if (defined(&check_maxulong($number))) { return "MAX_ULONG"; }
return $number;
}
sub printline {
my $mode = shift; # 0=normal, 1=bytes, 2=pages
my $ident = shift;
my $held = shift;
my $maxheld = shift;
my $barrier = shift;
my $limit = shift;
my $failcnt = shift;
if ($mode == 0) {
printf ("%-15s",$ident);
printf ("%18s",&recalc_nothing($held));
printf ("%21s",&recalc_nothing($maxheld));
printf ("%21s",&recalc_nothing($barrier));
printf ("%21s",&recalc_nothing($limit));
printf ("%21s",$failcnt);
print "\n";
} elsif ($mode == 1) {
printf ("%-15s",$ident);
printf ("%18s",&recalc_bytes($held));
printf ("%21s",&recalc_bytes($maxheld));
printf ("%21s",&recalc_bytes($barrier));
printf ("%21s",&recalc_bytes($limit));
printf ("%21s",$failcnt);
print "\n";
} elsif ($mode == 2) {
printf ("%-15s",$ident);
printf ("%18s",&recalc_pages($held));
printf ("%21s",&recalc_pages($maxheld));
printf ("%21s",&recalc_pages($barrier));
printf ("%21s",&recalc_pages($limit));
printf ("%21s",$failcnt);
print "\n";
}
}
sub work_line {
my $line = shift;
my $ident = $line;
my $held = $line;
my $maxheld = $line;
my $barrier = $line;
my $limit = $line;
my $failcnt = $line;
$ident =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$1/;
$held =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$2/;
$maxheld =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$3/;
$barrier =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$4/;
$limit =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$5/;
$failcnt =~ s/^\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/$6/;
# 0=normal, 1=bytes, 2=pages
if ($ident eq "dummy") {
# do nothing, skip this line
} elsif ($ident =~ /pages/) {
&printline(2,$ident,$held,$maxheld,$barrier,$limit,$failcnt);
} elsif ($ident =~ /^num/) {
&printline(0,$ident,$held,$maxheld,$barrier,$limit,$failcnt);
} else {
&printline(1,$ident,$held,$maxheld,$barrier,$limit,$failcnt);
}
}
sub print_header {
my $uid = shift;
print "#####################################################################################################################\n";
print "BEANS FOR UID $uid\n";
print "resource held maxheld barrier limit failcnt\n";
}
# now eat your beans baby
while (<BEANS>) {
chomp($line = $_);
# skip processing of headline
if ($line =~ /^\s+uid/) {
# do nothing, skip this
} elsif ($line =~ /^Ver/) {
# do nothing, skip this
} elsif ($line =~ /^\s+\d+:\s+kmem/) {
$uid = $line;
$line =~ s/^(\s+)(\d+):/$1/;
$uid =~ s/^(\s+)(\d+):.*$/$2/;
&print_header($uid);
&work_line($line);
} else {
&work_line($line);
}
}
close(BEANS);