Projet

Général

Profil

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

root / plugins / virtualization / xen-multi @ e5ce7492

Historique | Voir | Annoter | Télécharger (7,67 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
23
Then restart munin-node and you're done.
24
25
=head1 INTERPRETATION
26
27
This plugin produces four different graphs: CPU usage, memory usage, disk IOs
28
and network traffic.
29
30
In each graph, all Xen domains (including dom0) have their data stacked, giving
31
an overall amount of ressources used.
32
33
NOTE: xentop always reports 0 for dom0's disk IOs and network traffic, but
34
both graphs show its entry all the same, so each domain can keep its own color
35
along the different graphs.
36
37
=head2 CPU usage
38
39
This graph shows a percentage of the CPU time used by each domain.
40
41
=head2 Memory usage
42
43
This graph shows the amount of memory (in bytes) used by each domain.
44
45
=head2 Disk IOs
46
47
This graph shows the number of disk read and write operations for each domain.
48
49
=head2 Network traffic
50
51
This graph shows the amount of bits received and transmitted for each domain.
52
53
=head1 ACKNOWLEDGEMENTS
54
55
Michael Renner for the C<diskstats> plugin which I borrowed some code from.
56
57
=head1 VERSION
58
59
0.90
60
61
=head1 MAGIC MARKERS
62
63
  #%# family=auto
64
  #%# capabilities=autoconf
65
66
=head1 AUTHOR
67
68
Raphael HALIMI <raphael.halimi@gmail.com>
69
70
=head1 LICENSE
71
72
GPLv2
73
74
=cut
75
76
use strict;
77 1e301c2d Alex Tomlins
use Munin::Plugin;
78 20afb679 Rapha?l HALIMI
79
# autoconf - quite simple
80
if ($ARGV[0] eq "autoconf") {
81
  if (`which xentop`) {
82
    print "yes\n";
83
  } else {
84
    print "no (xentop not found)\n";
85
  }
86
  exit 0;
87
}
88
89
90
#
91
# Common steps for both "config" and a normal run
92
#
93
94
#
95
# trim_label
96
#
97
# Trims a given label to it's non-wrapping size
98
# $type = 'pos' for normal graphs and 'neg' for mirror graphs
99
# pos: nnn.nnU_ times 4
100
# neg: nnn.nnU/nnn.nnU_ times 4
101
102
sub trim_label {
103
  my ($type, $label) = @_; my $data_characters;
104
  my ($graph_width, $graph_border_width, $padding_characters, $pixels_per_character) = (400,97,10,6);
105
  if ($type eq 'pos') {$data_characters = 32;} elsif ($type eq 'neg') {$data_characters = 64;} else {return $label;}
106
107
  my $available_characters = abs(($graph_width+$graph_border_width)/$pixels_per_character)-$padding_characters-$data_characters;
108
109
  # If the label is longer than the available space, we write as many
110
  # characters as we can on both left and right, and two dots in the middle
111
  if ( $available_characters < length $label ) {
112
    my $center = ($available_characters-2)/2;
113
    $label = substr($label,0,($center)) . '..' . substr($label,-$center);
114
  }
115
116
  return $label;
117
}
118
119
# Global variables
120 1e301c2d Alex Tomlins
my (%domains,$domain,$munindomain,$cpusecs,$memk,$nettxk,$netrxk,$vbdrd,$vbdwr);
121 20afb679 Rapha?l HALIMI
122 1e301c2d Alex Tomlins
open (XENTOP,"xentop -b -f -i1 |") or die "Could not execute xentop, $!";
123 20afb679 Rapha?l HALIMI
124
# Now we build a hash of hashes to store information
125 1e301c2d Alex Tomlins
while (<XENTOP>) {
126 20afb679 Rapha?l HALIMI
  # Some cleaning first
127
  s/^\s+//; chomp;
128 1e301c2d Alex Tomlins
  # Skip the headers
129
  next if /^NAME/;
130
131
  # We define only what we need
132
  ($domain,undef,$cpusecs,undef,$memk,undef,undef,undef,undef,undef,$nettxk,$netrxk,undef,undef,$vbdrd,$vbdwr,undef,undef,undef) = split(/\s+/);
133
134
  # We have to store the sanitised domain name in a separate variable
135
  $domains{$domain}{'munindomain'} = clean_fieldname($domain);
136
137
  # We need the remaining data only for a normal run
138
  if ($ARGV[0] eq "") {
139
    $domains{$domain}{'cpusecs'} = $cpusecs;
140
    $domains{$domain}{'mem'} = $memk;
141
    $domains{$domain}{'nettx'} = $nettxk;
142
    $domains{$domain}{'netrx'} = $netrxk;
143
    $domains{$domain}{'vbdrd'} = $vbdrd;
144
    $domains{$domain}{'vbdwr'} = $vbdwr;
145 20afb679 Rapha?l HALIMI
  }
146
}
147
148
149
#
150
# config - quite simple, too
151
#
152
153
if ($ARGV[0] eq "config") {
154 1e301c2d Alex Tomlins
  print "multigraph xen_cpu_time\n";
155
  print "graph_title Xen domains CPU time\n";
156
  print "graph_args --base 1000 -l 0\n";
157 20afb679 Rapha?l HALIMI
  print "graph_vlabel %\n";
158
  print "graph_scale no\n";
159
  print "graph_category xen\n";
160 1e301c2d Alex Tomlins
  print "graph_info This graph shows CPU time for each Xen domain.\n";
161 20afb679 Rapha?l HALIMI
  for $domain (sort(keys(%domains))) {
162 1e301c2d Alex Tomlins
    print "$domains{$domain}{'munindomain'}_cpu_time.label ".trim_label('pos',$domain)."\n";
163
    print "$domains{$domain}{'munindomain'}_cpu_time.type COUNTER\n";
164
    print "$domains{$domain}{'munindomain'}_cpu_time.cdef $domains{$domain}{'munindomain'}_cpu_time,100,*\n";
165
    print "$domains{$domain}{'munindomain'}_cpu_time.draw AREASTACK\n";
166 20afb679 Rapha?l HALIMI
  }
167
168
  print "\nmultigraph xen_mem\n";
169
  print "graph_title Xen domains memory usage\n";
170
  print "graph_args --base 1024 -l 0\n";
171
  print "graph_vlabel bytes\n";
172
  print "graph_category xen\n";
173
  print "graph_info This graph shows memory usage for each Xen domain.\n";
174
  for $domain (sort(keys(%domains))) {
175
    print "$domains{$domain}{'munindomain'}_mem.label ".trim_label('pos',$domain)."\n";
176
    print "$domains{$domain}{'munindomain'}_mem.cdef $domains{$domain}{'munindomain'}_mem,1024,*\n";
177
    print "$domains{$domain}{'munindomain'}_mem.draw AREASTACK\n";
178
  }
179
180
  print "\nmultigraph xen_net\n";
181
  print "graph_title Xen domains network traffic\n";
182
  print "graph_args --base 1000\n";
183
  print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n";
184
  print "graph_category xen\n";
185
  print "graph_info This graph shows network traffic for each Xen domain.\n";
186
  for $domain (sort(keys(%domains))) {
187
    print "$domains{$domain}{'munindomain'}_netrx.label none\n";
188
    print "$domains{$domain}{'munindomain'}_netrx.cdef $domains{$domain}{'munindomain'}_netrx,8192,*\n";
189
    print "$domains{$domain}{'munindomain'}_netrx.type COUNTER\n";
190
    print "$domains{$domain}{'munindomain'}_netrx.graph no\n";
191
    print "$domains{$domain}{'munindomain'}_nettx.label ".trim_label('neg',$domain)."\n";
192
    print "$domains{$domain}{'munindomain'}_nettx.cdef $domains{$domain}{'munindomain'}_nettx,8192,*\n";
193
    print "$domains{$domain}{'munindomain'}_nettx.type COUNTER\n";
194
    print "$domains{$domain}{'munindomain'}_nettx.draw AREASTACK\n";
195
    print "$domains{$domain}{'munindomain'}_nettx.negative $domains{$domain}{'munindomain'}_netrx\n";
196
  }
197
198
  print "\nmultigraph xen_disk\n";
199
  print "graph_title Xen domains disk IOs\n";
200
  print "graph_args --base 1000\n";
201
  print "graph_vlabel IOs per \${graph_period} read (-) / write (+)\n";
202
  print "graph_category xen\n";
203
  print "graph_info This graph shows disk IOs for each Xen domain.\n";
204
  for $domain (sort(keys(%domains))) {
205
    print "$domains{$domain}{'munindomain'}_vbdrd.label none\n";
206
    print "$domains{$domain}{'munindomain'}_vbdrd.type COUNTER\n";
207
    print "$domains{$domain}{'munindomain'}_vbdrd.graph no\n";
208
    print "$domains{$domain}{'munindomain'}_vbdwr.label ".trim_label('neg',$domain)."\n";
209
    print "$domains{$domain}{'munindomain'}_vbdwr.type COUNTER\n";
210
    print "$domains{$domain}{'munindomain'}_vbdwr.draw AREASTACK\n";
211
    print "$domains{$domain}{'munindomain'}_vbdwr.negative $domains{$domain}{'munindomain'}_vbdrd\n";
212
  }
213
214
  exit 0;
215
}
216
217
218
#
219
# Normal run
220
#
221
222 1e301c2d Alex Tomlins
print "multigraph xen_cpu_time\n";
223 20afb679 Rapha?l HALIMI
for $domain (sort(keys(%domains))) {
224 1e301c2d Alex Tomlins
  print "$domains{$domain}{'munindomain'}_cpu_time.value $domains{$domain}{'cpusecs'}\n";
225 20afb679 Rapha?l HALIMI
}
226
227
print "\nmultigraph xen_mem\n";
228
for $domain (sort(keys(%domains))) {
229
  print "$domains{$domain}{'munindomain'}_mem.value $domains{$domain}{'mem'}\n";
230
}
231
232
print "\nmultigraph xen_net\n";
233
for $domain (sort(keys(%domains))) {
234
  print "$domains{$domain}{'munindomain'}_nettx.value $domains{$domain}{'nettx'}\n";
235
  print "$domains{$domain}{'munindomain'}_netrx.value $domains{$domain}{'netrx'}\n";
236
}
237
238
print "\nmultigraph xen_disk\n";
239
for $domain (sort(keys(%domains))) {
240
  print "$domains{$domain}{'munindomain'}_vbdrd.value $domains{$domain}{'vbdrd'}\n";
241
  print "$domains{$domain}{'munindomain'}_vbdwr.value $domains{$domain}{'vbdwr'}\n";
242
}