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
#! /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
 [xen-multi]
21
 user root
22
 env.xenskip "<space separated module list>"
23

    
24
Modules: cput, cpup, mem, disk, net
25

    
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
=head2 CPU time
41

    
42
This graph shows a percentage of the CPU time used by each domain.
43

    
44
=head2 CPU usage
45

    
46
This graph shows a percentage of the CPU percentage used by each domain.
47

    
48
=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
Modified by Krisztian IVANCSO <github-ivan@ivancso.net>
77

    
78
=head1 LICENSE
79

    
80
GPLv2
81

    
82
=cut
83

    
84
use strict;
85
use Munin::Plugin;
86

    
87
my $XEN_SKIP = $ENV{xenskip} || "";
88

    
89
# 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
  my ($graph_width, $graph_border_width, $padding_characters, $pixels_per_character) = (497,3,5,6);
115
  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
my (%domains,$domain,@domainlist,$munindomain,$cpusecs,$cpupercent,$memk,$nettxk,$netrxk,$vbdrd,$vbdwr);
131

    
132
open (XENTOP,"xentop -b -f -i2 |") or die "Could not execute xentop, $!";
133

    
134
# Now we build a hash of hashes to store information
135
while (<XENTOP>) {
136
  # Some cleaning first
137
  s/^\s+//; chomp;
138
  # Skip the headers
139
  next if /^NAME/;
140

    
141
  # We define only what we need
142
  ($domain,undef,$cpusecs,$cpupercent,$memk,undef,undef,undef,undef,undef,$nettxk,$netrxk,undef,undef,$vbdrd,$vbdwr,undef,undef,undef) = split(/\s+/);
143

    
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
    $domains{$domain}{'cpupercent'} = $cpupercent;
151
    $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
  }
157
}
158

    
159
@domainlist = sort(keys(%domains));
160

    
161
#
162
# config - quite simple, too
163
#
164

    
165
if ($ARGV[0] eq "config") {
166
  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
		print "graph_category Virtualization\n";
173
		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
  }
182

    
183
  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
		print "graph_category Virtualization\n";
190
		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
  }
196

    
197
  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
		print "graph_category Virtualization\n";
203
		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
  }
210

    
211
  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
		print "graph_category Virtualization\n";
217
		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
		print "graph_category Virtualization\n";
237
		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
  }
248

    
249
  exit 0;
250
}
251

    
252

    
253
#
254
# Normal run
255
#
256

    
257
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
}
263

    
264
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
}
270

    
271
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
}
277

    
278
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
}
285

    
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
}
293