From 0772e7880cf51f8878f03e028d3c71a3a3f17bb9 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 7 Aug 2023 13:01:59 +0200 Subject: [PATCH] (plugin) network::audiocodes::snmp - add sbc-calls mode + metric v2 (#4567) * wip * wip * wip * wip --- .../snmp/mode/components/fantray.pm | 25 ++- .../audiocodes/snmp/mode/components/module.pm | 26 ++- .../audiocodes/snmp/mode/components/psu.pm | 27 ++- src/network/audiocodes/snmp/mode/cpu.pm | 78 +++++--- src/network/audiocodes/snmp/mode/hardware.pm | 5 +- .../audiocodes/snmp/mode/interfaces.pm | 182 ++++++++++++++++++ .../audiocodes/snmp/mode/listtrunks.pm | 59 +++--- src/network/audiocodes/snmp/mode/memory.pm | 72 ++++--- src/network/audiocodes/snmp/mode/sbccalls.pm | 177 +++++++++++++++++ .../audiocodes/snmp/mode/trunkstatus.pm | 124 +++++------- src/network/audiocodes/snmp/plugin.pm | 16 +- 11 files changed, 593 insertions(+), 198 deletions(-) create mode 100644 src/network/audiocodes/snmp/mode/interfaces.pm create mode 100644 src/network/audiocodes/snmp/mode/sbccalls.pm diff --git a/src/network/audiocodes/snmp/mode/components/fantray.pm b/src/network/audiocodes/snmp/mode/components/fantray.pm index a8c1003c3..e85b65b4a 100644 --- a/src/network/audiocodes/snmp/mode/components/fantray.pm +++ b/src/network/audiocodes/snmp/mode/components/fantray.pm @@ -29,11 +29,11 @@ my %map_status = ( 2 => 'warning', 3 => 'minor', 4 => 'major', - 5 => 'critical', + 5 => 'critical' ); my %map_existence = ( 1 => 'present', - 2 => 'missing', + 2 => 'missing' ); my $mapping = { @@ -59,20 +59,27 @@ sub check { next if ($oid !~ /^$mapping->{acSysFanTraySeverity}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_acSysFanTrayEntry}, instance => $instance); - + next if ($result->{acSysFanTrayExistence} eq 'missing' && - $self->absent_problem(section => 'fantray', instance => $instance)); + $self->absent_problem(section => 'fantray', instance => $instance)); next if ($self->check_filter(section => 'fantray', instance => $instance)); $self->{components}->{fantray}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Fan tray '%s' status is '%s' [instance = %s]", - $instance, $result->{acSysFanTraySeverity}, $instance)); + $self->{output}->output_add( + long_msg => sprintf( + "fan tray '%s' status is '%s' [instance: %s]", + $instance, $result->{acSysFanTraySeverity}, $instance + ) + ); + my $exit = $self->get_severity(label => 'default', section => 'fantray', value => $result->{acSysFanTraySeverity}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Fan tray '%s' status is '%s'", $instance, $result->{acSysFanTraySeverity})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Fan tray '%s' status is '%s'", $instance, $result->{acSysFanTraySeverity}) + ); } } } -1; \ No newline at end of file +1; diff --git a/src/network/audiocodes/snmp/mode/components/module.pm b/src/network/audiocodes/snmp/mode/components/module.pm index c0efe4bc0..093d450e0 100644 --- a/src/network/audiocodes/snmp/mode/components/module.pm +++ b/src/network/audiocodes/snmp/mode/components/module.pm @@ -30,16 +30,16 @@ my %map_status = ( 4 => 'moduleBackToServiceStart', 5 => 'moduleMismatch', 6 => 'moduleFaulty', - 7 => 'notApplicable', + 7 => 'notApplicable' ); my %map_existence = ( 1 => 'present', - 2 => 'missing', + 2 => 'missing' ); my $mapping = { acSysModulePresence => { oid => '.1.3.6.1.4.1.5003.9.10.10.4.21.1.4', map => \%map_existence }, - acSysModuleFRUstatus => { oid => '.1.3.6.1.4.1.5003.9.10.10.4.21.1.14', map => \%map_status }, + acSysModuleFRUstatus => { oid => '.1.3.6.1.4.1.5003.9.10.10.4.21.1.14', map => \%map_status } }; my $oid_acSysModuleEntry = '.1.3.6.1.4.1.5003.9.10.10.4.21.1'; @@ -60,20 +60,26 @@ sub check { next if ($oid !~ /^$mapping->{acSysModuleFRUstatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_acSysModuleEntry}, instance => $instance); - + next if ($result->{acSysModulePresence} eq 'missing' && - $self->absent_problem(section => 'module', instance => $instance)); + $self->absent_problem(section => 'module', instance => $instance)); next if ($self->check_filter(section => 'module', instance => $instance)); $self->{components}->{module}->{total}++; - $self->{output}->output_add(long_msg => sprintf("module '%s' status is '%s' [instance = %s]", - $instance, $result->{acSysModuleFRUstatus}, $instance)); + $self->{output}->output_add( + long_msg => sprintf( + "module '%s' status is '%s' [instance: %s]", + $instance, $result->{acSysModuleFRUstatus}, $instance + ) + ); my $exit = $self->get_severity(section => 'module', value => $result->{acSysModuleFRUstatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Module '%s' status is '%s'", $instance, $result->{acSysModuleFRUstatus})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Module '%s' status is '%s'", $instance, $result->{acSysModuleFRUstatus}) + ); } } } -1; \ No newline at end of file +1; diff --git a/src/network/audiocodes/snmp/mode/components/psu.pm b/src/network/audiocodes/snmp/mode/components/psu.pm index 1080f4a01..f10a24263 100644 --- a/src/network/audiocodes/snmp/mode/components/psu.pm +++ b/src/network/audiocodes/snmp/mode/components/psu.pm @@ -29,16 +29,16 @@ my %map_status = ( 3 => 'warning', 4 => 'minor', 5 => 'major', - 6 => 'critical', + 6 => 'critical' ); my %map_existence = ( 1 => 'present', - 2 => 'missing', + 2 => 'missing' ); my $mapping = { acSysPowerSupplyExistence => { oid => '.1.3.6.1.4.1.5003.9.10.10.4.23.1.3', map => \%map_existence }, - acSysPowerSupplySeverity => { oid => '.1.3.6.1.4.1.5003.9.10.10.4.23.1.6', map => \%map_status }, + acSysPowerSupplySeverity => { oid => '.1.3.6.1.4.1.5003.9.10.10.4.23.1.6', map => \%map_status } }; my $oid_acSysPowerSupplyEntry = '.1.3.6.1.4.1.5003.9.10.10.4.23.1'; @@ -59,20 +59,27 @@ sub check { next if ($oid !~ /^$mapping->{acSysPowerSupplySeverity}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_acSysPowerSupplyEntry}, instance => $instance); - + next if ($result->{acSysPowerSupplyExistence} eq 'missing' && - $self->absent_problem(section => 'psu', instance => $instance)); + $self->absent_problem(section => 'psu', instance => $instance)); 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' [instance = %s]", - $instance, $result->{acSysPowerSupplySeverity}, $instance)); + $self->{output}->output_add( + long_msg => sprintf( + "power supply '%s' status is '%s' [instance: %s]", + $instance, $result->{acSysPowerSupplySeverity}, $instance + ) + ); + my $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{acSysPowerSupplySeverity}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Power supply '%s' status is '%s'", $instance, $result->{acSysPowerSupplySeverity})); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Power supply '%s' status is '%s'", $instance, $result->{acSysPowerSupplySeverity}) + ); } } } -1; \ No newline at end of file +1; diff --git a/src/network/audiocodes/snmp/mode/cpu.pm b/src/network/audiocodes/snmp/mode/cpu.pm index 3b80e42d1..8fc384464 100644 --- a/src/network/audiocodes/snmp/mode/cpu.pm +++ b/src/network/audiocodes/snmp/mode/cpu.pm @@ -25,41 +25,58 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance} . "' "; +} + sub set_counters { my ($self, %options) = @_; - + $self->{maps_counters_type} = [ - { name => 'global', type => 0, message_separator => ' - ' }, + { name => 'global', type => 0, message_separator => ' - ', skipped_code => { -10 => 1 } }, + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPU(s) average usages are ok', skipped_code => { -10 => 1 } } ]; + $self->{maps_counters}->{global} = [ { label => 'voip', nlabel => 'cpu.voip.utilization.percentage', set => { key_values => [ { name => 'voip' } ], - output_template => 'CPU VoIp Usage : %.2f %%', + output_template => 'CPU VoIp usage: %.2f %%', perfdatas => [ - { label => 'cpu_voip', value => 'voip', template => '%.2f', min => 0, max => 100, unit => '%' }, - ], + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] } }, { label => 'data', nlabel => 'cpu.data.utilization.percentage', set => { key_values => [ { name => 'data' } ], - output_template => 'CPU Data Usage : %.2f %%', + output_template => 'CPU data usage: %.2f %%', perfdatas => [ - { label => 'cpu_data', value => 'data', template => '%.2f', min => 0, max => 100, unit => '%' }, - ], + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] } - }, + } + ]; + + $self->{maps_counters}->{cpu} = [ + { label => 'core-cpu-utilization', nlabel => 'core.cpu.utilization.percentage', set => { + key_values => [ { name => 'cpu_usage' } ], + output_template => 'average usage is: %.2f%%', + perfdatas => [ + { template => '%.2f', unit => '%', min => 0, max => 100, label_extra_instance => 1 } + ] + } + } ]; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - - $options{options}->add_options(arguments => - { - }); - + + $options{options}->add_options(arguments => { }); + return $self; } @@ -68,11 +85,21 @@ sub manage_selection { my $oid_acSysStateVoIpCpuUtilization = '.1.3.6.1.4.1.5003.9.10.10.2.5.10.0'; my $oid_acSysStateDataCpuUtilization = '.1.3.6.1.4.1.5003.9.10.10.2.5.8.0'; - my $snmp_result = $options{snmp}->get_leef(oids => [ - $oid_acSysStateVoIpCpuUtilization, $oid_acSysStateDataCpuUtilization - ], nothing_quit => 1); - + my $snmp_result = $options{snmp}->get_leef( + oids => [$oid_acSysStateVoIpCpuUtilization, $oid_acSysStateDataCpuUtilization], + nothing_quit => 1 + ); + $self->{global} = { data => $snmp_result->{$oid_acSysStateDataCpuUtilization}, voip => $snmp_result->{$oid_acSysStateVoIpCpuUtilization} }; + + my $oid_acKpiCpuStatsCurrentCpuCpuUtilization = '.1.3.6.1.4.1.5003.15.2.4.1.2.1.1.2'; + $snmp_result = $options{snmp}->get_table(oid => $oid_acKpiCpuStatsCurrentCpuCpuUtilization); + + $self->{cpu} = {}; + foreach (keys %$snmp_result) { + /\.(\d+)$/; + $self->{cpu}->{$1} = { cpu_usage => $snmp_result->{$_} }; + } } 1; @@ -81,7 +108,7 @@ __END__ =head1 MODE -Check CPU usages. +Check CPU usage. =over 8 @@ -90,15 +117,10 @@ Check CPU usages. Only display some counters (regexp can be used). Example: --filter-counters='^voip$' -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Warning threshold. -Can be: 'voip', 'data'. - -=item B<--critical-*> - -Critical threshold. -Can be: 'voip', 'data'. +Threshold. +Can be: 'voip', 'data', 'core-cpu-utilization'. =back diff --git a/src/network/audiocodes/snmp/mode/hardware.pm b/src/network/audiocodes/snmp/mode/hardware.pm index 8a05179d3..61c98e4e7 100644 --- a/src/network/audiocodes/snmp/mode/hardware.pm +++ b/src/network/audiocodes/snmp/mode/hardware.pm @@ -63,7 +63,7 @@ sub snmp_execute { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => {}); @@ -77,7 +77,7 @@ __END__ =head1 MODE -Check Hardware. +Check hardware. =over 8 @@ -100,7 +100,6 @@ Can be specific or global: --absent-problem=psu,1 Define the expected status if no components are found (default: critical). - =item B<--threshold-overload> Use this option to override the status returned by the plugin when the status label matches a regular expression (syntax: section,[instance,]status,regexp). diff --git a/src/network/audiocodes/snmp/mode/interfaces.pm b/src/network/audiocodes/snmp/mode/interfaces.pm new file mode 100644 index 000000000..1865c7b74 --- /dev/null +++ b/src/network/audiocodes/snmp/mode/interfaces.pm @@ -0,0 +1,182 @@ +# +# Copyright 2023 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 network::audiocodes::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=item B<--check-metrics> + +If the expression is true, metrics are checked (Default: '%{opstatus} eq "up"'). + +=item B<--warning-status> + +Define the conditions to match for the status to be WARNING. +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--critical-status> + +Define the conditions to match for the status to be CRITICAL (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast', +'speed' (b/s). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: 'percent_delta') ('percent_delta', 'bps', 'counter'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter'). + +=item B<--units-cast> + +Units of thresholds for communication types (Default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interfaces'). + +=item B<--name> + +Allows you to define the interface (in option --interface) by name instead of OID index. The name matching mode supports regular expressions. + +=item B<--speed> + +Set interface speed for incoming/outgoing traffic (in Mb). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--map-speed-dsl> + +Get interface speed configuration for interface type 'adsl' and 'vdsl2'. + +Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name + +E.g: --map-speed-dsl=Et0.835,Et0-vdsl2 + +=item B<--force-counters64> + +Force to use 64 bits counters only. Can be used to improve performance. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Define the OID to be used to filter interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-display> + +Define the OID that will be used to name the interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-extra-display> + +Add an OID to display. + +=item B<--display-transform-src> + +Regexp src to transform display value. + +=item B<--display-transform-dst> + +Regexp dst to transform display value. + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/src/network/audiocodes/snmp/mode/listtrunks.pm b/src/network/audiocodes/snmp/mode/listtrunks.pm index b90f5c1dd..bc7265241 100644 --- a/src/network/audiocodes/snmp/mode/listtrunks.pm +++ b/src/network/audiocodes/snmp/mode/listtrunks.pm @@ -30,10 +30,8 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $options{options}->add_options(arguments => - { - }); - $self->{trunks} = {}; + $options{options}->add_options(arguments => {}); + return $self; } @@ -43,13 +41,15 @@ sub check_options { } my %map_deactivate = (0 => 'notAvailable', 1 => 'deActivated', 2 => 'activated'); -my %map_alarm = (0 => 'greyDisabled', 1 => 'greenActive', 2 => 'redLosLof', -3 => 'blueAis', 4 => 'yellowRai', 5 => 'orangeDChannel', 6 => 'purpleLowerLayerDown', 7 => 'darkOrangeNFASAlarm'); +my %map_alarm = ( + 0 => 'greyDisabled', 1 => 'greenActive', 2 => 'redLosLof', + 3 => 'blueAis', 4 => 'yellowRai', 5 => 'orangeDChannel', 6 => 'purpleLowerLayerDown', 7 => 'darkOrangeNFASAlarm' +); my $mapping = { acTrunkStatusAlarm => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.7', map => \%map_alarm }, acTrunkDeactivate => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.11', map => \%map_deactivate }, - acTrunkName => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.13' }, + acTrunkName => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.13' } }; sub manage_selection { @@ -58,10 +58,12 @@ sub manage_selection { my $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $mapping->{acTrunkStatusAlarm}->{oid} }, { oid => $mapping->{acTrunkDeactivate}->{oid} }, - { oid => $mapping->{acTrunkName}->{oid} }, + { oid => $mapping->{acTrunkName}->{oid} } ], - return_type => 1, nothing_quit => 1); + return_type => 1, nothing_quit => 1 + ); + my $results = {}; foreach my $oid (keys %{$snmp_result}) { next if ($oid !~ /^$mapping->{acTrunkName}->{oid}\.(.*)$/); my $instance = $1; @@ -72,24 +74,35 @@ sub manage_selection { next; } - $self->{trunks}->{$instance} = - { name => $result->{acTrunkName}, status => $result->{acTrunkStatusAlarm}, state => $result->{acTrunkDeactivate} }; + $results->{$instance} = { + name => $result->{acTrunkName}, + status => $result->{acTrunkStatusAlarm}, + state => $result->{acTrunkDeactivate} + }; } + + return $results; } sub run { my ($self, %options) = @_; - $self->manage_selection(%options); - foreach my $instance (sort keys %{$self->{trunks}}) { - $self->{output}->output_add(long_msg => '[name = ' . $self->{trunks}->{$instance}->{name} . - "] [status = '" . $self->{trunks}->{$instance}->{status} . "'] [state = '" . - $self->{trunks}->{$instance}->{state} . "']" - ); + my $results = $self->manage_selection(%options); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add( + long_msg => sprintf( + '[name: %s] [status: %s] [state: %s]', + $results->{$instance}->{name}, + $results->{$instance}->{status}, + $results->{$instance}->{state} + ) + ); } - $self->{output}->output_add(severity => 'OK', - short_msg => 'List trunks:'); + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List trunks:' + ); $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } @@ -103,10 +116,9 @@ sub disco_format { sub disco_show { my ($self, %options) = @_; - $self->manage_selection(%options); - foreach my $instance (sort keys %{$self->{trunks}}) { - $self->{output}->add_disco_entry(name => $self->{trunks}->{$instance}->{name}, - status => $self->{trunks}->{$instance}->{status}, state => $self->{trunks}->{$instance}->{state}); + my $results = $self->manage_selection(%options); + foreach my $instance (sort keys %$results) { + $self->{output}->add_disco_entry(%{$results->{$instance}}); } } @@ -123,4 +135,3 @@ List trunks. =back =cut - diff --git a/src/network/audiocodes/snmp/mode/memory.pm b/src/network/audiocodes/snmp/mode/memory.pm index 107c15a8e..e1128c130 100644 --- a/src/network/audiocodes/snmp/mode/memory.pm +++ b/src/network/audiocodes/snmp/mode/memory.pm @@ -25,41 +25,54 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Memory '; +} + sub set_counters { my ($self, %options) = @_; - + $self->{maps_counters_type} = [ - { name => 'global', type => 0, message_separator => ' - ' }, + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } } ]; + $self->{maps_counters}->{global} = [ - { label => 'voip', nlabel => 'memory.voip.utilization.percentage', set => { + { label => 'voip', nlabel => 'memory.voip.usage.percentage', set => { key_values => [ { name => 'voip' } ], - output_template => 'Memory VoIp Usage : %.2f %%', + output_template => 'VoIp usage: %.2f %%', perfdatas => [ - { label => 'used_voip', value => 'voip', template => '%.2f', min => 0, max => 100, unit => '%' }, - ], + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] } }, - { label => 'data', nlabel => 'memory.data.utilization.percentage', set => { + { label => 'data', nlabel => 'memory.data.usage.percentage', set => { key_values => [ { name => 'data' } ], - output_template => 'Memory Data Usage : %.2f %%', + output_template => 'data usage: %.2f %%', perfdatas => [ - { label => 'used_data', value => 'data', template => '%.2f', min => 0, max => 100, unit => '%' }, - ], + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] } }, + { label => 'system', nlabel => 'memory.system.usage.percentage', set => { + key_values => [ { name => 'system' } ], + output_template => 'system usage: %.2f %%', + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] + } + } ]; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - - $options{options}->add_options(arguments => - { - }); - + + $options{options}->add_options(arguments => {}); + return $self; } @@ -68,11 +81,17 @@ sub manage_selection { my $oid_acSysStateVoIpMemoryUtilization = '.1.3.6.1.4.1.5003.9.10.10.2.5.11.0'; my $oid_acSysStateDataMemoryUtilization = '.1.3.6.1.4.1.5003.9.10.10.2.5.9.0'; - my $snmp_result = $options{snmp}->get_leef(oids => [ - $oid_acSysStateVoIpMemoryUtilization, $oid_acSysStateDataMemoryUtilization - ], nothing_quit => 1); - - $self->{global} = { data => $snmp_result->{$oid_acSysStateDataMemoryUtilization}, voip => $snmp_result->{$oid_acSysStateVoIpMemoryUtilization} }; + my $oid_acKpiSystemStatsCurrentGlobalMemoryUtilization = '.1.3.6.1.4.1.5003.15.2.2.1.1.1.0'; + my $snmp_result = $options{snmp}->get_leef( + oids => [$oid_acSysStateVoIpMemoryUtilization, $oid_acSysStateDataMemoryUtilization, $oid_acKpiSystemStatsCurrentGlobalMemoryUtilization], + nothing_quit => 1 + ); + + $self->{global} = { + data => $snmp_result->{$oid_acSysStateDataMemoryUtilization}, + voip => $snmp_result->{$oid_acSysStateVoIpMemoryUtilization}, + system => $snmp_result->{$oid_acKpiSystemStatsCurrentGlobalMemoryUtilization} + }; } 1; @@ -90,15 +109,10 @@ Check memory usages. Only display some counters (regexp can be used). Example: --filter-counters='^voip$' -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Warning threshold. -Can be: 'voip', 'data'. - -=item B<--critical-*> - -Critical threshold. -Can be: 'voip', 'data'. +Thresholds. +Can be: 'voip', 'data', 'system'. =back diff --git a/src/network/audiocodes/snmp/mode/sbccalls.pm b/src/network/audiocodes/snmp/mode/sbccalls.pm new file mode 100644 index 000000000..e05d2f821 --- /dev/null +++ b/src/network/audiocodes/snmp/mode/sbccalls.pm @@ -0,0 +1,177 @@ +# +# Copyright 2023 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 network::audiocodes::snmp::mode::sbccalls; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5; + +sub prefix_calls_output { + my ($self, %options) = @_; + + return 'number of calls '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'call', type => 0, cb_prefix_output => 'prefix_calls_output', skipped_code => { -10 => 1 } }, + { name => 'session', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{call} = [ + { label => 'sbc-calls-duration-average', nlabel => 'sbc.calls.duration.average.seconds', set => { + key_values => [ { name => 'callsAvgDuration' } ], + output_template => 'average duration: %s s', + perfdatas => [ + { template => '%s', min => 0, unit => 's' } + ] + } + }, + { label => 'sbc-calls-active-inbound', nlabel => 'sbc.calls.active.inbound.count', set => { + key_values => [ { name => 'callsInActive' } ], + output_template => 'active inbound: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'sbc-calls-active-outbound', nlabel => 'sbc.calls.active.outbound.count', set => { + key_values => [ { name => 'callsOutActive' } ], + output_template => 'active outbound: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'sbc-calls-established-inbound', nlabel => 'sbc.calls.established.inbound.count', set => { + key_values => [ { name => 'callsInTotalEst', diff => 1 } ], + output_template => 'established inbound: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'sbc-calls-established-outbound', nlabel => 'sbc.calls.established.outbound.count', set => { + key_values => [ { name => 'callsOutTotalEst', diff => 1 } ], + output_template => 'established outbound: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'sbc-calls-notestablished-inbound-failed', nlabel => 'sbc.calls.notestablished.inbound.failed.count', set => { + key_values => [ { name => 'callsInFailedNotEst', diff => 1 } ], + output_template => 'not established inbound failed: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }, + { label => 'sbc-calls-notestablished-outbound', nlabel => 'sbc.calls.notestablished.outbound.failed.count', set => { + key_values => [ { name => 'callsOutFailedNotEst', diff => 1 } ], + output_template => 'not established outbound failed: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{session} = [ + { label => 'sbc-sessions-active', nlabel => 'sbc.sessions.active.count', set => { + key_values => [ { name => 'active' } ], + output_template => 'active sessions: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mapping = { + callsAvgDuration => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.1' }, # acKpiSbcCallStatsCurrentGlobalAverageCallDuration + callsInActive => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.2' }, # acKpiSbcCallStatsCurrentGlobalActiveCallsIn + callsOutActive => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.3' }, # acKpiSbcCallStatsCurrentGlobalActiveCallsOut + callsInTotalEst => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.8' }, # acKpiSbcCallStatsCurrentGlobalEstablishedCallsInTotal + callsOutTotalEst => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.9' }, # acKpiSbcCallStatsCurrentGlobalEstablishedCallsOutTotal + callsInFailedNotEst => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.19' }, # acKpiSbcCallStatsCurrentGlobalNotEstablishFailedCallsInTotal + callsOutFailedNotEst => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.20' }, # acKpiSbcCallStatsCurrentGlobalNotEstablishFailedCallsOutTotal + activeSessions => { oid => '.1.3.6.1.4.1.5003.15.3.1.1.1.43' } # acKpiSbcCallStatsCurrentGlobalActiveSessions + }; + + my $snmp_result = $options{snmp}->get_leef( + oids => [ map($_->{oid} . '.0', values(%$mapping)) ], + nothing_quit => 1 + ); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => 0); + $self->{call} = $result; + $self->{session} = { active => $result->{activeSessions} }; + + $self->{cache_name} = 'audiocodes_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + Digest::MD5::md5_hex( + defined($self->{option_results}->{filter_counters}) ? $self->{option_results}->{filter_counters} : '' + ); +} + +1; + +__END__ + +=head1 MODE + +Check SBC calls. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^calls' + +=item B<--warning-*> B<--critical-*> + +Threshold. +Can be: 'sbc-calls-duration-average', 'sbc-calls-active-inbound', 'sbc-calls-active-outbound', +'sbc-calls-established-inbound', 'sbc-calls-established-outbound', +'sbc-calls-notestablished-inbound-failed', 'sbc-calls-notestablished-outbound', 'sbc-sessions-active'. + +=back + +=cut diff --git a/src/network/audiocodes/snmp/mode/trunkstatus.pm b/src/network/audiocodes/snmp/mode/trunkstatus.pm index 8b4b27ea9..ff5459182 100644 --- a/src/network/audiocodes/snmp/mode/trunkstatus.pm +++ b/src/network/audiocodes/snmp/mode/trunkstatus.pm @@ -25,101 +25,78 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use Digest::MD5 qw(md5_hex); -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub custom_status_output { my ($self, %options) = @_; - - my $msg = 'alarm status : ' . $self->{result_values}->{alarm} . ' [state: ' . $self->{result_values}->{state} . ']'; - return $msg; + + return 'alarm status : ' . $self->{result_values}->{alarm} . ' [state: ' . $self->{result_values}->{state} . ']'; } -sub custom_status_calc { +sub prefix_trunk_output { my ($self, %options) = @_; - $self->{result_values}->{alarm} = $options{new_datas}->{$self->{instance} . '_alarm'}; - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - $self->{result_values}->{dchannel} = $options{new_datas}->{$self->{instance} . '_dchannel'}; - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; - return 0; + return "Trunk '" . $options{instance_value}->{display} . "' "; } sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'trunk', type => 1, cb_prefix_output => 'prefix_vpn_output', message_multiple => 'All trunks are ok' } + { name => 'trunk', type => 1, cb_prefix_output => 'prefix_trunk_output', message_multiple => 'All trunks are ok' } ]; - + $self->{maps_counters}->{trunk} = [ - { label => 'status', threshold => 0, set => { + { label => 'status', type => 2, critical_default => '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i', set => { key_values => [ { name => 'display' }, { name => 'dchannel' }, { name => 'alarm' }, { name => 'state' } ], - closure_custom_calc => $self->can('custom_status_calc'), closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold_ng } }, - { label => 'avg-calls', set => { + { label => 'avg-calls', nlabel => 'trunk.calls.average.count', set => { key_values => [ { name => 'acPMTrunkUtilizationAverage' }, { name => 'display' } ], - output_template => 'Average calls : %s', + output_template => 'average calls: %s', perfdatas => [ - { label => 'avg_calls', value => 'acPMTrunkUtilizationAverage', template => '%d', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' }, + ] } }, - { label => 'max-calls', set => { + { label => 'max-calls', nlabel => 'trunk.calls.max.count', set => { key_values => [ { name => 'acPMTrunkUtilizationMax' }, { name => 'display' } ], - output_template => 'Max calls : %s', + output_template => 'max calls: %s', perfdatas => [ - { label => 'max_calls', value => 'acPMTrunkUtilizationMax', template => '%d', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' }, + ] } }, - { label => 'count-calls', set => { + { label => 'count-calls', nlabel => 'trunk.calls.total.count', set => { key_values => [ { name => 'acPMTrunkUtilizationTotal', diff => 1 }, { name => 'display' } ], - output_template => 'Count calls : %s', + output_template => 'count calls: %s', perfdatas => [ - { label => 'count_calls', value => 'acPMTrunkUtilizationTotal', template => '%d', - min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display' }, - ], + { label => 'count_calls', template => '%d', min => 0, label_extra_instance => 1, instance_use => 'display' } + ] } - }, + } ]; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); bless $self, $class; - - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i' }, - }); - + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $self->change_macros(macros => ['warning_status', 'critical_status']); -} - -sub prefix_vpn_output { - my ($self, %options) = @_; - - return "Trunk '" . $options{instance_value}->{display} . "' "; -} - -my %map_alarm = (0 => 'greyDisabled', 1 => 'greenActive', 2 => 'redLosLof', -3 => 'blueAis', 4 => 'yellowRai', 5 => 'orangeDChannel', 6 => 'purpleLowerLayerDown', 7 => 'darkOrangeNFASAlarm'); +my %map_alarm = ( + 0 => 'greyDisabled', 1 => 'greenActive', 2 => 'redLosLof', + 3 => 'blueAis', 4 => 'yellowRai', 5 => 'orangeDChannel', 6 => 'purpleLowerLayerDown', 7 => 'darkOrangeNFASAlarm' +); my %map_dchannel = (0 => 'dChannelEstablished', 1 => 'dChannelNotEstablished', 10 => 'dChannelNotApplicable'); my %map_deactivate = (0 => 'notAvailable', 1 => 'deActivated', 2 => 'activated'); @@ -128,12 +105,12 @@ my $mapping = { acTrunkStatusDChannel => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.6', map => \%map_dchannel }, acTrunkStatusAlarm => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.7', map => \%map_alarm }, acTrunkDeactivate => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.11', map => \%map_deactivate }, - acTrunkName => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.13' }, + acTrunkName => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.13' } }, usage => { acPMTrunkUtilizationAverage => { oid => '.1.3.6.1.4.1.5003.10.10.2.21.1.4' }, acPMTrunkUtilizationMax => { oid => '.1.3.6.1.4.1.5003.10.10.2.21.1.5' }, - acPMTrunkUtilizationTotal => { oid => '.1.3.6.1.4.1.5003.10.10.2.21.1.12' }, + acPMTrunkUtilizationTotal => { oid => '.1.3.6.1.4.1.5003.10.10.2.21.1.12' } } }; @@ -155,33 +132,32 @@ sub manage_selection { $datas->{$_} = { %{$datas->{$_}}, %{$snmp_result->{ $mapping->{$_}->{$name}->{oid} }} }; } } + foreach (keys %{$snmp_result->{ $mapping->{status}->{acTrunkStatusAlarm}->{oid} }}) { /\.(\d+)$/; my $instance = $1; my $result = $options{snmp}->map_instance(mapping => $mapping->{status}, results => $datas->{status}, instance => $instance); my $result2 = $options{snmp}->map_instance(mapping => $mapping->{usage}, results => $datas->{usage}, instance => $instance . '.0'); - + my $display = defined($result->{acTrunkName}) && $result->{acTrunkName} ne '' ? $result->{acTrunkName} : $instance; - if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $display !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $display . "': no matching filter.", debug => 1); - next; - } - + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $display !~ /$self->{option_results}->{filter_name}/); + $self->{trunk}->{$instance} = { display => $display, alarm => $result->{acTrunkStatusAlarm}, state => $result->{acTrunkDeactivate}, dchannel => $result->{acTrunkStatusDChannel}, - %$result2 }; + %$result2 + }; } - + if (scalar(keys %{$self->{trunk}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No trunk found."); $self->{output}->option_exit(); } - - $self->{cache_name} = "audiocodes_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + + $self->{cache_name} = 'audiocodes_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . (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')); } @@ -207,20 +183,14 @@ You can use the following variables: %{display}, %{alarm}, %{dchannel}, %{state} =item B<--critical-status> -Define the conditions to match for the status to be CRITICAL (Default: '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i'). +Define the conditions to match for the status to be CRITICAL (default: '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i'). You can use the following variables: %{display}, %{alarm}, %{dchannel}, %{state} -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> -Warning threshold. +Thresholds. Can be: 'avg-calls', 'max-calls', 'count-calls'. -=item B<--critical-*> - -Critical threshold. -Can be: 'avg-calls', 'max-calls', 'count-calls'. - - =back =cut diff --git a/src/network/audiocodes/snmp/plugin.pm b/src/network/audiocodes/snmp/plugin.pm index 0b254baf5..4be5e750c 100644 --- a/src/network/audiocodes/snmp/plugin.pm +++ b/src/network/audiocodes/snmp/plugin.pm @@ -29,15 +29,15 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cpu' => 'network::audiocodes::snmp::mode::cpu', - 'hardware' => 'network::audiocodes::snmp::mode::hardware', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'list-trunks' => 'network::audiocodes::snmp::mode::listtrunks', - 'memory' => 'network::audiocodes::snmp::mode::memory', - 'trunk-status' => 'network::audiocodes::snmp::mode::trunkstatus', + 'cpu' => 'network::audiocodes::snmp::mode::cpu', + 'hardware' => 'network::audiocodes::snmp::mode::hardware', + 'interfaces' => 'network::audiocodes::snmp::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-trunks' => 'network::audiocodes::snmp::mode::listtrunks', + 'memory' => 'network::audiocodes::snmp::mode::memory', + 'sbc-calls' => 'network::audiocodes::snmp::mode::sbccalls', + 'trunk-status' => 'network::audiocodes::snmp::mode::trunkstatus', ); return $self;