Révision cb21db87
update view data; make everything work via vCenter too; add option to flatten the view to allow moving of VMs between hosts without breaking the VM graphs
| plugins/vmware/esx_ | ||
|---|---|---|
| 1 | 1 |
#!/usr/bin/perl -w |
| 2 |
# |
|
| 3 |
# -== Munin plugin for VMware ESXi/vSphere monitoring ==- |
|
| 4 |
# |
|
| 5 |
# Copyright (c) 2012 - Stefan Seidel <munin@stefanseidel.info> |
|
| 6 |
# |
|
| 7 |
# This program is free software: you can redistribute it and/or modify |
|
| 8 |
# it under the terms of the GNU General Public License as published by |
|
| 9 |
# the Free Software Foundation, either version 3 of the License, or |
|
| 10 |
# (at your option) any later version. |
|
| 11 |
# |
|
| 12 |
# This program is distributed in the hope that it will be useful, |
|
| 13 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 15 |
# GNU General Public License for more details. |
|
| 16 |
# |
|
| 17 |
# You should have received a copy of the GNU General Public License |
|
| 18 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
| 19 |
# |
|
| 20 |
# |
|
| 21 |
# This plugin uses the vSphere SDK for Perl available at |
|
| 22 |
# http://www.vmware.com/support/developer/viperltoolkit/ |
|
| 23 |
# or included in the vSphere CLI available at |
|
| 24 |
# http://www.vmware.com/support/developer/vcli/ |
|
| 25 |
# The use of the SDK is subject to the terms and condition |
|
| 26 |
# of VMware, Inc. to which you must agree upon installation. |
|
| 27 |
# |
|
| 28 |
|
|
| 29 |
|
|
| 30 |
# |
|
| 31 |
# -== Usage ==- |
|
| 32 |
# Put this file in /usr/share/munin/plugins, `chmod +x` it and |
|
| 33 |
# `ln -s` it to /etc/munin/plugins/esx_<hostname of server to monitor> |
|
| 34 |
# |
|
| 2 |
=HEADER |
|
| 3 |
-== Munin plugin for VMware ESXi/vSphere monitoring ==- |
|
| 4 |
|
|
| 5 |
Copyright (c) 2012 - Stefan Seidel <munin@stefanseidel.info> |
|
| 6 |
|
|
| 7 |
This program is free software: you can redistribute it and/or modify |
|
| 8 |
it under the terms of the GNU General Public License as published by |
|
| 9 |
the Free Software Foundation, either version 3 of the License, or |
|
| 10 |
(at your option) any later version. |
|
| 11 |
|
|
| 12 |
This program is distributed in the hope that it will be useful, |
|
| 13 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 14 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 15 |
GNU General Public License for more details. |
|
| 16 |
|
|
| 17 |
You should have received a copy of the GNU General Public License |
|
| 18 |
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
| 19 |
|
|
| 20 |
|
|
| 21 |
This plugin uses the vSphere SDK for Perl available at |
|
| 22 |
http://www.vmware.com/support/developer/viperltoolkit/ |
|
| 23 |
or included in the vSphere CLI available at |
|
| 24 |
http://www.vmware.com/support/developer/vcli/ |
|
| 25 |
The use of the SDK is subject to the terms and condition |
|
| 26 |
of VMware, Inc. to which you must agree upon installation. |
|
| 27 |
=cut |
|
| 28 |
|
|
| 29 |
=USAGE |
|
| 30 |
-== Usage ==- |
|
| 31 |
Put this file in /usr/share/munin/plugins, `chmod +x` it and |
|
| 32 |
`ln -s` it to /etc/munin/plugins/esx_<hostname of server to monitor> |
|
| 33 |
Add a file "esx_" /etc/munin/plugin-conf.d with content like this |
|
| 34 |
(omit the "# " at the beginning of each line) |
|
| 35 |
|
|
| 36 |
---- snip ---- |
|
| 37 |
[esx_*] |
|
| 38 |
timeout 60 |
|
| 39 |
env.user <username on ESX server or vCenter> |
|
| 40 |
env.password <password of user on ESX server or vCenter> |
|
| 41 |
---- snip ---- |
|
| 42 |
|
|
| 43 |
Then you need to add this host to your munin.conf on the munin server |
|
| 44 |
(often this is the same as your munin node, i.e. this host) and restart |
|
| 45 |
munin-node, and wait for the data to populate. |
|
| 46 |
|
|
| 47 |
|
|
| 48 |
-== Graphs don't render ==- |
|
| 49 |
Munin 1.4 has a bug with complex multigraphs like this, see |
|
| 50 |
http://munin-monitoring.org/ticket/1224 for details and a fix if |
|
| 51 |
your graphs don't render! |
|
| 52 |
|
|
| 53 |
|
|
| 54 |
-== Option flatview ==- |
|
| 55 |
There is an option to render all VMs and Host Systems in a flat |
|
| 56 |
structure, i.e. not rendering VMs as sub-items of their host. |
|
| 57 |
This is useful if you frequently move VMs between hosts and want to |
|
| 58 |
keep the VM graphs running. To activate this option, add |
|
| 59 |
|
|
| 60 |
---- snip ---- |
|
| 61 |
env.flatview top_level_entry |
|
| 62 |
---- snip ---- |
|
| 63 |
|
|
| 64 |
to the entry in your config file in /etc/munin/plugin-conf.d (see above). |
|
| 65 |
Be aware that this has some drawbacks: |
|
| 66 |
- you cannot have the same VM name in two hosts you monitor |
|
| 67 |
(the VM name is the unique identifier for the graphs) |
|
| 68 |
- you will only indirectly be able to see which VM is on which host |
|
| 69 |
(running VMs will appear in the CPU graphs of their hosts) |
|
| 70 |
- it's a flat structure, so it can become quite a long list |
|
| 71 |
- because of the way Munin works, all hosts will be queried serially, |
|
| 72 |
not in parallel as it would be the case without "flat view" - this |
|
| 73 |
MAY lead to timing problems if you have a large number of hosts or VMs |
|
| 74 |
|
|
| 75 |
|
|
| 76 |
-== Option vCenter ==- |
|
| 77 |
If you wish to access the host system indirectly through a vCenter, just |
|
| 78 |
specify this parameter: |
|
| 79 |
|
|
| 80 |
---- snip ---- |
|
| 81 |
env.vCenter <address or hostname of the vCenter> |
|
| 82 |
---- snip ---- |
|
| 83 |
|
|
| 84 |
This option can be used with or without the "flatview" option. Make sure your |
|
| 85 |
password and username are valid on the vCenter. The plugin name will still have |
|
| 86 |
to contain the hostname of the host you want to monitor - be aware that you have |
|
| 87 |
to use the hostname exactly as it is registered in the vCenter, so IPs and |
|
| 88 |
hostnames are NOT interchangeable. |
|
| 89 |
=cut |
|
| 90 |
|
|
| 91 |
=ACK |
|
| 92 |
-== Ackknowledgements ==- |
|
| 93 |
I would like to thank VMware for their SDK and the good documentation. |
|
| 94 |
|
|
| 95 |
Special thanks go to MEGABIT Informationstechnik GmbH (www.megabit.net) |
|
| 96 |
who graciously sponsored the development of the "flat view" option |
|
| 97 |
and the ability to access hosts via vCenter. |
|
| 98 |
=cut |
|
| 35 | 99 |
|
| 36 | 100 |
use strict; |
| 37 | 101 |
use sort 'stable'; # guarantee stability |
| ... | ... | |
| 45 | 109 |
use List::Util qw(sum max); |
| 46 | 110 |
use List::MoreUtils qw(all); |
| 47 | 111 |
use Munin::Plugin; |
| 112 |
use Time::HiRes qw(time); |
|
| 113 |
my $DEBUG = ${Munin::Plugin::DEBUG};
|
|
| 114 |
|
|
| 115 |
# Important: this is needed if you do not use a "proper" SSL certificate |
|
| 116 |
# on your vSphere/vCenter/ESX(i) server (which is the default) |
|
| 117 |
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
|
|
| 48 | 118 |
|
| 49 | 119 |
# get hostname from filename and blurt it out immediately |
| 50 | 120 |
# so that when something goes wrong, at least the plugin |
| 51 | 121 |
# output is linked with the right host |
| 52 | 122 |
$0 =~ /esx_(.+)$/; |
| 53 | 123 |
my $host_name = $1; |
| 54 |
print "host_name $host_name\n"; |
|
| 55 | 124 |
|
| 56 |
# env.user and env.password need to be set in plugin-conf/munin-node |
|
| 125 |
if ((defined $ARGV[0]) and ($ARGV[0] eq "config")) {
|
|
| 126 |
if ($ENV{flatview}) {
|
|
| 127 |
print "host_name $ENV{flatview}\n";
|
|
| 128 |
print "# for host $host_name\n" if $DEBUG; |
|
| 129 |
} else {
|
|
| 130 |
print "host_name $host_name\n"; |
|
| 131 |
} |
|
| 132 |
} |
|
| 133 |
|
|
| 134 |
# env.user and env.password need to be set in plugin-conf.d |
|
| 57 | 135 |
Opts::set_option ('username', $ENV{user} || 'root');
|
| 58 | 136 |
Opts::set_option ('password', $ENV{password} || '');
|
| 59 |
Opts::set_option ('url',"https://$host_name/sdk/webService");
|
|
| 137 |
if ($ENV{vCenter}) {
|
|
| 138 |
print "# vCenter: $ENV{vCenter} - host $host_name\n" if $DEBUG;
|
|
| 139 |
Opts::add_options ( (vihost => { alias => "h", type => "=s", required => 0 }) );
|
|
| 140 |
Opts::set_option ('vihost',"$host_name");
|
|
| 141 |
Opts::set_option ('url',"https://$ENV{vCenter}/sdk/webService");
|
|
| 142 |
} else {
|
|
| 143 |
Opts::set_option ('url',"https://$host_name/sdk/webService");
|
|
| 144 |
} |
|
| 145 |
|
|
| 60 | 146 |
|
| 61 | 147 |
# plugin needs Munin 1.4 or later |
| 62 | 148 |
need_multigraph(); |
| 63 | 149 |
|
| 64 | 150 |
# for datetime parsing later on |
| 65 | 151 |
my $iso8601 = DateTime::Format::ISO8601->new; |
| 152 |
my $sstarttime = time(); |
|
| 66 | 153 |
|
| 67 | 154 |
# connect to vSphere host |
| 68 | 155 |
Util::connect(); |
| 69 | 156 |
|
| 70 | 157 |
# central object host_view holds all relevant items (VMs, network, etc.) |
| 71 |
my $host_view = VIExt::get_host_view(1, ['summary', 'network', 'datastore', 'vm', 'runtime', 'configManager.networkSystem']); |
|
| 158 |
my $host_view = VIExt::get_host_view(1, ['summary', 'network', 'datastore', 'vm', 'runtime', 'configManager.networkSystem', 'configManager.dateTimeSystem']);
|
|
| 72 | 159 |
Opts::assert_usage(defined($host_view), "Invalid host."); |
| 73 | 160 |
|
| 161 |
my $serviceInst = Vim::get_view (mo_ref => ManagedObjectReference->new(type => 'ServiceInstance', value => 'ServiceInstance')); |
|
| 74 | 162 |
# Performance Manager for getting the actual values |
| 75 |
my $perfMan = Vim::get_view (mo_ref => ManagedObjectReference->new(type => 'PerformanceManager', value => 'ha-perfmgr'));
|
|
| 163 |
my $perfMan = Vim::get_view (mo_ref => $serviceInst->content->perfManager);
|
|
| 76 | 164 |
Opts::assert_usage(defined($perfMan), "No PerformanceManager."); |
| 77 | 165 |
|
| 78 | 166 |
# may be needed later |
| ... | ... | |
| 81 | 169 |
|
| 82 | 170 |
# used for getting the current vSphere server time and then |
| 83 | 171 |
# defining the (now - 5minutes) interval |
| 84 |
my $dtsys = Vim::get_view(mo_ref => ManagedObjectReference->new(type => 'HostDateTimeSystem', value => 'dateTimeSystem'));
|
|
| 172 |
my $dtsys = Vim::get_view(mo_ref => $host_view->{'configManager.dateTimeSystem'});
|
|
| 85 | 173 |
Opts::assert_usage(defined($dtsys), "No DateTimeSystem."); |
| 86 | 174 |
|
| 175 |
print "# time to connect and get objects: ", time() - $sstarttime, "\n" if $DEBUG; |
|
| 176 |
|
|
| 87 | 177 |
# enumerate all performance counters by their IDs |
| 88 | 178 |
my %perfCounter = map { $_->key => $_ } @{$perfMan->perfCounter};
|
| 89 | 179 |
# holds all performance data |
| ... | ... | |
| 93 | 183 |
# IDs/UUIDs to human readable names |
| 94 | 184 |
my $resolveNames; |
| 95 | 185 |
|
| 186 |
$host_view->update_view_data(); |
|
| 96 | 187 |
# retrieve performance counters for host |
| 97 | 188 |
push @all_perf_data, get_perf_data($host_view); |
| 98 | 189 |
# manually set UF name for host system |
| ... | ... | |
| 115 | 206 |
my $datastore = Vim::get_view (mo_ref => $_); |
| 116 | 207 |
# update freeSpace values (doesn't work on free ESXi) |
| 117 | 208 |
eval { $datastore->RefreshDatastore(); };
|
| 209 |
$datastore->update_view_data(); |
|
| 118 | 210 |
my $uuid =$datastore->summary->url; |
| 119 | 211 |
$uuid =~ s!.+/!!; |
| 120 | 212 |
$resolveNames->{datastore}->{$uuid} = $datastore->name;
|
| ... | ... | |
| 152 | 244 |
for ($host_view->vm) {
|
| 153 | 245 |
for (@$_) {
|
| 154 | 246 |
my $vm = Vim::get_view (mo_ref => $_); |
| 247 |
$vm->update_view_data(); |
|
| 155 | 248 |
# store VM id for later iteration |
| 156 | 249 |
my $vmId = $_->{value};
|
| 157 | 250 |
push @all_vms, $vmId; |
| 158 | 251 |
# ID to VM name |
| 159 | 252 |
$resolveNames->{vm}->{$vmId} = "VM ".$vm->summary->config->name;
|
| 253 |
$resolveNames->{vmuuid}->{$vmId} = $vm->summary->config->uuid;
|
|
| 160 | 254 |
# fetch disk space usage per datastore |
| 161 | 255 |
for (@{$vm->storage->perDatastoreUsage}) {
|
| 162 | 256 |
my $uuid = Vim::get_view(mo_ref => $_->datastore)->summary->url; |
| ... | ... | |
| 233 | 327 |
unit => "Numbers" }); |
| 234 | 328 |
} |
| 235 | 329 |
|
| 236 |
# -> DEBUG |
|
| 237 |
foreach (sort { $a->{group} cmp $b->{group} || $a->{instance} cmp $b->{instance} || $a->{name} cmp $b->{name} || $a->{rollup} cmp $b->{rollup} || $a->{vm} cmp $b->{vm} } @all_perf_data) {
|
|
| 238 |
print "# $_->{vm}\t$_->{rollup}\t$_->{group}\t$_->{instance}\t$_->{name}\t$_->{value}\t$_->{unit}\n";
|
|
| 330 |
if ($DEBUG) {
|
|
| 331 |
foreach (sort { $a->{group} cmp $b->{group} || $a->{instance} cmp $b->{instance} || $a->{name} cmp $b->{name} || $a->{rollup} cmp $b->{rollup} || $a->{vm} cmp $b->{vm} } @all_perf_data) {
|
|
| 332 |
print "# $_->{vm}\t$_->{rollup}\t$_->{group}\t$_->{instance}\t$_->{name}\t$_->{value}\t$_->{unit}\n";
|
|
| 333 |
} |
|
| 239 | 334 |
} |
| 240 |
# <- DEBUG |
|
| 241 | 335 |
|
| 242 | 336 |
# which graphs to draw |
| 243 | 337 |
my @all_graphs = (); |
| ... | ... | |
| 245 | 339 |
# host system |
| 246 | 340 |
push @all_graphs, ( |
| 247 | 341 |
{ selector => { group => qr/^cpu$/i, name => qr/^usagemhz$/i, instance => qr/^$/ },
|
| 248 |
config => { groupBy => "group", graphName => "usage_", graphTitle => "CPU usage per " }
|
|
| 342 |
config => { groupBy => "group", graphName => "host_cpu", graphTitle => "CPU usage per " }
|
|
| 249 | 343 |
}, |
| 250 | 344 |
{ selector => { group => qr/^disk$/i, name => qr/^(read|usage|write)$/i, instance => qr/.+/ },
|
| 251 |
config => { groupBy => "group", graphName => "transfer_", graphTitle => "Disk Transfer Rates per " }
|
|
| 345 |
config => { groupBy => "group", graphName => "host_disk_transfer", graphTitle => "Disk Transfer Rates per " }
|
|
| 252 | 346 |
}, |
| 253 | 347 |
{ selector => { group => qr/^disk$/i, name => qr/^.+Averaged$/i, instance => qr/.+/ },
|
| 254 |
config => { groupBy => "group", graphName => "iops_", graphTitle => "Disk I/O operations per " }
|
|
| 348 |
config => { groupBy => "group", graphName => "host_disk_iops", graphTitle => "Disk I/O operations per " }
|
|
| 255 | 349 |
}, |
| 256 | 350 |
{ selector => { group => qr/^disk$/i, name => qr/^.+Latency$/i, instance => qr/.+/, vm => qr/^$/ },
|
| 257 |
config => { groupBy => "vm", graphName => "latency_disk", graphTitle => "Disk latency for " }
|
|
| 351 |
config => { groupBy => "vm", graphName => "host_disk_latency", graphTitle => "Disk latency for " }
|
|
| 258 | 352 |
}, |
| 259 | 353 |
{ selector => { group => qr/^mem$/i, unit => qr/^KB$/i, rollup => qr/^none$/, vm => qr/^$/ },
|
| 260 |
config => { groupBy => "vm", graphName => "mem_host", graphTitle => "Memory usage for " }
|
|
| 354 |
config => { groupBy => "vm", graphName => "host_memory", graphTitle => "Memory usage for " }
|
|
| 261 | 355 |
}, |
| 262 | 356 |
{ selector => { group => qr/^datastore$/i, unit => qr/^Bytes$/i, vm => qr/^$/ },
|
| 263 | 357 |
config => { groupBy => "vm", graphName => "usage_datastore", graphTitle => "Disk space usage for ", graphArgs => "--lower-limit 10737418240 --logarithmic --alt-autoscale-min --units=si" }
|
| 264 | 358 |
}, |
| 265 | 359 |
{ selector => { group => qr/^net$/i, unit => qr/^KBps$/i, vm => qr/^$/ },
|
| 266 |
config => { groupBy => "vm", graphName => "traffic_net", graphTitle => "Network traffic for " }
|
|
| 360 |
config => { groupBy => "vm", graphName => "host_traffic_net", graphTitle => "Network traffic for " }
|
|
| 267 | 361 |
}, |
| 268 | 362 |
{ selector => { group => qr/^net$/i, unit => qr/^Number$/i, vm => qr/^$/ },
|
| 269 |
config => { groupBy => "vm", graphName => "packets_net", graphTitle => "Network packets for " }
|
|
| 363 |
config => { groupBy => "vm", graphName => "host_packets_net", graphTitle => "Network packets for " }
|
|
| 364 |
}, |
|
| 365 |
{ selector => { group => qr/^power$/i, name => qr/^power$/i },
|
|
| 366 |
config => { groupBy => "group", graphName => "power_usage", graphTitle => "Host System and VM " }
|
|
| 270 | 367 |
}, |
| 271 | 368 |
{ selector => { group => qr/^sys$/i, name => qr/^diskUsage$/i },
|
| 272 |
config => { groupBy => "name", graphName => "host_", graphTitle => "Host System " }
|
|
| 369 |
config => { groupBy => "name", graphName => "host_disk_usage", graphTitle => "Host System " }
|
|
| 273 | 370 |
}, |
| 274 | 371 |
{ selector => { group => qr/^sys$/i, name => qr/^uptime$/i },
|
| 275 |
config => { groupBy => "name", graphName => "host_", graphTitle => "Host System and VM ", graphArgs => "--lower-limit 1000 --logarithmic --alt-autoscale-min" }
|
|
| 372 |
config => { groupBy => "name", graphName => "uptimes", graphTitle => "Host System and VM ", graphArgs => "--lower-limit 1000 --logarithmic --alt-autoscale-min" }
|
|
| 276 | 373 |
} |
| 277 | 374 |
); |
| 278 | 375 |
|
| ... | ... | |
| 281 | 378 |
my $vmName = clean_fieldname($resolveNames->{vm}->{$_});
|
| 282 | 379 |
push @all_graphs, ( |
| 283 | 380 |
{ selector => { group => qr/^cpu$/i, name => qr/^usagemhz$/i, vm => qr/^$_$/ },
|
| 284 |
config => { groupBy => "vm", graphName => "$vmName.cpu_", graphTitle => "CPU usage for " }
|
|
| 381 |
config => { groupBy => "vm", graphName => "$vmName.vm_cpu", graphTitle => "CPU usage for " }
|
|
| 285 | 382 |
}, |
| 286 | 383 |
{ selector => { group => qr/^mem$/i, unit => qr/^KB$/i, rollup => qr/^none$/, vm => qr/^$_$/ },
|
| 287 |
config => { groupBy => "vm", graphName => "$vmName.memory_", graphTitle => "Memory usage for " }
|
|
| 384 |
config => { groupBy => "vm", graphName => "$vmName.vm_memory", graphTitle => "Memory usage for " }
|
|
| 288 | 385 |
}, |
| 289 | 386 |
{ selector => { group => qr/^datastore$/i, unit => qr/^Bytes$/i, vm => qr/^$_$/ },
|
| 290 |
config => { groupBy => "vm", graphName => "$vmName.datastore_", graphTitle => "Disk space usage for ", graphArgs => "--lower-limit 10485760 --logarithmic --alt-autoscale-min --units=si" }
|
|
| 387 |
config => { groupBy => "vm", graphName => "$vmName.vm_datastore", graphTitle => "Disk space usage for ", graphArgs => "--lower-limit 10485760 --logarithmic --alt-autoscale-min --units=si" }
|
|
| 291 | 388 |
}, |
| 292 | 389 |
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^Millisecond$/i, vm => qr/^$_$/ },
|
| 293 |
config => { groupBy => "vm", graphName => "$vmName.disklat_", graphTitle => "Disk latency for " }
|
|
| 390 |
config => { groupBy => "vm", graphName => "$vmName.vm_disklat", graphTitle => "Disk latency for " }
|
|
| 294 | 391 |
}, |
| 295 | 392 |
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^Number$/i, vm => qr/^$_$/ },
|
| 296 |
config => { groupBy => "vm", graphName => "$vmName.diskiops_", graphTitle => "Disk I/O operations for " }
|
|
| 393 |
config => { groupBy => "vm", graphName => "$vmName.vm_diskiops", graphTitle => "Disk I/O operations for " }
|
|
| 297 | 394 |
}, |
| 298 | 395 |
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^KBps$/i, vm => qr/^$_$/ },
|
| 299 |
config => { groupBy => "vm", graphName => "$vmName.disktrans_", graphTitle => "Disk transfer rates for " }
|
|
| 396 |
config => { groupBy => "vm", graphName => "$vmName.vm_disktrans", graphTitle => "Disk transfer rates for " }
|
|
| 300 | 397 |
}, |
| 301 | 398 |
{ selector => { group => qr/^net$/i, unit => qr/^KBps$/i, vm => qr/^$_$/ },
|
| 302 |
config => { groupBy => "vm", graphName => "$vmName.traffic_net_", graphTitle => "Network traffic for " }
|
|
| 399 |
config => { groupBy => "vm", graphName => "$vmName.vm_traffic_net", graphTitle => "Network traffic for " }
|
|
| 303 | 400 |
}, |
| 304 | 401 |
{ selector => { group => qr/^net$/i, unit => qr/^Number$/i, vm => qr/^$_$/ },
|
| 305 |
config => { groupBy => "vm", graphName => "$vmName.packets_net_", graphTitle => "Network packets for " }
|
|
| 402 |
config => { groupBy => "vm", graphName => "$vmName.vm_packets_net", graphTitle => "Network packets for " }
|
|
| 306 | 403 |
}, |
| 307 | 404 |
{ selector => { group => qr/^sys$/i, name => qr/^uptime$/i, vm => qr/^$_$/ },
|
| 308 |
config => { groupBy => "vm", graphName => "$vmName.uptime_", graphTitle => "VM uptime " }
|
|
| 405 |
config => { groupBy => "vm", graphName => "$vmName.vm_uptime", graphTitle => "VM uptime " }
|
|
| 309 | 406 |
} |
| 310 | 407 |
); |
| 311 | 408 |
} |
| ... | ... | |
| 313 | 410 |
# sensor graphs |
| 314 | 411 |
push @all_graphs, ( |
| 315 | 412 |
{ selector => { group => qr/^sensors$/i },
|
| 316 |
config => { groupBy => "unit", graphName => "sensor_", graphTitle => "Sensors " }
|
|
| 413 |
config => { groupBy => "unit", graphName => "sensor_", graphTitle => "Sensors ", multiGraph => 1 }
|
|
| 317 | 414 |
}); |
| 318 | 415 |
|
| 416 |
print "# time to collect all data: ", time() - $sstarttime, "\n" if $DEBUG; |
|
| 319 | 417 |
|
| 320 | 418 |
# actual processing |
| 321 | 419 |
foreach (@all_graphs) {
|
| ... | ... | |
| 327 | 425 |
} |
| 328 | 426 |
} |
| 329 | 427 |
|
| 428 |
print "# time of the script: ", time() - $sstarttime, "\n" if $DEBUG; |
|
| 429 |
|
|
| 330 | 430 |
0; |
| 331 | 431 |
|
| 332 | 432 |
#################################################################### |
| ... | ... | |
| 350 | 450 |
sub get_perf_data {
|
| 351 | 451 |
my $entity = shift; |
| 352 | 452 |
my @ret = (); |
| 453 |
my $gathstart = time(); |
|
| 353 | 454 |
# get the current server time |
| 354 | 455 |
my $curtime = $iso8601->parse_datetime($dtsys->QueryDateTime()); |
| 355 | 456 |
# and subtract 5 minutes to get all values for the last period |
| ... | ... | |
| 375 | 476 |
unit => $perfDesc->unitInfo->label }; |
| 376 | 477 |
} |
| 377 | 478 |
} |
| 479 |
print "# time to gather info for $entity :", time() - $gathstart, "\n" if $DEBUG; |
|
| 378 | 480 |
return @ret; |
| 379 | 481 |
} |
| 380 | 482 |
|
| 381 | 483 |
# generate a munin-friendly and unique field name |
| 382 | 484 |
sub gen_dp_name {
|
| 383 |
return clean_fieldname("$_[0]->{name}v$_[0]->{vm}i$_[0]->{instance}");
|
|
| 485 |
my $fname = $_[0]->{name};
|
|
| 486 |
$fname .= "v".$resolveNames->{vmuuid}->{$_[0]->{vm}} unless $_[1] eq "vm" or $_[0]->{vm} eq "";
|
|
| 487 |
$fname .= "i$_[0]->{instance}" unless $_[1] eq "instance" or $_[0]->{instance} eq "";
|
|
| 488 |
return clean_fieldname($fname); |
|
| 384 | 489 |
} |
| 385 | 490 |
|
| 386 | 491 |
# trim white spaces |
| ... | ... | |
| 403 | 508 |
$par = $par->{selector};
|
| 404 | 509 |
my $oldGroup = "_-_"; |
| 405 | 510 |
my $factor; |
| 511 |
if ($ENV{flatview}) {
|
|
| 512 |
$cfg->{graphName} = clean_fieldname("Host_$host_name").".".$cfg->{graphName} unless $cfg->{graphName} =~ m/\./;
|
|
| 513 |
} |
|
| 406 | 514 |
|
| 407 | 515 |
# find values according to criteria in $par and sort by grouping parameter |
| 408 |
foreach (sort { $a->{$cfg->{groupBy}} cmp $b->{$cfg->{groupBy}} } grep { my $d = $_; all { (not exists $d->{$_}) || $d->{$_} =~ /$par->{$_}/ } keys %$par; } @$arr) {
|
|
| 409 |
my $groupCrit = $cfg->{groupBy};
|
|
| 410 |
my $curGroup = $_->{$groupCrit};
|
|
| 516 |
#foreach (sort { $a->{$cfg->{groupBy}} cmp $b->{$cfg->{groupBy}} } grep { my $d = $_; all { (not exists $d->{$_}) || $d->{$_} =~ /$par->{$_}/ } keys %$par; } @$arr) {
|
|
| 517 |
foreach (sort { $a->{$cfg->{groupBy}} cmp $b->{$cfg->{groupBy}} } grep { my $d = $_; all { (not exists $d->{$_}) || $d->{$_} =~ /$par->{$_}/ } keys %$par; } @$arr) {
|
|
| 518 |
my $groupCrit = $cfg->{groupBy} || "";
|
|
| 519 |
my $curGroup = $_->{$groupCrit} || "";
|
|
| 411 | 520 |
|
| 412 | 521 |
if (!($curGroup eq $oldGroup)) {
|
| 413 | 522 |
# we're in a new group, meaning a new graph starts |
| 414 | 523 |
$factor = 0; |
| 415 | 524 |
# clean up group name for multigraph name |
| 416 | 525 |
my $ccurGroup = $curGroup; |
| 417 |
$ccurGroup =~ s/ |\./_/g;
|
|
| 418 |
print "multigraph ",$cfg->{graphName},$ccurGroup,"\n";
|
|
| 526 |
$ccurGroup =~ s/ |\./_/g;
|
|
| 527 |
print "multigraph ",$cfg->{graphName},(exists $cfg->{multiGraph}?$ccurGroup:""),"\n";
|
|
| 419 | 528 |
|
| 420 | 529 |
if ("config" eq $act) {
|
| 421 | 530 |
# want configuration |
| ... | ... | |
| 457 | 566 |
|
| 458 | 567 |
} |
| 459 | 568 |
$oldGroup = $curGroup; |
| 460 |
my $dpName = gen_dp_name($_); |
|
| 569 |
my $dpName = gen_dp_name($_, $groupCrit);
|
|
| 461 | 570 |
if ("config" eq $act) {
|
| 462 | 571 |
# want configuration |
| 463 | 572 |
# get instance and VM names and UF names, if applicable |
| ... | ... | |
| 485 | 594 |
} |
| 486 | 595 |
} else {
|
| 487 | 596 |
# just print value |
| 488 |
print gen_dp_name ($_), ".value $_->{value}\n";
|
|
| 597 |
print "$dpName.value $_->{value}\n";
|
|
| 489 | 598 |
} |
| 490 | 599 |
} |
| 491 | 600 |
} |
Formats disponibles : Unified diff