Projet

Général

Profil

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

root / plugins / virtualization / xen-multi @ c5ab6538

Historique | Voir | Annoter | Télécharger (7,73 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 ad4d9724 Niall Donegan
    print "$domains{$domain}{'munindomain'}_cpu_time.type DERIVE\n";
164 1e301c2d Alex Tomlins
    print "$domains{$domain}{'munindomain'}_cpu_time.cdef $domains{$domain}{'munindomain'}_cpu_time,100,*\n";
165 ad4d9724 Niall Donegan
    print "$domains{$domain}{'munindomain'}_cpu_time.min 0\n";
166 1e301c2d Alex Tomlins
    print "$domains{$domain}{'munindomain'}_cpu_time.draw AREASTACK\n";
167 20afb679 Rapha?l HALIMI
  }
168
169
  print "\nmultigraph xen_mem\n";
170
  print "graph_title Xen domains memory usage\n";
171
  print "graph_args --base 1024 -l 0\n";
172
  print "graph_vlabel bytes\n";
173
  print "graph_category xen\n";
174
  print "graph_info This graph shows memory usage for each Xen domain.\n";
175
  for $domain (sort(keys(%domains))) {
176
    print "$domains{$domain}{'munindomain'}_mem.label ".trim_label('pos',$domain)."\n";
177
    print "$domains{$domain}{'munindomain'}_mem.cdef $domains{$domain}{'munindomain'}_mem,1024,*\n";
178
    print "$domains{$domain}{'munindomain'}_mem.draw AREASTACK\n";
179
  }
180
181
  print "\nmultigraph xen_net\n";
182
  print "graph_title Xen domains network traffic\n";
183
  print "graph_args --base 1000\n";
184
  print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n";
185
  print "graph_category xen\n";
186
  print "graph_info This graph shows network traffic for each Xen domain.\n";
187
  for $domain (sort(keys(%domains))) {
188
    print "$domains{$domain}{'munindomain'}_netrx.label none\n";
189
    print "$domains{$domain}{'munindomain'}_netrx.cdef $domains{$domain}{'munindomain'}_netrx,8192,*\n";
190
    print "$domains{$domain}{'munindomain'}_netrx.type COUNTER\n";
191
    print "$domains{$domain}{'munindomain'}_netrx.graph no\n";
192
    print "$domains{$domain}{'munindomain'}_nettx.label ".trim_label('neg',$domain)."\n";
193
    print "$domains{$domain}{'munindomain'}_nettx.cdef $domains{$domain}{'munindomain'}_nettx,8192,*\n";
194
    print "$domains{$domain}{'munindomain'}_nettx.type COUNTER\n";
195
    print "$domains{$domain}{'munindomain'}_nettx.draw AREASTACK\n";
196
    print "$domains{$domain}{'munindomain'}_nettx.negative $domains{$domain}{'munindomain'}_netrx\n";
197
  }
198
199
  print "\nmultigraph xen_disk\n";
200
  print "graph_title Xen domains disk IOs\n";
201
  print "graph_args --base 1000\n";
202
  print "graph_vlabel IOs per \${graph_period} read (-) / write (+)\n";
203
  print "graph_category xen\n";
204
  print "graph_info This graph shows disk IOs for each Xen domain.\n";
205
  for $domain (sort(keys(%domains))) {
206
    print "$domains{$domain}{'munindomain'}_vbdrd.label none\n";
207
    print "$domains{$domain}{'munindomain'}_vbdrd.type COUNTER\n";
208
    print "$domains{$domain}{'munindomain'}_vbdrd.graph no\n";
209
    print "$domains{$domain}{'munindomain'}_vbdwr.label ".trim_label('neg',$domain)."\n";
210
    print "$domains{$domain}{'munindomain'}_vbdwr.type COUNTER\n";
211
    print "$domains{$domain}{'munindomain'}_vbdwr.draw AREASTACK\n";
212
    print "$domains{$domain}{'munindomain'}_vbdwr.negative $domains{$domain}{'munindomain'}_vbdrd\n";
213
  }
214
215
  exit 0;
216
}
217
218
219
#
220
# Normal run
221
#
222
223 1e301c2d Alex Tomlins
print "multigraph xen_cpu_time\n";
224 20afb679 Rapha?l HALIMI
for $domain (sort(keys(%domains))) {
225 1e301c2d Alex Tomlins
  print "$domains{$domain}{'munindomain'}_cpu_time.value $domains{$domain}{'cpusecs'}\n";
226 20afb679 Rapha?l HALIMI
}
227
228
print "\nmultigraph xen_mem\n";
229
for $domain (sort(keys(%domains))) {
230
  print "$domains{$domain}{'munindomain'}_mem.value $domains{$domain}{'mem'}\n";
231
}
232
233
print "\nmultigraph xen_net\n";
234
for $domain (sort(keys(%domains))) {
235
  print "$domains{$domain}{'munindomain'}_nettx.value $domains{$domain}{'nettx'}\n";
236
  print "$domains{$domain}{'munindomain'}_netrx.value $domains{$domain}{'netrx'}\n";
237
}
238
239
print "\nmultigraph xen_disk\n";
240
for $domain (sort(keys(%domains))) {
241
  print "$domains{$domain}{'munindomain'}_vbdrd.value $domains{$domain}{'vbdrd'}\n";
242
  print "$domains{$domain}{'munindomain'}_vbdwr.value $domains{$domain}{'vbdwr'}\n";
243
}