Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / virtualization / xen-multi @ e3899a30

Historique | Voir | Annoter | Télécharger (9,02 ko)

1 20afb679 Rapha?l HALIMI
#! /usr/bin/perl
2
3
# -*- perl -*-
4
5
=head1 NAME
6
7
xen_multi - Munin multigraph plugin to monitor Xen domains activity
8
9
=head1 APPLICABLE SYSTEMS
10
11
This plugin should work on any system running a Xen hypervisor and where xentop
12
is installed. It also needs Munin 1.4.0 or higher, since it uses AREASTACK
13
(available from 1.3.3) and multigraph (available from 1.4.0).
14
15
=head1 CONFIGURATION
16
17
xentop requires superuser privileges, so you need to include in your
18
configuration:
19
20 4a525a31 Niall Donegan
 [xen-multi]
21 20afb679 Rapha?l HALIMI
 user root
22 332c74d7 ivan
 env.xenskip "<space separated module list>"
23
24
Modules: cput, cpup, mem, disk, net
25 20afb679 Rapha?l HALIMI
26
Then restart munin-node and you're done.
27
28
=head1 INTERPRETATION
29
30
This plugin produces four different graphs: CPU usage, memory usage, disk IOs
31
and network traffic.
32
33
In each graph, all Xen domains (including dom0) have their data stacked, giving
34
an overall amount of ressources used.
35
36
NOTE: xentop always reports 0 for dom0's disk IOs and network traffic, but
37
both graphs show its entry all the same, so each domain can keep its own color
38
along the different graphs.
39
40 332c74d7 ivan
=head2 CPU time
41 20afb679 Rapha?l HALIMI
42
This graph shows a percentage of the CPU time used by each domain.
43
44 332c74d7 ivan
=head2 CPU usage
45
46
This graph shows a percentage of the CPU percentage used by each domain.
47
48 20afb679 Rapha?l HALIMI
=head2 Memory usage
49
50
This graph shows the amount of memory (in bytes) used by each domain.
51
52
=head2 Disk IOs
53
54
This graph shows the number of disk read and write operations for each domain.
55
56
=head2 Network traffic
57
58
This graph shows the amount of bits received and transmitted for each domain.
59
60
=head1 ACKNOWLEDGEMENTS
61
62
Michael Renner for the C<diskstats> plugin which I borrowed some code from.
63
64
=head1 VERSION
65
66
0.90
67
68
=head1 MAGIC MARKERS
69
70
  #%# family=auto
71
  #%# capabilities=autoconf
