summaryrefslogtreecommitdiff
path: root/files/plugins/xen_cpu
blob: 382c8b53e751b9e70feeff1b88bdd7f33abaef4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/perl -w
#
# xen_cpu_v2.pl 1.00
# Script to minitor the CPU usage of Xen domains
# Zoltan HERPAI (c) 2009, wigyori@uid0.hu
#
# Based loosely on Adam Crews' xen_cpu script
#
# This script tries to measure the CPU usage of the Xen guests
# accurately. 
# The problem with the current monitoring script is that these 
# scripts use the CPU output of xentop or xm list, which might be
# inaccurate due to the resources used up at the time of the query by
# the xm or xentop command.
#
# This script stores the previous value of the CPU sec value of the given
# guests in a tempfile, then does some simple calculations to get the real
# CPU usage percentage of the guests.
#

#%# family=auto
#%# capabilities=autoconf

use strict;
use POSIX;

# Define where to find xm tools
my $XM = '/usr/sbin/xm';
my $XMTOP = '/usr/sbin/xentop';
my $curtime = time();
my $basename = `/usr/bin/env basename $0`; chop ($basename);
my $TEMPFILE = "/tmp/$basename";

my $debug = 0;

##############
# You should not need to edit anything below here
#

$ENV{PATH} = '/bin:/usr/bin:/usr/sbin';

my $arg;
if ( defined($ARGV[0]) )
{
	if ( $ARGV[0] eq 'config' )
	{
		$arg = 'config';
	}
	if ( $ARGV[0] eq 'autoconf' )
	{
		$arg = 'autoconf';
	}
	
	if ( $arg eq 'autoconf')
	{
		if ( -e $XM && -e $XMTOP )
		{
			print "yes\n";
			exit 0;
		}
		else
		{
			print "no ($XM and/or $XMTOP not found\n";
			exit 1;
		}
	}

	if ( $arg eq 'config' )
	{
		my %cnf;
		%cnf = (
			'graph_title' => 'Xen Domain CPU Usage v2',
			'graph_args' => '--base 1000 -l 0 --upper-limit 100 --rigid',
			'graph_vlabel' => 'Percent (%)',
			'graph_category' => 'xen',
			'graph_info' => 'Display the % of CPU Usage for each domain',
		);

		my @domains = `$XM list`;
		my $cnt = 0;
		shift(@domains); # we dont need the header line
		foreach my $domain ( @domains )
		{
			my ($dom,undef) = split(/\s/, $domain, 2);
			$dom =~ s/[-.]/_/g;
			$cnf{ "$dom" . '.label' } = "$dom";
			$cnf{ "$dom" . '.draw' } = 'STACK';
			$cnf{ "$dom" . '.min' } = '0';
			$cnf{ "$dom" . '.max' } = '100';
			$cnf{ "$dom" . '.info' } = '% CPU used for ' . "$dom";
#			$cnf{ "$dom" . '.draw' } = 'AREA';
			if ( $cnt == 0 )
			{
				$cnf{ "$dom" . '.draw' } = 'AREA';
			}
			$cnt++;
		}
		foreach my $key (sort(keys(%cnf)))
		{
			print "$key $cnf{$key}\n";
		}
		exit 0;
	}
}
	
my @xmlist = `$XM list`;
shift (@xmlist);

my %dom; my $name; my $oldtime;
# Read old data
if ( -e $TEMPFILE )
{
	open(FH, "<", $TEMPFILE) or die $!;
	$oldtime = <FH>;

	if ( $debug )
	{
		print "Oldtime: $oldtime\n";
	}

	while (<FH>)
	{
		# Get the guest name and its CPU usage, and store it in $dom
		$_ =~ /(\S+)\s+\S+\s+\S+\s+\d+\s+\S+\s+(\S+)/;
		$dom{$1}->{'oldtime'} = $2;
	}
	
	close FH;
}

my $diff; my $cpusum = 0;
foreach my $domain ( @xmlist )
{
	# Get the domains' name and current CPU usage, store it in $dom
	$domain =~ /(\S+)\s+\S+\s+\S+\s+\d+\s+\S+\s+(\S+)/;
	$dom{$1}->{'newtime'} = $2;

	$diff = $dom{$1}->{'newtime'} - $dom{$1}->{'oldtime'};
	$diff = sprintf("%.2f", $diff);
	
	# Calc the diff between old and new cputime, or reset the counter
	if ( $diff < 0 )
	{
		$diff = $dom{$1}->{'newtime'};
	}
	$dom{$1}->{'diff'} = $diff;
	
	# Calc a sum CPU usage
	$cpusum = $cpusum + $diff;
}

my $numcpus = `$XM info |grep nr_cpus |cut -d \: -f 2`;
my $timediff = $curtime - $oldtime;
my $tcpuavail = $numcpus * $timediff;

if ( $debug )
{
	print "UsedCPUtime sum: $cpusum\n";
	print "CPUs: $numcpus\n";
	print "Timediff: $timediff\n";
	print "Total CPU time available: $tcpuavail\n";
}

my $key; my $value;
while (($key, $value) = each %dom)
{
	# Calc a percentage based on the used CPU time sum
	my $tmp = 0;
	$tmp = ( $dom{$key}->{'diff'} / $cpusum ) * 100;
	$dom{$key}->{'pc_time'} = sprintf("%.2f", $tmp);
	
	# Calc a percentage based on the _total_ available CPU time
	$tmp = 0;
	$tmp = ( $dom{$key}->{'diff'} / $tcpuavail ) * 100;
	$dom{$key}->{'pc_tcpu'} = sprintf("%.2f", $tmp);
	
	if ( $debug )
	{
		print "$key newtime: ".$dom{$key}->{'newtime'}.", oldtime: ".$dom{$key}->{'oldtime'}.", diff: ".$dom{$key}->{'diff'}.", pc_bytime ".$dom{$key}->{'pc_time'}.", pc_bytcpu ".$dom{$key}->{'pc_tcpu'}."\n";
	}
	print "$key.value ".$dom{$key}->{'pc_tcpu'}."\n";
}

# We'll need to log out the current "xm list" output, and the current time also.
open(FH, ">", $TEMPFILE) or die $!;
print FH $curtime."\n";
print FH @xmlist;
close FH;