3 # Nagios plugin to monitor vmware esx servers
6 # Copyright (c) 2008 op5 AB
7 # Author: Kostyantyn Hushchyn <>
8 # Contributor(s): Patrick Müller, Jeremy Martin, Eric Jonsson, stumpr, John Cavanaugh, Libor Klepac, maikmayers, Steffen Poulsen, Mark Elliott
10 # For direct contact with any of the op5 developers send a mail to
12 # Discussions are directed to the mailing list ,
13 # see http://lists.op5.com/mailman/listinfo/op5-users
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License version 2 as
17 # published by the Free Software Foundation.
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see
.
30 use vars qw($PROGNAME $VERSION $output $values $result);
33 my $perl_module_instructions="
34 Download the latest version of Perl Toolkit from VMware support page.
35 In this example we use VMware-vSphere-SDK-for-Perl-4.0.0-161974.x86_64.tar.gz,
36 but the instructions should apply to newer versions as well.
38 Upload the file to your op5 Monitor server's /root dir and execute:
41 tar xvzf VMware-vSphere-SDK-for-Perl-4.0.0-161974.x86_64.tar.gz
42 cd vmware-vsphere-cli-distrib/
45 Follow the on screen instructions, described below:
47 \"Creating a new vSphere CLI installer database using the tar4 format.
49 Installing vSphere CLI.
51 Installing version 161974 of vSphere CLI
53 You must read and accept the vSphere CLI End User License Agreement to
55 Press enter to display it.\"
59 \"Read through the License Agreement\"
60 \"Do you accept? (yes/no)
65 \"The following Perl modules were found on the system but may be too old to work
71 \"In which directory do you want to install the executable files? [/usr/bin]\"
75 \"Please wait while copying vSphere CLI files...
77 The installation of vSphere CLI 4.0.0 build-161974 for Linux completed
78 successfully. You can decide to remove this software from your system at any
79 time by invoking the following command:
80 \"/usr/bin/vmware-uninstall-vSphere-CLI.pl\".
82 This installer has successfully installed both vSphere CLI and the vSphere SDK
88 Note: \"Crypt::SSLeay\" and \"Compress::Zlib\" are not needed for check_esx3 to work.
93 require VMware::VIRuntime
94 } or Nagios::Plugin::Functions::nagios_exit(UNKNOWN, "Missing perl module VMware::VIRuntime. Download and install \'VMware Infrastructure (VI) Perl Toolkit\', available at http://www.vmware.com/download/sdk/\n $perl_module_instructions");
96 $PROGNAME = basename($0);
99 my $np = Nagios::Plugin->new(
100 usage => "Usage: %s -D
| -H [ -N ]\n"
104 . " [ -t
] [ -w ] [ -c ]\n"
108 shortname => uc($PROGNAME),
109 blurb => 'VMWare Infrastructure plugin',
110 extra => "Supported commands(^ means blank or not specified parameter) :\n"
111 . " Common options for VM, Host and DC :\n"
112 . " * cpu - shows cpu info\n"
113 . " + usage - CPU usage in percentage\n"
114 . " + usagemhz - CPU usage in MHz\n"
115 . " ^ all cpu info\n"
116 . " * mem - shows mem info\n"
117 . " + usage - mem usage in percentage\n"
118 . " + usagemb - mem usage in MB\n"
119 . " + swap - swap mem usage in MB\n"
120 . " + overhead - additional mem used by VM Server in MB\n"
121 . " + overall - overall mem used by VM Server in MB\n"
122 . " + memctl - mem used by VM memory control driver(vmmemctl) that controls ballooning\n"
123 . " ^ all mem info\n"
124 . " * net - shows net info\n"
125 . " + usage - overall network usage in KBps(Kilobytes per Second) \n"
126 . " + receive - receive in KBps(Kilobytes per Second) \n"
127 . " + send - send in KBps(Kilobytes per Second) \n"
128 . " ^ all net info\n"
129 . " * io - shows disk io info\n"
130 . " + read - read latency in ms (totalReadLatency.average)\n"
131 . " + write - write latency in ms (totalWriteLatency.average)\n"
132 . " ^ all disk io info\n"
133 . " * runtime - shows runtime info\n"
134 . " + status - overall host status (gray/green/red/yellow)\n"
135 . " + issues - all issues for the host\n"
136 . " ^ all runtime info\n"
138 . " * cpu - shows cpu info\n"
139 . " + wait - CPU wait time in ms\n"
140 . " + ready - CPU ready time in ms\n"
141 . " * mem - shows mem info\n"
142 . " + swapin - swapin mem usage in MB\n"
143 . " + swapout - swapout mem usage in MB\n"
144 . " + active - active mem usage in MB\n"
145 . " * io - shows disk I/O info\n"
146 . " + usage - overall disk usage in MB/s\n"
147 . " * runtime - shows runtime info\n"
148 . " + con - connection state\n"
149 . " + cpu - allocated CPU in MHz\n"
150 . " + mem - allocated mem in MB\n"
151 . " + state - virtual machine state (UP, DOWN, SUSPENDED)\n"
152 . " + consoleconnections - console connections to VM\n"
153 . " + guest - guest OS status, needs VMware Tools\n"
154 . " + tools - VMWare Tools status\n"
155 . " Host specific :\n"
156 . " * net - shows net info\n"
157 . " + nic - makes sure all active NICs are plugged in\n"
158 . " * io - shows disk io info\n"
159 . " + aborted - aborted commands count\n"
160 . " + resets - bus resets count\n"
161 . " + kernel - kernel latency in ms\n"
162 . " + device - device latency in ms\n"
163 . " + queue - queue latency in ms\n"
164 . " * vmfs - shows Datastore info\n"
165 . " + (name) - free space info for datastore with name (name)\n"
166 . " ^ all datastore info\n"
167 . " * runtime - shows runtime info\n"
168 . " + con - connection state\n"
169 . " + health - checks cpu/storage/memory/sensor status\n"
170 . " + maintenance - shows whether host is in maintenance mode\n"
171 . " + list(vm) - list of VMWare machines and their statuses\n"
172 . " * service - shows Host service info\n"
173 . " + (names) - check the state of one or several services specified by (names), syntax for (names):
,,...,\n"
174 . " ^ show all services\n"
175 . " * storage - shows Host storage info\n"
176 . " + adapter - list bus adapters\n"
177 . " + lun - list SCSI logical units\n"
178 . " + path - list logical unit paths\n"
180 . " * io - shows disk io info\n"
181 . " + aborted - aborted commands count\n"
182 . " + resets - bus resets count\n"
183 . " + kernel - kernel latency in ms\n"
184 . " + device - device latency in ms\n"
185 . " + queue - queue latency in ms\n"
186 . " * vmfs - shows Datastore info\n"
187 . " + (name) - free space info for datastore with name (name)\n"
188 . " ^ all datastore info\n"
189 . " * runtime - shows runtime info\n"
190 . " + list(vm) - list of VMWare machines and their statuses\n"
191 . " + listhost - list of VMWare esx host servers and their statuses\n"
192 . " + tools - VMWare Tools status\n"
193 . " * recommendations - shows recommendations for cluster\n"
194 . " + (name) - recommendations for cluster with name (name)\n"
195 . " ^ all clusters recommendations\n"
196 . "\n\nCopyright (c) 2008 op5",
202 help => "-H, --host=
\n"
203 . ' ESX or ESXi hostname.',
208 spec => 'cluster|C=s',
209 help => "-C, --cluster=
\n"
210 . ' ESX or ESXi clustername.',
215 spec => 'datacenter|D=s',
216 help => "-D, --datacenter=
\n"
217 . ' Datacenter hostname.',
223 help => "-N, --name=
\n"
224 . ' Virtual machine name.',
229 spec => 'username|u=s',
230 help => "-u, --username=
\n"
231 . ' Username to connect with.',
236 spec => 'password|p=s',
237 help => "-p, --password=
\n"
238 . ' Password to use with the username.',
243 spec => 'authfile|f=s',
244 help => "-f, --authfile=
\n"
245 . " Authentication file with login and password. File syntax :\n"
252 spec => 'warning|w=s',
253 help => "-w, --warning=THRESHOLD\n"
254 . " Warning threshold. See\n"
255 . " http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
256 . ' for the threshold format.',
261 spec => 'critical|c=s',
262 help => "-c, --critical=THRESHOLD\n"
263 . " Critical threshold. See\n"
264 . " http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
265 . ' for the threshold format.',
270 spec => 'command|l=s',
271 help => "-l, --command=COMMAND\n"
272 . ' Specify command type (CPU, MEM, NET, IO, VMFS, RUNTIME, ...)',
277 spec => 'subcommand|s=s',
278 help => "-s, --subcommand=SUBCOMMAND\n"
279 . ' Specify subcommand',
284 spec => 'sessionfile|S=s',
285 help => "-S, --sessionfile=SESSIONFILE\n"
286 . ' Specify a filename to store sessions for faster authentication',
291 spec => 'exclude|x=s',
292 help => "-x, --exclude=
\n"
293 . ' Specify black list',
298 spec => 'options|o=s',
299 help => "-o, --options=
\n"
300 . ' Specify additional command options',
306 my $host = $np->opts->host;
307 my $cluster = $np->opts->cluster;
308 my $datacenter = $np->opts->datacenter;
309 my $vmname = $np->opts->name;
310 my $username = $np->opts->username;
311 my $password = $np->opts->password;
312 my $authfile = $np->opts->authfile;
313 my $warning = $np->opts->warning;
314 my $critical = $np->opts->critical;
315 my $command = $np->opts->command;
316 my $subcommand = $np->opts->subcommand;
317 my $sessionfile = $np->opts->sessionfile;
318 my $blacklist = $np->opts->exclude;
319 my $addopts = $np->opts->options;
322 $output = "Unknown ERROR!";
325 if (defined($subcommand))
327 $subcommand = undef if ($subcommand eq '');
330 if (defined($critical))
332 ($percc, $critical) = check_percantage($critical);
333 $critical = undef if ($critical eq '');
336 if (defined($warning))
338 ($percw, $warning) = check_percantage($warning);
339 $warning = undef if ($warning eq '');
342 $np->set_thresholds(critical => $critical, warning => $warning);
346 die "Provide either Password/Username or Auth file or Session file\n" if ((!defined($password) || !defined($username) || defined($authfile)) && (defined($password) || defined($username) || !defined($authfile)) && (defined($password) || defined($username) || defined($authfile) || !defined($sessionfile)));
347 die "Both threshold values must be the same units\n" if (($percw && !$percc && defined($critical)) || (!$percw && $percc && defined($warning)));
348 if (defined($authfile))
350 open (AUTH_FILE, $authfile) || die "Unable to open auth file \"$authfile\"\n";
352 if(s/^[ \t]*username[ \t]*=//){
356 if(s/^[ \t]*password[ \t]*=//){
361 die "Auth file must contain both username and password\n" if (!(defined($username) && defined($password)));
366 if (defined($datacenter))
368 $host_address = $datacenter;
370 elsif (defined($host))
372 $host_address = $host;
376 $np->nagios_exit(CRITICAL, "No Host or Datacenter specified");
379 $host_address .= ":443" if (index($host_address, ":") == -1);
380 $host_address = "https://" . $host_address . "/sdk/webService";
382 if (defined($sessionfile) and -e $sessionfile)
384 Opts::set_option("sessionfile", $sessionfile);
386 Util::connect($host_address, $username, $password);
387 die "Connected host doesn't match reqested once\n" if (Opts::get_option("url") ne $host_address);
390 Opts::set_option("sessionfile", undef);
391 Util::connect($host_address, $username, $password);
396 Util::connect($host_address, $username, $password);
399 if (defined($sessionfile))
401 Vim::save_session(session_file => $sessionfile);
403 $command = uc($command);
404 if (defined($vmname))
406 if ($command eq "CPU")
408 ($result, $output) = vm_cpu_info($vmname, $np, local_uc($subcommand));
410 elsif ($command eq "MEM")
412 ($result, $output) = vm_mem_info($vmname, $np, local_uc($subcommand));
414 elsif ($command eq "NET")
416 ($result, $output) = vm_net_info($vmname, $np, local_uc($subcommand));
418 elsif ($command eq "IO")
420 ($result, $output) = vm_disk_io_info($vmname, $np, local_uc($subcommand));
422 elsif ($command eq "RUNTIME")
424 ($result, $output) = vm_runtime_info($vmname, $np, local_uc($subcommand));
428 $output = "Unknown HOST-VM command\n" . $np->opts->_help;
432 elsif (defined($host))
435 $esx = {name => $host} if (defined($datacenter));
436 if ($command eq "CPU")
438 ($result, $output) = host_cpu_info($esx, $np, local_uc($subcommand), $addopts);
440 elsif ($command eq "MEM")
442 ($result, $output) = host_mem_info($esx, $np, local_uc($subcommand), $addopts);
444 elsif ($command eq "NET")
446 ($result, $output) = host_net_info($esx, $np, local_uc($subcommand));
448 elsif ($command eq "IO")
450 ($result, $output) = host_disk_io_info($esx, $np, local_uc($subcommand));
452 elsif ($command eq "VMFS")
454 ($result, $output) = host_list_vm_volumes_info($esx, $np, $subcommand, $blacklist, $percc || $percw, $addopts);
456 elsif ($command eq "RUNTIME")
458 ($result, $output) = host_runtime_info($esx, $np, local_uc($subcommand), $blacklist);
460 elsif ($command eq "SERVICE")
462 ($result, $output) = host_service_info($esx, $np, $subcommand);
464 elsif ($command eq "STORAGE")
466 ($result, $output) = host_storage_info($esx, $np, local_uc($subcommand), $blacklist);
470 $output = "Unknown HOST command\n" . $np->opts->_help;
474 elsif (defined($cluster))
476 if ($command eq "CPU")
478 ($result, $output) = cluster_cpu_info($cluster, $np, local_uc($subcommand));
480 elsif ($command eq "MEM")
482 ($result, $output) = cluster_mem_info($cluster, $np, local_uc($subcommand), $addopts);
484 elsif ($command eq "CLUSTER")
486 ($result, $output) = cluster_cluster_info($cluster, $np, local_uc($subcommand));
488 elsif ($command eq "VMFS")
490 ($result, $output) = cluster_list_vm_volumes_info($cluster, $np, $subcommand, $blacklist, $percc || $percw, $addopts);
492 elsif ($command eq "RUNTIME")
494 ($result, $output) = cluster_runtime_info($cluster, $np, local_uc($subcommand), $blacklist);
498 $output = "Unknown CLUSTER command\n" . $np->opts->_help;
504 if ($command eq "RECOMMENDATIONS")
507 $cluster_name = {name => $subcommand} if (defined($subcommand));
508 ($result, $output) = return_cluster_DRS_recommendations($np, $cluster_name);
510 elsif ($command eq "CPU")
512 ($result, $output) = dc_cpu_info($np, local_uc($subcommand), $addopts);
514 elsif ($command eq "MEM")
516 ($result, $output) = dc_mem_info($np, local_uc($subcommand), $addopts);
518 elsif ($command eq "NET")
520 ($result, $output) = dc_net_info($np, local_uc($subcommand));
522 elsif ($command eq "IO")
524 ($result, $output) = dc_disk_io_info($np, local_uc($subcommand));
526 elsif ($command eq "VMFS")
528 ($result, $output) = dc_list_vm_volumes_info($np, $subcommand, $blacklist, $percc || $percw, $addopts);
530 elsif ($command eq "RUNTIME")
532 ($result, $output) = dc_runtime_info($np, local_uc($subcommand), $blacklist);
536 $output = "Unknown HOST command\n" . $np->opts->_help;
543 if (uc(ref($@)) eq "HASH")
546 $result = $@->{code};
556 $np->nagios_exit($result, $output);
558 #######################################################################################################################################################################
560 sub get_key_metrices {
561 my ($perfmgr_view, $group, @names) = @_;
563 my $perfCounterInfo = $perfmgr_view->perfCounter;
566 die "Insufficient rights to access perfcounters\n" if (!defined($perfCounterInfo));
568 foreach (@$perfCounterInfo) {
569 if ($_->groupInfo->key eq $group) {
570 my $cur_name = $_->nameInfo->key . "." . $_->rollupType->val;
571 foreach my $index (0..@names-1)
573 if ($names[$index] =~ /$cur_name/)
575 $names[$index] =~ /(\w+).(\w+):*(.*)/;
576 $counters[$index] = PerfMetricId->new(counterId => $_->key, instance => $3);
585 sub generic_performance_values {
586 my ($views, $group, @list) = @_;
590 my $perfMgr = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager, properties => [ 'perfCounter' ]);
591 my $metrices = get_key_metrices($perfMgr, $group, @list);
593 my @perf_query_spec = ();
594 push(@perf_query_spec, PerfQuerySpec->new(entity => $_, metricId => $metrices, format => 'csv', intervalId => 20, maxSample => 1)) foreach (@$views);
595 my $perf_data = $perfMgr->QueryPerf(querySpec => \@perf_query_spec);
596 $amount *= @$perf_data;
600 my $unsorted = shift(@$perf_data)->value;
601 my @host_values = ();
603 foreach my $id (@$unsorted)
605 foreach my $index (0..@$metrices-1)
607 if ($id->id->counterId == $$metrices[$index]->counterId)
609 $counter++ if (!defined($host_values[$index]));
610 $host_values[$index] = $id;
614 push(@values, \@host_values);
616 return undef if ($counter != $amount || $counter == 0);
620 sub return_host_performance_values {
622 my $host_name = shift(@_);
623 my $host_view = Vim::find_entity_views(view_type => 'HostSystem', filter => $host_name, properties => [ 'name', 'runtime.inMaintenanceMode' ]); # Added properties named argument.
624 die "Runtime error\n" if (!defined($host_view));
625 die "Host \"" . $$host_name{"name"} . "\" does not exist\n" if (!@$host_view);
626 die {msg => ("NOTICE: \"" . $$host_view[0]->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($$host_view[0]->get_property('runtime.inMaintenanceMode')) eq "TRUE");
627 $values = generic_performance_values($host_view, @_);
629 return undef if ($@);
630 return ($host_view, $values);
633 sub return_host_vmware_performance_values {
635 my $vmname = shift(@_);
636 my $vm_view = Vim::find_entity_views(view_type => 'VirtualMachine', filter => {name => "$vmname"}, properties => [ 'name', 'runtime.powerState' ]);
637 die "Runtime error\n" if (!defined($vm_view));
638 die "VMware machine \"" . $vmname . "\" does not exist\n" if (!@$vm_view);
639 die "VMware machine \"" . $vmname . "\" is not running. Current state is \"" . $$vm_view[0]->get_property('runtime.powerState')->val . "\"\n" if ($$vm_view[0]->get_property('runtime.powerState')->val ne "poweredOn");
640 $values = generic_performance_values($vm_view, @_);
643 return ($vm_view, $values);
646 sub return_dc_performance_values {
648 my $host_views = Vim::find_entity_views(view_type => 'HostSystem', properties => [ 'name' ]);
649 die "Runtime error\n" if (!defined($host_views));
650 die "Datacenter does not contain any hosts\n" if (!@$host_views);
651 $values = generic_performance_values($host_views, @_);
653 return undef if ($@);
654 return ($host_views, $values);
657 sub return_cluster_performance_values {
659 my $cluster_name = shift(@_);
660 my $cluster_view = Vim::find_entity_views(view_type => 'ClusterComputeResource', filter => { name => "$cluster_name" }, properties => [ 'name' ]); # Added properties named argument.
661 die "Runtime error\n" if (!defined($cluster_view));
662 die "Cluster \"" . $cluster_name . "\" does not exist\n" if (!@$cluster_view);
663 $values = generic_performance_values($cluster_view, @_);
665 return undef if ($@);
669 # Temporary solution to overcome zeros in network output
670 sub return_host_temporary_vc_4_1_network_performance_values {
672 my ($host_name, @list) = @_;
674 my $host_view = Vim::find_entity_views(view_type => 'HostSystem', filter => $host_name, properties => [ 'name', 'runtime.inMaintenanceMode', 'summary.config.product.version' ]); # Added properties named argument.
675 die "Runtime error\n" if (!defined($host_view));
676 die "Host \"" . $$host_name{"name"} . "\" does not exist\n" if (!@$host_view);
677 die {msg => ("NOTICE: \"" . $$host_view[0]->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($$host_view[0]->get_property('runtime.inMaintenanceMode')) eq "TRUE");
678 my $software_version = $$host_view[0]->get_property('summary.config.product.version');
679 return undef if (substr($software_version, 0, 4) ne '4.1.');
681 my $perfMgr = Vim::get_view(mo_ref => Vim::get_service_content()->perfManager, properties => [ 'perfCounter' ]);
682 my $metrices = get_key_metrices($perfMgr, 'net', @list);
685 my @perf_query_spec = ();
686 push(@perf_query_spec, PerfQuerySpec->new(entity => $_, metricId => $metrices, format => 'csv', intervalId => 20, maxSample => 1)) foreach (@$host_view);
687 my $perf_data = $perfMgr->QueryPerf(querySpec => \@perf_query_spec);
688 $amount *= @$perf_data;
693 my $unsorted = shift(@$perf_data)->value;
694 my @host_values = ();
696 foreach my $id (@$unsorted)
698 foreach my $index (0..@$metrices-1)
700 if ($id->id->counterId == $$metrices[$index]->counterId)
702 if (!defined($host_values[$index]))
705 $host_values[$index] = bless({ 'value' => '0' }, "PerfMetricSeriesCSV");
707 $host_values[$index]{"value"} += convert_number($id->value) if ($id->id->instance ne '');
711 push(@values, \@host_values);
714 return undef if ($counter != $amount || $counter == 0 || $@);
715 return ($host_view, \@values);
717 # Remove as soon as possible
721 my ($val) = shift(@_);
722 return defined($val)?uc($val):undef;
727 my ($number, $cnt) = @_;
728 $cnt = 2 if (!defined($cnt));
729 return sprintf("%.${cnt}f", "$number");
734 my @vals = split(/,/, shift(@_));
735 return shift(@vals) if ($vals[-1] < 0);
741 my ($number) = shift(@_);
742 my $perc = $number =~ s/\%//;
743 return ($perc, $number);
746 sub check_health_state
748 my ($state) = shift(@_);
751 if (uc($state) eq "GREEN") {
753 } elsif (uc($state) eq "YELLOW") {
755 } elsif (uc($state) eq "RED") {
763 my ($issue) = shift(@_);
767 if (defined($issue->datacenter))
769 $output .= 'Datacenter "' . $issue->datacenter->name . '", ';
771 if (defined($issue->host))
773 $output .= 'Host "' . $issue->host->name . '", ';
775 if (defined($issue->vm))
777 $output .= 'VM "' . $issue->vm->name . '", ';
779 if (defined($issue->computeResource))
781 $output .= 'Compute Resource "' . $issue->computeResource->name . '", ';
783 if (exists($issue->{dvs}) && defined($issue->dvs))
785 # Since vSphere API 4.0
786 $output .= 'Virtual Switch "' . $issue->dvs->name . '", ';
788 if (exists($issue->{ds}) && defined($issue->ds))
790 # Since vSphere API 4.0
791 $output .= 'Datastore "' . $issue->ds->name . '", ';
793 if (exists($issue->{net}) && defined($issue->net))
795 # Since vSphere API 4.0
796 $output .= 'Network "' . $issue->net->name . '" ';
800 $output .= ": " . $issue->fullFormattedMessage;
801 $output .= "(caused by " . $issue->userName . ")" if ($issue->userName ne "");
806 sub datastore_volumes_info
808 my ($datastore, $np, $subcommand, $blacklist, $perc, $addopts) = @_;
817 $usedflag = $addopts =~ m/(^|\s|\t|,)\Qused\E($|\s|\t|,)/ if (defined($addopts));
818 $briefflag = $addopts =~ m/(^|\s|\t|,)\Qbrief\E($|\s|\t|,)/ if (defined($addopts));
819 $regexpflag = $addopts =~ m/(^|\s|\t|,)\Qregexp\E($|\s|\t|,)/ if (defined($addopts));
820 $blackregexpflag = $addopts =~ m/(^|\s|\t|,)\Qblacklistregexp\E($|\s|\t|,)/ if (defined($addopts));
822 die "Blacklist is supported only in generic check or regexp subcheck\n" if (defined($subcommand) && defined($blacklist) && !defined($regexpflag));
824 if (defined($regexpflag) && defined($subcommand))
832 $@ =~ s/ at.*line.*\.//;
838 foreach my $ref_store (@{$datastore})
840 my $store = Vim::get_view(mo_ref => $ref_store, properties => ['summary', 'info']);
841 my $name = $store->summary->name;
842 if (!defined($subcommand) || ($name eq $subcommand) || (defined($regexpflag) && $name =~ /$subcommand/))
844 if (defined($blacklist))
846 next if ($blackregexpflag?$name =~ /$blacklist/:$blacklist =~ m/(^|\s|\t|,)\Q$name\E($|\s|\t|,)/);
849 if ($store->summary->accessible)
851 my $value1 = simplify_number(convert_number($store->summary->freeSpace) / 1024 / 1024);
852 my $value2 = convert_number($store->summary->capacity);
853 $value2 = simplify_number(convert_number($store->info->freeSpace) / $value2 * 100) if ($value2 > 0);
857 $value1 = simplify_number(convert_number($store->summary->capacity) / 1024 / 1024) - $value1;
858 $value2 = 100 - $value2;
861 $state = $np->check_threshold(check => $perc?$value2:$value1);
862 $res = Nagios::Plugin::Functions::max_state($res, $state);
863 $np->add_perfdata(label => $name, value => $perc?$value2:$value1, uom => $perc?'%':'MB', threshold => $np->threshold);
864 $output .= $name . "=". $value1 . " MB (" . $value2 . "%), " if (!$briefflag || $state != OK);
869 $output .= $name . " is not accessible, ";
871 last if (!$regexpflag && defined($subcommand) && ($name eq $subcommand));
872 $blacklist .= $blackregexpflag?"|^$name\$":",$name";
880 $output = "Storages : " . $output;
886 $output = "There are no alerts";
891 $output = defined($subcommand)?$regexpflag? "No matching volumes for regexp \"$subcommand\" found":"No volume named \"$subcommand\" found":"There are no volumes";
895 return ($res, $output);
898 #=====================================================================| HOST |============================================================================#
902 my ($host, $np, $subcommand, $addopts) = @_;
905 my $output = 'HOST CPU Unknown error';
908 $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));
910 if (defined($subcommand))
912 if ($subcommand eq "USAGE")
915 if (defined($quickStats))
917 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
918 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
919 die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
920 $values = $host_view->get_property('summary.quickStats');
921 my $hardinfo = $host_view->get_property('summary.hardware');
922 $value = simplify_number($values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100) if exists($values->{overallCpuUsage}) && defined($hardinfo);
926 $values = return_host_performance_values($host, 'cpu', ('usage.average'));
927 $value = simplify_number(convert_number($$values[0][0]->value) * 0.01) if (defined($values));
931 $np->add_perfdata(label => "cpu_usage", value => $value, uom => '%', threshold => $np->threshold);
932 $output = "cpu usage=" . $value . " %";
933 $res = $np->check_threshold(check => $value);
936 elsif ($subcommand eq "USAGEMHZ")
939 if (defined($quickStats))
941 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.quickStats']);
942 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
943 die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
944 $values = $host_view->get_property('summary.quickStats');
945 $value = simplify_number($values->overallCpuUsage) if exists($values->{overallCpuUsage});
949 $values = return_host_performance_values($host, 'cpu', ('usagemhz.average'));
950 $value = simplify_number(convert_number($$values[0][0]->value)) if (defined($values));
954 $np->add_perfdata(label => "cpu_usagemhz", value => $value, uom => 'Mhz', threshold => $np->threshold);
955 $output = "cpu usagemhz=" . $value . " MHz";
956 $res = $np->check_threshold(check => $value);
962 $output = "HOST CPU - unknown subcommand\n" . $np->opts->_help;
969 if (defined($quickStats))
971 my $host_view = Vim::find_entity_view(view_type => 'HostSystem', filter => $host, properties => ['name', 'runtime.inMaintenanceMode', 'summary.hardware', 'summary.quickStats']);
972 die "Host \"" . $$host{"name"} . "\" does not exist\n" if (!defined($host_view));
973 die {msg => ("NOTICE: \"" . $host_view->name . "\" is in maintenance mode, check skipped\n"), code => OK} if (uc($host_view->get_property('runtime.inMaintenanceMode')) eq "TRUE");
974 $values = $host_view->get_property('summary.quickStats');
975 my $hardinfo = $host_view->get_property('summary.hardware');
976 if (exists($values->{overallCpuUsage}) && defined($hardinfo))
978 $value1 = simplify_number($values->overallCpuUsage);
979 $value2 = simplify_number($values->overallCpuUsage / ($hardinfo->numCpuCores * $hardinfo->cpuMhz) * 100);
984 $values = return_host_performance_values($host, 'cpu', ('usagemhz.average', 'usage.average'));
986 $value1 = simplify_number(convert_number($$values[0][0]->value));
987 $value2 = simplify_number(convert_number($$values[0][1]->value) * 0.01);
990 if (defined($value1) && defined($value2))
992 $np->add_perfdata(label => "cpu_usagemhz", value => $value1, uom => 'Mhz', threshold => $np->threshold);
993 $np->add_perfdata(label => "cpu_usage", value => $value2, uom => '%', threshold => $np->threshold);
995 $output = "cpu usage=" . $value1 . " MHz (" . $value2 . "%)";
999 return ($res, $output);
1004 my ($host, $np, $subcommand, $addopts) = @_;
1007 my $output = 'HOST MEM Unknown error';
1011 $quickStats = $addopts =~ m/(^|\s|\t|,)\Qquickstats\E($|\s|\t|,)/ if (defined($addopts));
1012 $outputlist = $addopts =~ m/(^|\s|\t|,)\Qlistvm\E($|\s|\t|,)/ if (defined($addopts));
1014 if (defined($subcommand))
1016 if ($subcommand eq "USAGE")