72
73
=head1 AUTHOR
74
75
Raphael HALIMI <raphael.halimi@gmail.com>
76 332c74d7 ivan
Modified by Krisztian IVANCSO <github-ivan@ivancso.net>
77 20afb679 Rapha?l HALIMI
78
=head1 LICENSE
79
80
GPLv2
81
82
=cut
83
84
use strict;
85 1e301c2d Alex Tomlins
use Munin::Plugin;
86 20afb679 Rapha?l HALIMI
87 332c74d7 ivan
my $XEN_SKIP = $ENV{xenskip} || "";
88
89 20afb679 Rapha?l HALIMI
# autoconf - quite simple
90
if ($ARGV[0] eq "autoconf") {
91
  if (`which xentop`) {
92
    print "yes\n";
93
  } else {
94
    print "no (xentop not found)\n";
95
  }
96
  exit 0;
97
}
98
99
100
#
101
# Common steps for both "config" and a normal run
102
#
103
104
#
105
# trim_label
106
#
107
# Trims a given label to it's non-wrapping size
108
# $type = 'pos' for normal graphs and 'neg' for mirror graphs
109
# pos: nnn.nnU_ times 4
110
# neg: nnn.nnU/nnn.nnU_ times 4
111
112
sub trim_label {
113
  my ($type, $label) = @_; my $data_characters;
114 332c74d7 ivan
  my ($graph_width, $graph_border_width, $padding_characters, $pixels_per_character) = (497,3,5,6);
115 20afb679 Rapha?l HALIMI
  if ($type eq 'pos') {$data_characters = 32;} elsif ($type eq 'neg') {$data_characters = 64;} else {return $label;}
116
117
  my $available_characters = abs(($graph_width+$graph_border_width)/$pixels_per_character)-$padding_characters-$data_characters;
118
119
  # If the label is longer than the available space, we write as many
120
  # characters as we can on both left and right, and two dots in the middle
121
  if ( $available_characters < length $label ) {
122
    my $center = ($available_characters-2)/2;
123
    $label = substr($label,0,($center)) . '..' . substr($label,-$center);
124
  }
125
126
  return $label;
127
}
128
129
# Global variables
130 332c74d7 ivan
my (%domains,$domain,@domainlist,$munindomain,$cpusecs,$cpupercent,$memk,$nettxk,$netrxk,$vbdrd,$vbdwr);
131 20afb679 Rapha?l HALIMI
132 332c74d7 ivan
open (XENTOP,"xentop -b -f -i2 |") or die "Could not execute xentop, $!";
133 20afb679 Rapha?l HALIMI
134
# Now we build a hash of hashes to store information
135 1e301c2d Alex Tomlins
while (<XENTOP>) {
136 20afb679 Rapha?l HALIMI
  # Some cleaning first
137
  s/^\s+//; chomp;
138 1e301c2d Alex Tomlins
  # Skip the headers
139
  next if /^NAME/;
140
141
  # We define only what we need
142 332c74d7 ivan
  ($domain,undef,$cpusecs,$cpupercent,$memk,undef,undef,undef,undef,undef,$nettxk,$netrxk,undef,undef,$vbdrd,$vbdwr,undef,undef,undef) = split(/\s+/);
143 1e301c2d Alex Tomlins
144
  # We have to store the sanitised domain name in a separate variable
145
  $domains{$domain}{'munindomain'} = clean_fieldname($domain);
146
147
  # We need the remaining data only for a normal run
148
  if ($ARGV[0] eq "") {
149
    $domains{$domain}{'cpusecs'} = $cpusecs;
150 332c74d7 ivan
    $domains{$domain}{'cpupercent'} = $cpupercent;
151 1e301c2d Alex Tomlins
    $domains{$domain}{'mem'} = $memk;
152
    $domains{$domain}{'nettx'} = $nettxk;
153
    $domains{$domain}{'netrx'} = $netrxk;
154
    $domains{$domain}{'vbdrd'} = $vbdrd;
155
    $domains{$domain}{'vbdwr'} = $vbdwr;
156 20afb679 Rapha?l HALIMI
  }
157
}
158
159 332c74d7 ivan
@domainlist = sort(keys(%domains));
160 20afb679 Rapha?l HALIMI
161
#
162
# config - quite simple, too
163
#
164
165
if ($ARGV[0] eq "config") {
166 332c74d7 ivan
  if ($XEN_SKIP !~ /cput/) {
167
		print "multigraph xen_cpu_time\n";
168
		print "graph_title Xen domains CPU time\n";
169
		print "graph_args --base 1000 -l 0\n";
170
		print "graph_vlabel cpu seconds\n";
171
		print "graph_scale no\n";
172 e3899a30 Gabriele Pohl
		print "graph_category Virtualization\n";
173 332c74d7 ivan
		print "graph_info This graph shows CPU time for each Xen domain.\n";
174
		for $domain (@domainlist) {
175
			print "$domains{$domain}{'munindomain'}_cpu_time.label ".trim_label('pos',$domain)."\n";
176
			print "$domains{$domain}{'munindomain'}_cpu_time.type DERIVE\n";
177
			print "$domains{$domain}{'munindomain'}_cpu_time.cdef $domains{$domain}{'munindomain'}_cpu_time,100,*\n";
178
			print "$domains{$domain}{'munindomain'}_cpu_time.min 0\n";
179
			print "$domains{$domain}{'munindomain'}_cpu_time.draw AREASTACK\n";
180
		}
181 20afb679 Rapha?l HALIMI
  }
182
183 332c74d7 ivan
  if ($XEN_SKIP !~ /cpup/) {
184
		print "\nmultigraph xen_cpu\n";
185
		print "graph_title Xen domains CPU utilization\n";
186
		print "graph_args --base 1000 -l 0 --upper-limit 100\n";
187
		print "graph_vlabel %\n";
188
		print "graph_scale no\n";
189 e3899a30 Gabriele Pohl
		print "graph_category Virtualization\n";
190 332c74d7 ivan
		print "graph_info This graph shows CPU utilization for each Xen domain.\n";
191
		for $domain (@domainlist) {
192
			print "$domains{$domain}{'munindomain'}_cpu.label ".trim_label('pos',$domain)."\n";
193
			print "$domains{$domain}{'munindomain'}_cpu.draw AREASTACK\n"
194
		}
195 20afb679 Rapha?l HALIMI
  }
196
197 332c74d7 ivan
  if ($XEN_SKIP !~ /mem/) {
198
		print "\nmultigraph xen_mem\n";
199
		print "graph_title Xen domains memory usage\n";
200
		print "graph_args --base 1024 -l 0\n";
201
		print "graph_vlabel bytes\n";
202 e3899a30 Gabriele Pohl
		print "graph_category Virtualization\n";
203 332c74d7 ivan
		print "graph_info This graph shows memory usage for each Xen domain.\n";
204
		for $domain (@domainlist) {
205
			print "$domains{$domain}{'munindomain'}_mem.label ".trim_label('pos',$domain)."\n";
206
			print "$domains{$domain}{'munindomain'}_mem.cdef $domains{$domain}{'munindomain'}_mem,1024,*\n";
207
			print "$domains{$domain}{'munindomain'}_mem.draw AREASTACK\n";
208
		}
209 20afb679 Rapha?l HALIMI
  }
210
211 332c74d7 ivan
  if ($XEN_SKIP !~ /net/) {
212
		print "\nmultigraph xen_net\n";
213
		print "graph_title Xen domains network traffic\n";
214
		print "graph_args --base 1000\n";
215
		print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n";
216 e3899a30 Gabriele Pohl
		print "graph_category Virtualization\n";
217 332c74d7 ivan
		print "graph_info This graph shows network traffic for each Xen domain.\n";
218
		for $domain (@domainlist) {
219
			print "$domains{$domain}{'munindomain'}_netrx.label none\n";
220
			print "$domains{$domain}{'munindomain'}_netrx.cdef $domains{$domain}{'munindomain'}_netrx,8192,*\n";
221
			print "$domains{$domain}{'munindomain'}_netrx.type COUNTER\n";
222
			print "$domains{$domain}{'munindomain'}_netrx.graph no\n";
223
			print "$domains{$domain}{'munindomain'}_nettx.label ".trim_label('neg',$domain)."\n";
224
			print "$domains{$domain}{'munindomain'}_nettx.cdef $domains{$domain}{'munindomain'}_nettx,8192,*\n";
225
			print "$domains{$domain}{'munindomain'}_nettx.type COUNTER\n";
226
			print "$domains{$domain}{'munindomain'}_nettx.draw AREASTACK\n";
227
			print "$domains{$domain}{'munindomain'}_nettx.negative $domains{$domain}{'munindomain'}_netrx\n";
228
		}
229
  }
230
231
  if ($XEN_SKIP !~ /disk/) {
232
		print "\nmultigraph xen_disk\n";
233
		print "graph_title Xen domains disk IOs\n";
234
		print "graph_args --base 1000\n";
235
		print "graph_vlabel IOs per \${graph_period} read (-) / write (+)\n";
236 e3899a30 Gabriele Pohl
		print "graph_category Virtualization\n";
237 332c74d7 ivan
		print "graph_info This graph shows disk IOs for each Xen domain.\n";
238
		for $domain (@domainlist) {
239
			print "$domains{$domain}{'munindomain'}_vbdrd.label none\n";
240
			print "$domains{$domain}{'munindomain'}_vbdrd.type COUNTER\n";
241
			print "$domains{$domain}{'munindomain'}_vbdrd.graph no\n";
242
			print "$domains{$domain}{'munindomain'}_vbdwr.label ".trim_label('neg',$domain)."\n";
243
			print "$domains{$domain}{'munindomain'}_vbdwr.type COUNTER\n";
244
			print "$domains{$domain}{'munindomain'}_vbdwr.draw AREASTACK\n";
245
			print "$domains{$domain}{'munindomain'}_vbdwr.negative $domains{$domain}{'munindomain'}_vbdrd\n";
246
		}
247 20afb679 Rapha?l HALIMI
  }
248
249
  exit 0;
250
}
251
252
253
#
254
# Normal run
255
#
256
257 332c74d7 ivan
if ($XEN_SKIP !~ /cput/) {
258
	print "multigraph xen_cpu_time\n";
259
	for $domain (@domainlist) {
260
		print "$domains{$domain}{'munindomain'}_cpu_time.value $domains{$domain}{'cpusecs'}\n";
261
	}
262 20afb679 Rapha?l HALIMI
}
263
264 332c74d7 ivan
if ($XEN_SKIP !~ /cpup/) {
265
	print "\nmultigraph xen_cpu\n";
266
	for $domain (@domainlist) {
267
		print "$domains{$domain}{'munindomain'}_cpu.value $domains{$domain}{'cpupercent'}\n";
268
	}
269 20afb679 Rapha?l HALIMI
}
270
271 332c74d7 ivan
if ($XEN_SKIP !~ /mem/) {
272
	print "\nmultigraph xen_mem\n";
273
	for $domain (@domainlist) {
274
		print "$domains{$domain}{'munindomain'}_mem.value $domains{$domain}{'mem'}\n";
275
	}
276 20afb679 Rapha?l HALIMI
}
277
278 332c74d7 ivan
if ($XEN_SKIP !~ /net/) {
279
	print "\nmultigraph xen_net\n";
280
	for $domain (@domainlist) {
281
		print "$domains{$domain}{'munindomain'}_nettx.value $domains{$domain}{'nettx'}\n";
282
		print "$domains{$domain}{'munindomain'}_netrx.value $domains{$domain}{'netrx'}\n";
283
	}
284 20afb679 Rapha?l HALIMI
}
285 332c74d7 ivan
286
if ($XEN_SKIP !~ /disk/) {
287
	print "\nmultigraph xen_disk\n";
288
	for $domain (@domainlist) {
289
		print "$domains{$domain}{'munindomain'}_vbdrd.value $domains{$domain}{'vbdrd'}\n";
290
		print "$domains{$domain}{'munindomain'}_vbdwr.value $domains{$domain}{'vbdwr'}\n";
291
	}
292
}