Open main menu

OpenVZ Virtuozzo Containers Wiki β

Human readable user beancounters

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 |_at_| 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);