mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
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
This commit is contained in:
parent
1d24429110
commit
cb21db87c7
1 changed files with 177 additions and 68 deletions
|
@ -1,37 +1,101 @@
|
||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
#
|
=HEADER
|
||||||
# -== Munin plugin for VMware ESXi/vSphere monitoring ==-
|
-== Munin plugin for VMware ESXi/vSphere monitoring ==-
|
||||||
#
|
|
||||||
# Copyright (c) 2012 - Stefan Seidel <munin@stefanseidel.info>
|
Copyright (c) 2012 - Stefan Seidel <munin@stefanseidel.info>
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
(at your option) any later version.
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
|
||||||
#
|
|
||||||
# This plugin uses the vSphere SDK for Perl available at
|
|
||||||
# http://www.vmware.com/support/developer/viperltoolkit/
|
|
||||||
# or included in the vSphere CLI available at
|
|
||||||
# http://www.vmware.com/support/developer/vcli/
|
|
||||||
# The use of the SDK is subject to the terms and condition
|
|
||||||
# of VMware, Inc. to which you must agree upon installation.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
#
|
This plugin uses the vSphere SDK for Perl available at
|
||||||
# -== Usage ==-
|
http://www.vmware.com/support/developer/viperltoolkit/
|
||||||
# Put this file in /usr/share/munin/plugins, `chmod +x` it and
|
or included in the vSphere CLI available at
|
||||||
# `ln -s` it to /etc/munin/plugins/esx_<hostname of server to monitor>
|
http://www.vmware.com/support/developer/vcli/
|
||||||
#
|
The use of the SDK is subject to the terms and condition
|
||||||
|
of VMware, Inc. to which you must agree upon installation.
|
||||||
|
=cut
|
||||||
|
|
||||||
|
=USAGE
|
||||||
|
-== Usage ==-
|
||||||
|
Put this file in /usr/share/munin/plugins, `chmod +x` it and
|
||||||
|
`ln -s` it to /etc/munin/plugins/esx_<hostname of server to monitor>
|
||||||
|
Add a file "esx_" /etc/munin/plugin-conf.d with content like this
|
||||||
|
(omit the "# " at the beginning of each line)
|
||||||
|
|
||||||
|
---- snip ----
|
||||||
|
[esx_*]
|
||||||
|
timeout 60
|
||||||
|
env.user <username on ESX server or vCenter>
|
||||||
|
env.password <password of user on ESX server or vCenter>
|
||||||
|
---- snip ----
|
||||||
|
|
||||||
|
Then you need to add this host to your munin.conf on the munin server
|
||||||
|
(often this is the same as your munin node, i.e. this host) and restart
|
||||||
|
munin-node, and wait for the data to populate.
|
||||||
|
|
||||||
|
|
||||||
|
-== Graphs don't render ==-
|
||||||
|
Munin 1.4 has a bug with complex multigraphs like this, see
|
||||||
|
http://munin-monitoring.org/ticket/1224 for details and a fix if
|
||||||
|
your graphs don't render!
|
||||||
|
|
||||||
|
|
||||||
|
-== Option flatview ==-
|
||||||
|
There is an option to render all VMs and Host Systems in a flat
|
||||||
|
structure, i.e. not rendering VMs as sub-items of their host.
|
||||||
|
This is useful if you frequently move VMs between hosts and want to
|
||||||
|
keep the VM graphs running. To activate this option, add
|
||||||
|
|
||||||
|
---- snip ----
|
||||||
|
env.flatview top_level_entry
|
||||||
|
---- snip ----
|
||||||
|
|
||||||
|
to the entry in your config file in /etc/munin/plugin-conf.d (see above).
|
||||||
|
Be aware that this has some drawbacks:
|
||||||
|
- you cannot have the same VM name in two hosts you monitor
|
||||||
|
(the VM name is the unique identifier for the graphs)
|
||||||
|
- you will only indirectly be able to see which VM is on which host
|
||||||
|
(running VMs will appear in the CPU graphs of their hosts)
|
||||||
|
- it's a flat structure, so it can become quite a long list
|
||||||
|
- because of the way Munin works, all hosts will be queried serially,
|
||||||
|
not in parallel as it would be the case without "flat view" - this
|
||||||
|
MAY lead to timing problems if you have a large number of hosts or VMs
|
||||||
|
|
||||||
|
|
||||||
|
-== Option vCenter ==-
|
||||||
|
If you wish to access the host system indirectly through a vCenter, just
|
||||||
|
specify this parameter:
|
||||||
|
|
||||||
|
---- snip ----
|
||||||
|
env.vCenter <address or hostname of the vCenter>
|
||||||
|
---- snip ----
|
||||||
|
|
||||||
|
This option can be used with or without the "flatview" option. Make sure your
|
||||||
|
password and username are valid on the vCenter. The plugin name will still have
|
||||||
|
to contain the hostname of the host you want to monitor - be aware that you have
|
||||||
|
to use the hostname exactly as it is registered in the vCenter, so IPs and
|
||||||
|
hostnames are NOT interchangeable.
|
||||||
|
=cut
|
||||||
|
|
||||||
|
=ACK
|
||||||
|
-== Ackknowledgements ==-
|
||||||
|
I would like to thank VMware for their SDK and the good documentation.
|
||||||
|
|
||||||
|
Special thanks go to MEGABIT Informationstechnik GmbH (www.megabit.net)
|
||||||
|
who graciously sponsored the development of the "flat view" option
|
||||||
|
and the ability to access hosts via vCenter.
|
||||||
|
=cut
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use sort 'stable'; # guarantee stability
|
use sort 'stable'; # guarantee stability
|
||||||
|
@ -45,34 +109,58 @@ use DateTime::Format::ISO8601; # may need to install "libdatetime-format-iso8601
|
||||||
use List::Util qw(sum max);
|
use List::Util qw(sum max);
|
||||||
use List::MoreUtils qw(all);
|
use List::MoreUtils qw(all);
|
||||||
use Munin::Plugin;
|
use Munin::Plugin;
|
||||||
|
use Time::HiRes qw(time);
|
||||||
|
my $DEBUG = ${Munin::Plugin::DEBUG};
|
||||||
|
|
||||||
|
# Important: this is needed if you do not use a "proper" SSL certificate
|
||||||
|
# on your vSphere/vCenter/ESX(i) server (which is the default)
|
||||||
|
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
|
||||||
|
|
||||||
# get hostname from filename and blurt it out immediately
|
# get hostname from filename and blurt it out immediately
|
||||||
# so that when something goes wrong, at least the plugin
|
# so that when something goes wrong, at least the plugin
|
||||||
# output is linked with the right host
|
# output is linked with the right host
|
||||||
$0 =~ /esx_(.+)$/;
|
$0 =~ /esx_(.+)$/;
|
||||||
my $host_name = $1;
|
my $host_name = $1;
|
||||||
print "host_name $host_name\n";
|
|
||||||
|
|
||||||
# env.user and env.password need to be set in plugin-conf/munin-node
|
if ((defined $ARGV[0]) and ($ARGV[0] eq "config")) {
|
||||||
|
if ($ENV{flatview}) {
|
||||||
|
print "host_name $ENV{flatview}\n";
|
||||||
|
print "# for host $host_name\n" if $DEBUG;
|
||||||
|
} else {
|
||||||
|
print "host_name $host_name\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# env.user and env.password need to be set in plugin-conf.d
|
||||||
Opts::set_option ('username', $ENV{user} || 'root');
|
Opts::set_option ('username', $ENV{user} || 'root');
|
||||||
Opts::set_option ('password', $ENV{password} || '');
|
Opts::set_option ('password', $ENV{password} || '');
|
||||||
Opts::set_option ('url',"https://$host_name/sdk/webService");
|
if ($ENV{vCenter}) {
|
||||||
|
print "# vCenter: $ENV{vCenter} - host $host_name\n" if $DEBUG;
|
||||||
|
Opts::add_options ( (vihost => { alias => "h", type => "=s", required => 0 }) );
|
||||||
|
Opts::set_option ('vihost',"$host_name");
|
||||||
|
Opts::set_option ('url',"https://$ENV{vCenter}/sdk/webService");
|
||||||
|
} else {
|
||||||
|
Opts::set_option ('url',"https://$host_name/sdk/webService");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# plugin needs Munin 1.4 or later
|
# plugin needs Munin 1.4 or later
|
||||||
need_multigraph();
|
need_multigraph();
|
||||||
|
|
||||||
# for datetime parsing later on
|
# for datetime parsing later on
|
||||||
my $iso8601 = DateTime::Format::ISO8601->new;
|
my $iso8601 = DateTime::Format::ISO8601->new;
|
||||||
|
my $sstarttime = time();
|
||||||
|
|
||||||
# connect to vSphere host
|
# connect to vSphere host
|
||||||
Util::connect();
|
Util::connect();
|
||||||
|
|
||||||
# central object host_view holds all relevant items (VMs, network, etc.)
|
# central object host_view holds all relevant items (VMs, network, etc.)
|
||||||
my $host_view = VIExt::get_host_view(1, ['summary', 'network', 'datastore', 'vm', 'runtime', 'configManager.networkSystem']);
|
my $host_view = VIExt::get_host_view(1, ['summary', 'network', 'datastore', 'vm', 'runtime', 'configManager.networkSystem', 'configManager.dateTimeSystem']);
|
||||||
Opts::assert_usage(defined($host_view), "Invalid host.");
|
Opts::assert_usage(defined($host_view), "Invalid host.");
|
||||||
|
|
||||||
|
my $serviceInst = Vim::get_view (mo_ref => ManagedObjectReference->new(type => 'ServiceInstance', value => 'ServiceInstance'));
|
||||||
# Performance Manager for getting the actual values
|
# Performance Manager for getting the actual values
|
||||||
my $perfMan = Vim::get_view (mo_ref => ManagedObjectReference->new(type => 'PerformanceManager', value => 'ha-perfmgr'));
|
my $perfMan = Vim::get_view (mo_ref => $serviceInst->content->perfManager);
|
||||||
Opts::assert_usage(defined($perfMan), "No PerformanceManager.");
|
Opts::assert_usage(defined($perfMan), "No PerformanceManager.");
|
||||||
|
|
||||||
# may be needed later
|
# may be needed later
|
||||||
|
@ -81,9 +169,11 @@ Opts::assert_usage(defined($perfMan), "No PerformanceManager.");
|
||||||
|
|
||||||
# used for getting the current vSphere server time and then
|
# used for getting the current vSphere server time and then
|
||||||
# defining the (now - 5minutes) interval
|
# defining the (now - 5minutes) interval
|
||||||
my $dtsys = Vim::get_view(mo_ref => ManagedObjectReference->new(type => 'HostDateTimeSystem', value => 'dateTimeSystem'));
|
my $dtsys = Vim::get_view(mo_ref => $host_view->{'configManager.dateTimeSystem'});
|
||||||
Opts::assert_usage(defined($dtsys), "No DateTimeSystem.");
|
Opts::assert_usage(defined($dtsys), "No DateTimeSystem.");
|
||||||
|
|
||||||
|
print "# time to connect and get objects: ", time() - $sstarttime, "\n" if $DEBUG;
|
||||||
|
|
||||||
# enumerate all performance counters by their IDs
|
# enumerate all performance counters by their IDs
|
||||||
my %perfCounter = map { $_->key => $_ } @{$perfMan->perfCounter};
|
my %perfCounter = map { $_->key => $_ } @{$perfMan->perfCounter};
|
||||||
# holds all performance data
|
# holds all performance data
|
||||||
|
@ -93,6 +183,7 @@ my @all_vms = ();
|
||||||
# IDs/UUIDs to human readable names
|
# IDs/UUIDs to human readable names
|
||||||
my $resolveNames;
|
my $resolveNames;
|
||||||
|
|
||||||
|
$host_view->update_view_data();
|
||||||
# retrieve performance counters for host
|
# retrieve performance counters for host
|
||||||
push @all_perf_data, get_perf_data($host_view);
|
push @all_perf_data, get_perf_data($host_view);
|
||||||
# manually set UF name for host system
|
# manually set UF name for host system
|
||||||
|
@ -115,6 +206,7 @@ for ($host_view->datastore) {
|
||||||
my $datastore = Vim::get_view (mo_ref => $_);
|
my $datastore = Vim::get_view (mo_ref => $_);
|
||||||
# update freeSpace values (doesn't work on free ESXi)
|
# update freeSpace values (doesn't work on free ESXi)
|
||||||
eval { $datastore->RefreshDatastore(); };
|
eval { $datastore->RefreshDatastore(); };
|
||||||
|
$datastore->update_view_data();
|
||||||
my $uuid =$datastore->summary->url;
|
my $uuid =$datastore->summary->url;
|
||||||
$uuid =~ s!.+/!!;
|
$uuid =~ s!.+/!!;
|
||||||
$resolveNames->{datastore}->{$uuid} = $datastore->name;
|
$resolveNames->{datastore}->{$uuid} = $datastore->name;
|
||||||
|
@ -152,11 +244,13 @@ for ($host_view->datastore) {
|
||||||
for ($host_view->vm) {
|
for ($host_view->vm) {
|
||||||
for (@$_) {
|
for (@$_) {
|
||||||
my $vm = Vim::get_view (mo_ref => $_);
|
my $vm = Vim::get_view (mo_ref => $_);
|
||||||
|
$vm->update_view_data();
|
||||||
# store VM id for later iteration
|
# store VM id for later iteration
|
||||||
my $vmId = $_->{value};
|
my $vmId = $_->{value};
|
||||||
push @all_vms, $vmId;
|
push @all_vms, $vmId;
|
||||||
# ID to VM name
|
# ID to VM name
|
||||||
$resolveNames->{vm}->{$vmId} = "VM ".$vm->summary->config->name;
|
$resolveNames->{vm}->{$vmId} = "VM ".$vm->summary->config->name;
|
||||||
|
$resolveNames->{vmuuid}->{$vmId} = $vm->summary->config->uuid;
|
||||||
# fetch disk space usage per datastore
|
# fetch disk space usage per datastore
|
||||||
for (@{$vm->storage->perDatastoreUsage}) {
|
for (@{$vm->storage->perDatastoreUsage}) {
|
||||||
my $uuid = Vim::get_view(mo_ref => $_->datastore)->summary->url;
|
my $uuid = Vim::get_view(mo_ref => $_->datastore)->summary->url;
|
||||||
|
@ -233,11 +327,11 @@ for (keys %sensorCount) {
|
||||||
unit => "Numbers" });
|
unit => "Numbers" });
|
||||||
}
|
}
|
||||||
|
|
||||||
# -> DEBUG
|
if ($DEBUG) {
|
||||||
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) {
|
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) {
|
||||||
print "# $_->{vm}\t$_->{rollup}\t$_->{group}\t$_->{instance}\t$_->{name}\t$_->{value}\t$_->{unit}\n";
|
print "# $_->{vm}\t$_->{rollup}\t$_->{group}\t$_->{instance}\t$_->{name}\t$_->{value}\t$_->{unit}\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# <- DEBUG
|
|
||||||
|
|
||||||
# which graphs to draw
|
# which graphs to draw
|
||||||
my @all_graphs = ();
|
my @all_graphs = ();
|
||||||
|
@ -245,34 +339,37 @@ my @all_graphs = ();
|
||||||
# host system
|
# host system
|
||||||
push @all_graphs, (
|
push @all_graphs, (
|
||||||
{ selector => { group => qr/^cpu$/i, name => qr/^usagemhz$/i, instance => qr/^$/ },
|
{ selector => { group => qr/^cpu$/i, name => qr/^usagemhz$/i, instance => qr/^$/ },
|
||||||
config => { groupBy => "group", graphName => "usage_", graphTitle => "CPU usage per " }
|
config => { groupBy => "group", graphName => "host_cpu", graphTitle => "CPU usage per " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^disk$/i, name => qr/^(read|usage|write)$/i, instance => qr/.+/ },
|
{ selector => { group => qr/^disk$/i, name => qr/^(read|usage|write)$/i, instance => qr/.+/ },
|
||||||
config => { groupBy => "group", graphName => "transfer_", graphTitle => "Disk Transfer Rates per " }
|
config => { groupBy => "group", graphName => "host_disk_transfer", graphTitle => "Disk Transfer Rates per " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^disk$/i, name => qr/^.+Averaged$/i, instance => qr/.+/ },
|
{ selector => { group => qr/^disk$/i, name => qr/^.+Averaged$/i, instance => qr/.+/ },
|
||||||
config => { groupBy => "group", graphName => "iops_", graphTitle => "Disk I/O operations per " }
|
config => { groupBy => "group", graphName => "host_disk_iops", graphTitle => "Disk I/O operations per " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^disk$/i, name => qr/^.+Latency$/i, instance => qr/.+/, vm => qr/^$/ },
|
{ selector => { group => qr/^disk$/i, name => qr/^.+Latency$/i, instance => qr/.+/, vm => qr/^$/ },
|
||||||
config => { groupBy => "vm", graphName => "latency_disk", graphTitle => "Disk latency for " }
|
config => { groupBy => "vm", graphName => "host_disk_latency", graphTitle => "Disk latency for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^mem$/i, unit => qr/^KB$/i, rollup => qr/^none$/, vm => qr/^$/ },
|
{ selector => { group => qr/^mem$/i, unit => qr/^KB$/i, rollup => qr/^none$/, vm => qr/^$/ },
|
||||||
config => { groupBy => "vm", graphName => "mem_host", graphTitle => "Memory usage for " }
|
config => { groupBy => "vm", graphName => "host_memory", graphTitle => "Memory usage for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^datastore$/i, unit => qr/^Bytes$/i, vm => qr/^$/ },
|
{ selector => { group => qr/^datastore$/i, unit => qr/^Bytes$/i, vm => qr/^$/ },
|
||||||
config => { groupBy => "vm", graphName => "usage_datastore", graphTitle => "Disk space usage for ", graphArgs => "--lower-limit 10737418240 --logarithmic --alt-autoscale-min --units=si" }
|
config => { groupBy => "vm", graphName => "usage_datastore", graphTitle => "Disk space usage for ", graphArgs => "--lower-limit 10737418240 --logarithmic --alt-autoscale-min --units=si" }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^net$/i, unit => qr/^KBps$/i, vm => qr/^$/ },
|
{ selector => { group => qr/^net$/i, unit => qr/^KBps$/i, vm => qr/^$/ },
|
||||||
config => { groupBy => "vm", graphName => "traffic_net", graphTitle => "Network traffic for " }
|
config => { groupBy => "vm", graphName => "host_traffic_net", graphTitle => "Network traffic for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^net$/i, unit => qr/^Number$/i, vm => qr/^$/ },
|
{ selector => { group => qr/^net$/i, unit => qr/^Number$/i, vm => qr/^$/ },
|
||||||
config => { groupBy => "vm", graphName => "packets_net", graphTitle => "Network packets for " }
|
config => { groupBy => "vm", graphName => "host_packets_net", graphTitle => "Network packets for " }
|
||||||
|
},
|
||||||
|
{ selector => { group => qr/^power$/i, name => qr/^power$/i },
|
||||||
|
config => { groupBy => "group", graphName => "power_usage", graphTitle => "Host System and VM " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^sys$/i, name => qr/^diskUsage$/i },
|
{ selector => { group => qr/^sys$/i, name => qr/^diskUsage$/i },
|
||||||
config => { groupBy => "name", graphName => "host_", graphTitle => "Host System " }
|
config => { groupBy => "name", graphName => "host_disk_usage", graphTitle => "Host System " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^sys$/i, name => qr/^uptime$/i },
|
{ selector => { group => qr/^sys$/i, name => qr/^uptime$/i },
|
||||||
config => { groupBy => "name", graphName => "host_", graphTitle => "Host System and VM ", graphArgs => "--lower-limit 1000 --logarithmic --alt-autoscale-min" }
|
config => { groupBy => "name", graphName => "uptimes", graphTitle => "Host System and VM ", graphArgs => "--lower-limit 1000 --logarithmic --alt-autoscale-min" }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -281,31 +378,31 @@ foreach (@all_vms) {
|
||||||
my $vmName = clean_fieldname($resolveNames->{vm}->{$_});
|
my $vmName = clean_fieldname($resolveNames->{vm}->{$_});
|
||||||
push @all_graphs, (
|
push @all_graphs, (
|
||||||
{ selector => { group => qr/^cpu$/i, name => qr/^usagemhz$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^cpu$/i, name => qr/^usagemhz$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.cpu_", graphTitle => "CPU usage for " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_cpu", graphTitle => "CPU usage for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^mem$/i, unit => qr/^KB$/i, rollup => qr/^none$/, vm => qr/^$_$/ },
|
{ selector => { group => qr/^mem$/i, unit => qr/^KB$/i, rollup => qr/^none$/, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.memory_", graphTitle => "Memory usage for " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_memory", graphTitle => "Memory usage for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^datastore$/i, unit => qr/^Bytes$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^datastore$/i, unit => qr/^Bytes$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.datastore_", graphTitle => "Disk space usage for ", graphArgs => "--lower-limit 10485760 --logarithmic --alt-autoscale-min --units=si" }
|
config => { groupBy => "vm", graphName => "$vmName.vm_datastore", graphTitle => "Disk space usage for ", graphArgs => "--lower-limit 10485760 --logarithmic --alt-autoscale-min --units=si" }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^Millisecond$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^Millisecond$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.disklat_", graphTitle => "Disk latency for " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_disklat", graphTitle => "Disk latency for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^Number$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^Number$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.diskiops_", graphTitle => "Disk I/O operations for " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_diskiops", graphTitle => "Disk I/O operations for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^KBps$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^virtualDisk$/i, unit => qr/^KBps$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.disktrans_", graphTitle => "Disk transfer rates for " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_disktrans", graphTitle => "Disk transfer rates for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^net$/i, unit => qr/^KBps$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^net$/i, unit => qr/^KBps$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.traffic_net_", graphTitle => "Network traffic for " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_traffic_net", graphTitle => "Network traffic for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^net$/i, unit => qr/^Number$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^net$/i, unit => qr/^Number$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.packets_net_", graphTitle => "Network packets for " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_packets_net", graphTitle => "Network packets for " }
|
||||||
},
|
},
|
||||||
{ selector => { group => qr/^sys$/i, name => qr/^uptime$/i, vm => qr/^$_$/ },
|
{ selector => { group => qr/^sys$/i, name => qr/^uptime$/i, vm => qr/^$_$/ },
|
||||||
config => { groupBy => "vm", graphName => "$vmName.uptime_", graphTitle => "VM uptime " }
|
config => { groupBy => "vm", graphName => "$vmName.vm_uptime", graphTitle => "VM uptime " }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -313,9 +410,10 @@ foreach (@all_vms) {
|
||||||
# sensor graphs
|
# sensor graphs
|
||||||
push @all_graphs, (
|
push @all_graphs, (
|
||||||
{ selector => { group => qr/^sensors$/i },
|
{ selector => { group => qr/^sensors$/i },
|
||||||
config => { groupBy => "unit", graphName => "sensor_", graphTitle => "Sensors " }
|
config => { groupBy => "unit", graphName => "sensor_", graphTitle => "Sensors ", multiGraph => 1 }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
print "# time to collect all data: ", time() - $sstarttime, "\n" if $DEBUG;
|
||||||
|
|
||||||
# actual processing
|
# actual processing
|
||||||
foreach (@all_graphs) {
|
foreach (@all_graphs) {
|
||||||
|
@ -327,6 +425,8 @@ foreach (@all_graphs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print "# time of the script: ", time() - $sstarttime, "\n" if $DEBUG;
|
||||||
|
|
||||||
0;
|
0;
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
|
@ -350,6 +450,7 @@ sub process_value_array {
|
||||||
sub get_perf_data {
|
sub get_perf_data {
|
||||||
my $entity = shift;
|
my $entity = shift;
|
||||||
my @ret = ();
|
my @ret = ();
|
||||||
|
my $gathstart = time();
|
||||||
# get the current server time
|
# get the current server time
|
||||||
my $curtime = $iso8601->parse_datetime($dtsys->QueryDateTime());
|
my $curtime = $iso8601->parse_datetime($dtsys->QueryDateTime());
|
||||||
# and subtract 5 minutes to get all values for the last period
|
# and subtract 5 minutes to get all values for the last period
|
||||||
|
@ -375,12 +476,16 @@ sub get_perf_data {
|
||||||
unit => $perfDesc->unitInfo->label };
|
unit => $perfDesc->unitInfo->label };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
print "# time to gather info for $entity :", time() - $gathstart, "\n" if $DEBUG;
|
||||||
return @ret;
|
return @ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
# generate a munin-friendly and unique field name
|
# generate a munin-friendly and unique field name
|
||||||
sub gen_dp_name {
|
sub gen_dp_name {
|
||||||
return clean_fieldname("$_[0]->{name}v$_[0]->{vm}i$_[0]->{instance}");
|
my $fname = $_[0]->{name};
|
||||||
|
$fname .= "v".$resolveNames->{vmuuid}->{$_[0]->{vm}} unless $_[1] eq "vm" or $_[0]->{vm} eq "";
|
||||||
|
$fname .= "i$_[0]->{instance}" unless $_[1] eq "instance" or $_[0]->{instance} eq "";
|
||||||
|
return clean_fieldname($fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
# trim white spaces
|
# trim white spaces
|
||||||
|
@ -403,19 +508,23 @@ sub munin_print {
|
||||||
$par = $par->{selector};
|
$par = $par->{selector};
|
||||||
my $oldGroup = "_-_";
|
my $oldGroup = "_-_";
|
||||||
my $factor;
|
my $factor;
|
||||||
|
if ($ENV{flatview}) {
|
||||||
|
$cfg->{graphName} = clean_fieldname("Host_$host_name").".".$cfg->{graphName} unless $cfg->{graphName} =~ m/\./;
|
||||||
|
}
|
||||||
|
|
||||||
# find values according to criteria in $par and sort by grouping parameter
|
# find values according to criteria in $par and sort by grouping parameter
|
||||||
foreach (sort { $a->{$cfg->{groupBy}} cmp $b->{$cfg->{groupBy}} } grep { my $d = $_; all { (not exists $d->{$_}) || $d->{$_} =~ /$par->{$_}/ } keys %$par; } @$arr) {
|
#foreach (sort { $a->{$cfg->{groupBy}} cmp $b->{$cfg->{groupBy}} } grep { my $d = $_; all { (not exists $d->{$_}) || $d->{$_} =~ /$par->{$_}/ } keys %$par; } @$arr) {
|
||||||
my $groupCrit = $cfg->{groupBy};
|
foreach (sort { $a->{$cfg->{groupBy}} cmp $b->{$cfg->{groupBy}} } grep { my $d = $_; all { (not exists $d->{$_}) || $d->{$_} =~ /$par->{$_}/ } keys %$par; } @$arr) {
|
||||||
my $curGroup = $_->{$groupCrit};
|
my $groupCrit = $cfg->{groupBy} || "";
|
||||||
|
my $curGroup = $_->{$groupCrit} || "";
|
||||||
|
|
||||||
if (!($curGroup eq $oldGroup)) {
|
if (!($curGroup eq $oldGroup)) {
|
||||||
# we're in a new group, meaning a new graph starts
|
# we're in a new group, meaning a new graph starts
|
||||||
$factor = 0;
|
$factor = 0;
|
||||||
# clean up group name for multigraph name
|
# clean up group name for multigraph name
|
||||||
my $ccurGroup = $curGroup;
|
my $ccurGroup = $curGroup;
|
||||||
$ccurGroup =~ s/ |\./_/g;
|
$ccurGroup =~ s/ |\./_/g;
|
||||||
print "multigraph ",$cfg->{graphName},$ccurGroup,"\n";
|
print "multigraph ",$cfg->{graphName},(exists $cfg->{multiGraph}?$ccurGroup:""),"\n";
|
||||||
|
|
||||||
if ("config" eq $act) {
|
if ("config" eq $act) {
|
||||||
# want configuration
|
# want configuration
|
||||||
|
@ -457,7 +566,7 @@ sub munin_print {
|
||||||
|
|
||||||
}
|
}
|
||||||
$oldGroup = $curGroup;
|
$oldGroup = $curGroup;
|
||||||
my $dpName = gen_dp_name($_);
|
my $dpName = gen_dp_name($_, $groupCrit);
|
||||||
if ("config" eq $act) {
|
if ("config" eq $act) {
|
||||||
# want configuration
|
# want configuration
|
||||||
# get instance and VM names and UF names, if applicable
|
# get instance and VM names and UF names, if applicable
|
||||||
|
@ -485,7 +594,7 @@ sub munin_print {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
# just print value
|
# just print value
|
||||||
print gen_dp_name ($_), ".value $_->{value}\n";
|
print "$dpName.value $_->{value}\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue