From fc06521642ea9f2217696fe05d88beb02a9b17bd Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 6 Jun 2019 11:18:29 +0200 Subject: [PATCH] add dell me4 plugin --- .../storage/dell/me4/custom/api.pm | 6 + .../me4/mode/components/.temperature.pm.swp | Bin 0 -> 16384 bytes .../dell/me4/mode/components/controller.pm | 67 +++++ .../storage/dell/me4/mode/components/disk.pm | 85 ++++++ .../storage/dell/me4/mode/components/fan.pm | 80 ++++++ .../storage/dell/me4/mode/components/fru.pm | 58 ++++ .../storage/dell/me4/mode/components/psu.pm | 63 +++++ .../dell/me4/mode/components/sensor.pm | 104 +++++++ .../dell/me4/mode/components/volume.pm | 58 ++++ .../dell/me4/mode/controllerstatistics.pm | 263 ++++++++++++++++++ .../storage/dell/me4/mode/hardware.pm | 186 +++++++++++++ .../storage/dell/me4/mode/listcontrollers.pm | 104 +++++++ .../storage/dell/me4/mode/listvolumes.pm | 2 +- .../storage/dell/me4/mode/volumestatistics.pm | 241 ++++++++++++++++ centreon-plugins/storage/dell/me4/plugin.pm | 6 +- 15 files changed, 1321 insertions(+), 2 deletions(-) create mode 100644 centreon-plugins/storage/dell/me4/mode/components/.temperature.pm.swp create mode 100644 centreon-plugins/storage/dell/me4/mode/components/controller.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/components/disk.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/components/fan.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/components/fru.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/components/psu.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/components/sensor.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/components/volume.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/controllerstatistics.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/hardware.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/listcontrollers.pm create mode 100644 centreon-plugins/storage/dell/me4/mode/volumestatistics.pm diff --git a/centreon-plugins/storage/dell/me4/custom/api.pm b/centreon-plugins/storage/dell/me4/custom/api.pm index 898f19de2..0539ef3ae 100644 --- a/centreon-plugins/storage/dell/me4/custom/api.pm +++ b/centreon-plugins/storage/dell/me4/custom/api.pm @@ -138,6 +138,12 @@ sub settings { $self->{http}->set_options(%{$self->{option_results}}); } +sub get_hostname { + my ($self, %options) = @_; + + return $self->{hostname}; +} + sub get_session_key { my ($self, %options) = @_; diff --git a/centreon-plugins/storage/dell/me4/mode/components/.temperature.pm.swp b/centreon-plugins/storage/dell/me4/mode/components/.temperature.pm.swp new file mode 100644 index 0000000000000000000000000000000000000000..cd2e0ca07f57e064aa4e2640df48c207ce2833ec GIT binary patch literal 16384 zcmeHNL5$;88GgIavZa(3kT}21&NLZq63+}(OEbHxW;0mVQ4qZ(o`J9xR=oH}#KZKr^5j& zGy|Fe&46Y=GoTsJ3}^;41OI~z2#c{VL$8PQz>n|$>GS`;Uu5hL!0&-?1G_*4xDNdN z^Njrjcno|CXaRe`CE(XDpl$#t1J47`0at+cKZkR`&w(EUKLWl7oC3$d6nF^Ozysh8 zum@ZMe)>FPW8hif8Q`CvW$Z7&`@j!?5U2rHfImIQ*l&Sv099Ze_#<9gJOo|>UIhO9 z8OA;U_JH3!%h(Cv1OIx4u^$3`;CG*9>{q}qfB>ifkMRhN_F9 zC6wq3%PK82oh|nAx}Ucnj=ezjC*g=D3;h7qBEwRlmz8ty;(A!*cF5Q1uTbXM()R1O zoBOn)d-eUp<}80|b=8YLw4jZRoiiG)EGt=Gyr@v3{KQr#F&pyOR@)gJ_K=sZt_-%r zJ`Aa%u=Geck<1O`RI-Ai7CKb)j=-~HD}}<9*rHn-8~k*k*W`qk){^=78Y*F2tj~lZ z^fQ*`k+e4WO+KG|Bvn6EwC_d}Xl#~3X)4=uS9f>~4Fid9P+WuB?~A?}k9xv`U4 zGq3Pk;x>G3BK$t>pFWi@&N6Gb@>p@AH8b-?w&Yje<;MNZ%Ign|oH-ZjeBwTs*pyt6 zT=Ho>vD>Tn4!fC`ek|AfZ#}R45gjk~yYs!Pl!XdQ4h4b?{OMv(JIAF~7|E=^Fkb3h z=lwp}GnP3%PYNB&Bz;IISymUNOLQw?CF_3#0|?|7z2uJxonr=1#wOb?b4kt&o`(2?4?S>vXsgfqK-eFyiqPx!b?ftnc^k^mpsMI-Tn^@4ngWAjou@X>&G9ZzR`X zxEls_xfQEPZEQChomQ{asPFSQnnT&bE3XzfWd=734e5k-6c&u7A@xJ@@7##(Cyh9h zdSnB)H=i&tv3xe*;AmNy{rT0F^{Gz=HauXZBjpHLFG?);skTAatw6-VjH8~q&?Mgtx%5y?*6a6Do0 zQ$AyCejhKIi3=9v)TL1@GYDBva|(zlF&2fAQ&xm|!=1PlDkMD$v--k35+lje1i4mA zYKUvKv0tm9invxw%7|+Ew*I9)mZX<8zsx3 ztfE6#%KRaYD?4t7zBKKjZE{Drqlh#bdB`P6WsbagVuxWYRJazTyw&R6IXLX`x9Xiv zz1?dyyZoTT8wc%OT&f3cw7$mc?YH^YTkYL4mo}6LxICuF7jn#KPZ0K`MG9FqaWROL zv{p5y1Sa1B38HX$q2A@KZh_yfcU#>uWE{E<2@d2pBRhbc!3oa-D^@h6ImIZDIHx?s zWIjc5ilxDkyrH7f?U+4sfw5A4%`m3ZX;r{DV_Efrk%1sh42H&jtI=$Co0aYAW<2C= zFX9t%!o7hKkSmb9_-GB!kSr9GJel{TTL3wP8e?&Y=n}-3(x+QRocTC5Jy-E5NXrW$ zuI6^k6IG9OOwW}0JsFUpIP~KsvVCDbhR|u? literal 0 HcmV?d00001 diff --git a/centreon-plugins/storage/dell/me4/mode/components/controller.pm b/centreon-plugins/storage/dell/me4/mode/components/controller.pm new file mode 100644 index 000000000..294c23080 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/components/controller.pm @@ -0,0 +1,67 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::components::controller; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{controllers} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/controllers'); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking controllers"); + $self->{components}->{controller} = {name => 'controllers', total => 0, skip => 0}; + return if ($self->check_filter(section => 'controller')); + return if (!defined($self->{json_results}->{controllers})); + + foreach my $result (@{$self->{json_results}->{controllers}->{controllers}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'controller', instance => $instance)); + + $self->{components}->{controller}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Controller '%s' status is '%s', health is '%s', redundancy status is '%s'", + $result->{'durable-id'}, $result->{status}, $result->{health}, $result->{'redundancy-status'})); + + my $exit1 = $self->get_severity(section => 'controller', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Controller '%s' status is '%s'", $result->{'durable-id'}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'controller', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Controller '%s' health is '%s'", $result->{'durable-id'}, $result->{health})); + } + my $exit3 = $self->get_severity(section => 'controller', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Controller '%s' redundancy status is '%s'", $result->{'redundancy-status'}, $result->{health})); + } + } +} + +1; diff --git a/centreon-plugins/storage/dell/me4/mode/components/disk.pm b/centreon-plugins/storage/dell/me4/mode/components/disk.pm new file mode 100644 index 000000000..be7faf39a --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/components/disk.pm @@ -0,0 +1,85 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::components::disk; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{disks} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/disks'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disks"); + $self->{components}->{disk} = {name => 'disks', total => 0, skip => 0}; + return if ($self->check_filter(section => 'disk')); + return if (!defined($self->{json_results}->{disks})); + + foreach my $result (@{$self->{json_results}->{disks}->{drives}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'disk', instance => $instance)); + + $self->{components}->{disk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Disk '%s' status is '%s', health is '%s', state is '%s' [instance = %s] [temperature = %s C]", + $result->{'serial-number'}, $result->{status}, $result->{health}, $result->{state}, $instance, + $result->{'temperature-numeric'})); + + my $exit1 = $self->get_severity(section => 'disk', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Disk '%s' status is '%s'", $result->{'serial-number'}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'disk', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Disk '%s' health is '%s'", $result->{'serial-number'}, $result->{health})); + } + my $exit3 = $self->get_severity(section => 'disk', value => $result->{state}); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Disk '%s' state is '%s'", $result->{'serial-number'}, $result->{state})); + } + + next if ($result->{'temperature-numeric'} !~ /[0-9]/); + my ($exit4, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'disk', instance => $instance, value => $result->{'temperature-numeric'}); + if (!$self->{output}->is_status(value => $exit4, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit4, + short_msg => sprintf("Disk '%s' temperature is %s C", $result->{'serial-number'}, $result->{'temperature-numeric'})); + } + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.disk.temperature.celsius', + instances => $instance, + value => $result->{'temperature-numeric'}, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +1; diff --git a/centreon-plugins/storage/dell/me4/mode/components/fan.pm b/centreon-plugins/storage/dell/me4/mode/components/fan.pm new file mode 100644 index 000000000..81e915a71 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/components/fan.pm @@ -0,0 +1,80 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::components::fan; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{fans} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/fans'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + return if (!defined($self->{json_results}->{fans})); + + foreach my $result (@{$self->{json_results}->{fans}->{fan}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s', health is '%s' [instance = %s] [speed = %s rpm]", + $result->{name}, $result->{status}, $result->{health}, $instance, + $result->{speed})); + + my $exit1 = $self->get_severity(section => 'fan', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Fan '%s' status is '%s'", $result->{name}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'fan', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Fan '%s' health is '%s'", $result->{name}, $result->{health})); + } + + next if ($result->{speed} !~ /[0-9]/); + my ($exit3, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{speed}); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Fan '%s' speed is %s rpm", $result->{name}, $result->{speed})); + } + $self->{output}->perfdata_add( + label => 'speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{speed}, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +1; diff --git a/centreon-plugins/storage/dell/me4/mode/components/fru.pm b/centreon-plugins/storage/dell/me4/mode/components/fru.pm new file mode 100644 index 000000000..f9f964c61 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/components/fru.pm @@ -0,0 +1,58 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::components::fru; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{frus} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/frus'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking FRUs"); + $self->{components}->{fru} = {name => 'frus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fru')); + return if (!defined($self->{json_results}->{frus})); + + foreach my $result (@{$self->{json_results}->{frus}->{'enclosure-fru'}}) { + my $instance = $result->{name}; + + next if ($self->check_filter(section => 'fru', instance => $instance)); + + $self->{components}->{fru}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("FRU '%s' status is '%s'", + $result->{name}, $result->{'fru-status'})); + + my $exit1 = $self->get_severity(section => 'fru', value => $result->{'fru-status'}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("FRU '%s' status is '%s'", $result->{name}, $result->{'fru-status'})); + } + } +} + +1; diff --git a/centreon-plugins/storage/dell/me4/mode/components/psu.pm b/centreon-plugins/storage/dell/me4/mode/components/psu.pm new file mode 100644 index 000000000..c131a8e1d --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/components/psu.pm @@ -0,0 +1,63 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::components::psu; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{psus} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/power-supplies'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + return if (!defined($self->{json_results}->{psus})); + + foreach my $result (@{$self->{json_results}->{psus}->{'power-supplies'}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'psu', instance => $instance)); + + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Power supply '%s' status is '%s', health is '%s' [instance = %s]", + $result->{name}, $result->{status}, $result->{health}, $instance)); + + my $exit1 = $self->get_severity(section => 'psu', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Power supply '%s' status is '%s'", $result->{name}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'psu', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Power supply '%s' health is '%s'", $result->{name}, $result->{health})); + } + } +} + +1; diff --git a/centreon-plugins/storage/dell/me4/mode/components/sensor.pm b/centreon-plugins/storage/dell/me4/mode/components/sensor.pm new file mode 100644 index 000000000..aecc80916 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/components/sensor.pm @@ -0,0 +1,104 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::components::sensor; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{sensors} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/sensors'); +} + +my %mapping = ( + 'Voltage' => { + unit => 'V', + nlabel => 'voltage', + nunit => 'volt', + regexp => qr/(\d+)/ + }, + 'Current' => { + unit => 'A', + nlabel => 'current', + nunit => 'ampere', + regexp => qr/(\d+)/ + }, + 'Temperature' => { + unit => 'C', + nlabel => 'temperature', + nunit => 'celsius', + regexp => qr/(\d+)\sC/ + }, + 'Charge Capacity' => { + unit => '%', + nlabel => 'capacity', + nunit => 'percentage', + regexp => qr/(\d+)%/ + }, +); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking sensors"); + $self->{components}->{sensor} = {name => 'sensors', total => 0, skip => 0}; + return if ($self->check_filter(section => 'sensor')); + return if (!defined($self->{json_results}->{sensors})); + + foreach my $result (@{$self->{json_results}->{sensors}->{sensors}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'sensor', instance => $instance)); + + $self->{components}->{sensor}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance = %s] [value = %s]", + $result->{'sensor-name'}, $result->{status}, $instance, + $result->{value})); + + my $exit1 = $self->get_severity(section => 'sensor', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("sensor '%s' status is '%s'", $result->{'sensor-name'}, $result->{status})); + } + + next if (!defined($mapping{$result->{'sensor-type'}})); + next if ($result->{value} !~ $mapping{$result->{'sensor-type'}}->{regexp}); + my $value = $1; + my ($exit3, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'sensor', instance => $instance, value => $value); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Sensor '%s' value is %s %s", $result->{'sensor-name'}, $value, $mapping{$result->{'sensor-type'}}->{nunit})); + } + $self->{output}->perfdata_add( + label => 'sensor', unit => $mapping{$result->{'sensor-type'}}->{unit}, + nlabel => 'hardware.sensor.' . $mapping{$result->{'sensor-type'}}->{nlabel} . '.' . $mapping{$result->{'sensor-type'}}->{nunit}, + instances => $instance, + value => $value, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +1; diff --git a/centreon-plugins/storage/dell/me4/mode/components/volume.pm b/centreon-plugins/storage/dell/me4/mode/components/volume.pm new file mode 100644 index 000000000..10317beb3 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/components/volume.pm @@ -0,0 +1,58 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::components::volume; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{volumes} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/volumes'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking volumes"); + $self->{components}->{volume} = {name => 'volumes', total => 0, skip => 0}; + return if ($self->check_filter(section => 'volume')); + return if (!defined($self->{json_results}->{volumes})); + + foreach my $result (@{$self->{json_results}->{volumes}->{volumes}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'volume', instance => $instance)); + + $self->{components}->{volume}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Volume '%s' health is '%s' [instance = %s]", + $result->{'volume-name'}, $result->{health}, $instance)); + + my $exit1 = $self->get_severity(section => 'volume', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Volume '%s' health is '%s'", $result->{'volume-name'}, $result->{health})); + } + } +} + +1; diff --git a/centreon-plugins/storage/dell/me4/mode/controllerstatistics.pm b/centreon-plugins/storage/dell/me4/mode/controllerstatistics.pm new file mode 100644 index 000000000..0053b6be3 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/controllerstatistics.pm @@ -0,0 +1,263 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::controllerstatistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'controllers', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All controllers statistics are ok' } + ]; + + $self->{maps_counters}->{controllers} = [ + { label => 'data-read', nlabel => 'controller.data.read.bytespersecond', set => { + key_values => [ { name => 'data-read-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Read: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_read', value => 'data-read-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-written', nlabel => 'controller.data.written.bytespersecond', set => { + key_values => [ { name => 'data-written-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Written: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_written', value => 'data-written-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'reads', nlabel => 'controller.reads.count', set => { + key_values => [ { name => 'number-of-reads', diff => 1 }, { name => 'display'} ], + output_template => 'Reads: %s/s', + per_second => 1, + perfdatas => [ + { label => 'reads', value => 'number-of-reads_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'writes', nlabel => 'controller.writes.count', set => { + key_values => [ { name => 'number-of-writes', diff => 1 }, { name => 'display'} ], + output_template => 'Writes: %s/s', + per_second => 1, + perfdatas => [ + { label => 'writes', value => 'number-of-writes_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-transfer', nlabel => 'controller.data.transfer.bytespersecond', set => { + key_values => [ { name => 'bytes-per-second-numeric'}, { name => 'display'} ], + output_template => 'Data Transfer: %s%s/s', + output_change_bytes => 1, + perfdatas => [ + { label => 'data_transfer', value => 'bytes-per-second-numeric_absolute', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'iops', nlabel => 'controller.iops.ops', set => { + key_values => [ { name => 'iops'}, { name => 'display'} ], + output_template => 'IOPS: %d ops', + perfdatas => [ + { label => 'iops', value => 'iops_absolute', + template => '%d', min => 0, unit => 'ops', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'forwarded-cmds', nlabel => 'controller.commands.forwarded.count', set => { + key_values => [ { name => 'num-forwarded-cmds'}, { name => 'display'} ], + output_template => 'Forwarded Commands: %d', + perfdatas => [ + { label => 'forwarded_cmds', value => 'num-forwarded-cmds_absolute', + template => '%d', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-used', nlabel => 'controller.cache.write.usage.percentage', set => { + key_values => [ { name => 'write-cache-used'}, { name => 'display'} ], + output_template => 'Cache Write Usage: %s%%', + perfdatas => [ + { label => 'write_cache_used', value => 'write-cache-used_absolute', + template => '%d', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-hits', nlabel => 'controller.cache.write.hits.count', set => { + key_values => [ { name => 'write-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_hits', value => 'write-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-misses', nlabel => 'controller.cache.write.misses.count', set => { + key_values => [ { name => 'write-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_misses', value => 'write-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-hits', nlabel => 'controller.cache.read.hits.count', set => { + key_values => [ { name => 'read-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_hits', value => 'read-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-misses', nlabel => 'controller.cache.read.misses.count', set => { + key_values => [ { name => 'read-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_misses', value => 'read-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cpu-utilization', nlabel => 'controller.cpu.utilization.percentage', set => { + key_values => [ { name => 'cpu-load'}, { name => 'display'} ], + output_template => 'CPU Utilization: %.2f%%', + perfdatas => [ + { label => 'cpu_utilization', value => 'cpu-load_absolute', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Controller '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->request_api(method => 'GET', url_path => '/api/show/controller-statistics'); + + $self->{controllers} = {}; + + foreach my $controller (@{$results->{'controller-statistics'}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $controller->{'durable-id'} !~ /$self->{option_results}->{filter_name}/); + + $self->{controllers}->{$controller->{'durable-id'}} = { display => $controller->{'durable-id'}, %{$controller} }; + } + + if (scalar(keys %{$self->{controllers}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No controllers found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "dell_me4_" . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); + +} + +1; + +__END__ + +=head1 MODE + +Check controllers statistics. + +=over 8 + +=item B<--filter-name> + +Filter controller name (Can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'controller.data.read.bytespersecond', 'controller.data.written.bytespersecond', +'controller.reads.count', 'controller.writes.count', +'controller.data.transfer.bytespersecond', 'controller.iops.ops', +'controller.commands.forwarded.count', +'controller.cache.write.usage.percentage', 'controller.cache.write.hits.count', +'controller.cache.write.misses.count', 'controller.cache.read.hits.count', +'controller.cache.read.misses.count', 'controller.cpu.utilization.percentage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'controller.data.read.bytespersecond', 'controller.data.written.bytespersecond', +'controller.reads.count', 'controller.writes.count', +'controller.data.transfer.bytespersecond', 'controller.iops.ops', +'controller.commands.forwarded.count', +'controller.cache.write.usage.percentage', 'controller.cache.write.hits.count', +'controller.cache.write.misses.count', 'controller.cache.read.hits.count', +'controller.cache.read.misses.count', 'controller.cpu.utilization.percentage'. + +=back + +=cut diff --git a/centreon-plugins/storage/dell/me4/mode/hardware.pm b/centreon-plugins/storage/dell/me4/mode/hardware.pm new file mode 100644 index 000000000..fd5620ee4 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/hardware.pm @@ -0,0 +1,186 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(controller|disk|fan|fru|psu|sensor|volume)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(fan|disk|sensor)$'; + + $self->{cb_hook1} = 'init_custom'; + + $self->{thresholds} = { + controller => [ + ['OK', 'OK'], + ['Operational', 'OK'], + ['Redundant', 'OK'], + ['Redundant with independent cache', 'OK'], + ['Degraded', 'WARNING'], + ['Operational but not redundant', 'WARNING'], + ['Fault', 'CRITICAL'], + ['Down', 'CRITICAL'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ['Not Installed', 'UNKNOWN'], + ], + disk => [ + ['OK', 'OK'], + ['Up', 'OK'], + ['AVAIL', 'OK'], + ['LINEAR POOL', 'OK'], + ['LINEAR POOLVRSC', 'OK'], + ['DEDICATED SP', 'OK'], + ['GLOBAL SP', 'OK'], + ['LEFTOVR', 'OK'], + ['VDISK', 'OK'], + ['VDISK SP', 'OK'], + ['VIRTUAL POOL', 'OK'], + ['Degraded', 'WARNING'], + ['Warning', 'WARNING'], + ['Unsupported', 'WARNING'], + ['Fault', 'CRITICAL'], + ['Spun Down', 'CRITICAL'], + ['Error', 'CRITICAL'], + ['Unrecoverable', 'CRITICAL'], + ['Unavailable', 'CRITICAL'], + ['FAILED', 'CRITICAL'], + ['UNUSABLE', 'CRITICAL'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ['Not Present', 'UNKNOWN'], + ], + fan => [ + ['OK', 'OK'], + ['Up', 'OK'], + ['Degraded', 'WARNING'], + ['Error', 'CRITICAL'], + ['Fault', 'CRITICAL'], + ['Missing', 'UNKNOWN'], + ['Off', 'UNKNOWN'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + fru => [ + ['OK', 'OK'], + ['Fault', 'CRITICAL'], + ['Invalid Data', 'CRITICAL'], + ['Power OFF', 'UNKNOWN'], + ['Absent', 'UNKNOWN'], + ], + psu => [ + ['OK', 'OK'], + ['Up', 'OK'], + ['Degraded', 'WARNING'], + ['Error', 'CRITICAL'], + ['Fault', 'CRITICAL'], + ['Missing', 'UNKNOWN'], + ['Off', 'UNKNOWN'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + sensor => [ + ['OK', 'OK'], + ['Warning', 'WARNING'], + ['Critical', 'CRITICAL'], + ['Unavailable', 'CRITICAL'], + ['Unrecoverable', 'UNKNOWN'], + ['Not Installed', 'UNKNOWN'], + ['Unsupported', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + volume => [ + ['OK', 'OK'], + ['Degraded', 'WARNING'], + ['Fault', 'CRITICAL'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'storage::dell::me4::mode::components'; + $self->{components_module} = ['controller', 'disk', 'fan', 'fru', 'psu', 'sensor', 'volume']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub init_custom { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; +} + +1; + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'controller', 'disk', 'fan', 'fru', 'psu', 'sensor', 'volume'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter='sensor,Overall Sensor' + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='controller,OK,Operational but not redundant' + +=item B<--warning> + +Set warning threshold for 'temperature' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut diff --git a/centreon-plugins/storage/dell/me4/mode/listcontrollers.pm b/centreon-plugins/storage/dell/me4/mode/listcontrollers.pm new file mode 100644 index 000000000..74f004cb0 --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/listcontrollers.pm @@ -0,0 +1,104 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::listcontrollers; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{result} = $options{custom}->request_api(method => 'GET', url_path => '/api/show/controllers'); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $controller (@{$self->{result}->{controllers}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $controller->{'durable-id'} !~ /$self->{option_results}->{filter_name}/); + + $self->{output}->output_add(long_msg => sprintf("[name = %s]", + $controller->{'durable-id'}, + )); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List controllers:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $controller (@{$self->{controllers}}) { + $self->{output}->add_disco_entry( + name => $controller->{'durable-id'}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List controllers. + +=over 8 + +=item B<--filter-name> + +Filter controller name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/storage/dell/me4/mode/listvolumes.pm b/centreon-plugins/storage/dell/me4/mode/listvolumes.pm index 74628906f..a500bc1a8 100644 --- a/centreon-plugins/storage/dell/me4/mode/listvolumes.pm +++ b/centreon-plugins/storage/dell/me4/mode/listvolumes.pm @@ -46,7 +46,7 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - $self->{result} = $options{custom}->request_api(method => 'GET', url_path => '/api/show/volumes'); + $self->{result} = $options{custom}->request_api(method => 'GET', url_path => '/api/show/volumes'); } sub run { diff --git a/centreon-plugins/storage/dell/me4/mode/volumestatistics.pm b/centreon-plugins/storage/dell/me4/mode/volumestatistics.pm new file mode 100644 index 000000000..f4de3f94c --- /dev/null +++ b/centreon-plugins/storage/dell/me4/mode/volumestatistics.pm @@ -0,0 +1,241 @@ +# +# Copyright 2019 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::dell::me4::mode::volumestatistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volumes', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All volumes statistics are ok' } + ]; + + $self->{maps_counters}->{volumes} = [ + { label => 'data-read', nlabel => 'volume.data.read.bytespersecond', set => { + key_values => [ { name => 'data-read-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Read: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_read', value => 'data-read-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-written', nlabel => 'volume.data.written.bytespersecond', set => { + key_values => [ { name => 'data-written-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Written: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_written', value => 'data-written-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'reads', nlabel => 'volume.reads.count', set => { + key_values => [ { name => 'number-of-reads', diff => 1 }, { name => 'display'} ], + output_template => 'Reads: %s/s', + per_second => 1, + perfdatas => [ + { label => 'reads', value => 'number-of-reads_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'writes', nlabel => 'volume.writes.count', set => { + key_values => [ { name => 'number-of-writes', diff => 1 }, { name => 'display'} ], + output_template => 'Writes: %s/s', + per_second => 1, + perfdatas => [ + { label => 'writes', value => 'number-of-writes_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-transfer', nlabel => 'volume.data.transfer.bytespersecond', set => { + key_values => [ { name => 'bytes-per-second-numeric'}, { name => 'display'} ], + output_template => 'Data Transfer: %s%s/s', + output_change_bytes => 1, + perfdatas => [ + { label => 'data_transfer', value => 'bytes-per-second-numeric_absolute', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'iops', nlabel => 'volume.iops.ops', set => { + key_values => [ { name => 'iops'}, { name => 'display'} ], + output_template => 'IOPS: %d ops', + perfdatas => [ + { label => 'iops', value => 'iops_absolute', + template => '%d', min => 0, unit => 'ops', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-percent', nlabel => 'volume.cache.write.usage.percentage', set => { + key_values => [ { name => 'write-cache-percent'}, { name => 'display'} ], + output_template => 'Cache Write Usage: %s%%', + perfdatas => [ + { label => 'write_cache_used', value => 'write-cache-percent_absolute', + template => '%d', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-hits', nlabel => 'volume.cache.write.hits.count', set => { + key_values => [ { name => 'write-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_hits', value => 'write-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-misses', nlabel => 'volume.cache.write.misses.count', set => { + key_values => [ { name => 'write-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_misses', value => 'write-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-hits', nlabel => 'volume.cache.read.hits.count', set => { + key_values => [ { name => 'read-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_hits', value => 'read-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-misses', nlabel => 'volume.cache.read.misses.count', set => { + key_values => [ { name => 'read-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_misses', value => 'read-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Volume '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->request_api(method => 'GET', url_path => '/api/show/volume-statistics'); + + $self->{volumes} = {}; + + foreach my $volume (@{$results->{'volume-statistics'}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $volume->{'volume-name'} !~ /$self->{option_results}->{filter_name}/); + + $self->{volumes}->{$volume->{'volume-name'}} = { display => $volume->{'volume-name'}, %{$volume} }; + } + + if (scalar(keys %{$self->{volumes}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volumes found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "dell_me4_" . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); + +} + +1; + +__END__ + +=head1 MODE + +Check volumes statistics. + +=over 8 + +=item B<--filter-name> + +Filter volume name (Can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'volume.data.read.bytespersecond', 'volume.data.written.bytespersecond', +'volume.reads.count', 'volume.writes.count', +'volume.data.transfer.bytespersecond', 'volume.iops.ops', +'volume.cache.write.usage.percentage', 'volume.cache.write.hits.count', +'volume.cache.write.misses.count', 'volume.cache.read.hits.count', +'volume.cache.read.misses.count'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'volume.data.read.bytespersecond', 'volume.data.written.bytespersecond', +'volume.reads.count', 'volume.writes.count', +'volume.data.transfer.bytespersecond', 'volume.iops.ops', +'volume.cache.write.usage.percentage', 'volume.cache.write.hits.count', +'volume.cache.write.misses.count', 'volume.cache.read.hits.count', +'volume.cache.read.misses.count'. + +=back + +=cut diff --git a/centreon-plugins/storage/dell/me4/plugin.pm b/centreon-plugins/storage/dell/me4/plugin.pm index cefa75662..fb9ac2cd9 100644 --- a/centreon-plugins/storage/dell/me4/plugin.pm +++ b/centreon-plugins/storage/dell/me4/plugin.pm @@ -31,7 +31,11 @@ sub new { $self->{version} = '0.1'; %{ $self->{modes} } = ( - 'list-volumes' => 'storage::dell::me4::mode::listvolumes', + 'controller-statistics' => 'storage::dell::me4::mode::controllerstatistics', + 'hardware' => 'storage::dell::me4::mode::hardware', + 'list-controllers' => 'storage::dell::me4::mode::listcontrollers', + 'list-volumes' => 'storage::dell::me4::mode::listvolumes', + 'volume-statistics' => 'storage::dell::me4::mode::volumestatistics', ); $self->{custom_modes}{api} = 'storage::dell::me4::custom::api';