From d024c2f9c5b9df172d96221a0daf5dc0765628ef Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 7 May 2014 11:13:13 +0200 Subject: [PATCH 1/5] Fix #5528 --- centreon/plugins/perfdata.pm | 99 ++++++------------------------------ 1 file changed, 15 insertions(+), 84 deletions(-) diff --git a/centreon/plugins/perfdata.pm b/centreon/plugins/perfdata.pm index 8d3026a1d..f8ebb617e 100644 --- a/centreon/plugins/perfdata.pm +++ b/centreon/plugins/perfdata.pm @@ -109,42 +109,10 @@ sub trim { return $value; } -sub continue_to { - my $self = shift; - my ($forbidden, $stop1, $not_stop_after) = @_; - my $value = ""; - - while ($self->{perfdata_pos} < $self->{perfdata_size}) { - if (defined($forbidden) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] =~ /$forbidden/) { - return undef; - } - if (${$self->{perfdata_chars}}[$self->{perfdata_pos}] =~ /$stop1/) { - if (!defined($not_stop_after)) { - return $value; - } - if (!($self->{perfdata_pos} + 1 < $self->{perfdata_size} && ${$self->{perfdata_chars}}[$self->{perfdata_pos} + 1] =~ /$not_stop_after/)) { - $self->{perfdata_pos}++; - return $value; - } - $self->{perfdata_pos}++; - } - - $value .= ${$self->{perfdata_chars}}[$self->{perfdata_pos}]; - $self->{perfdata_pos}++; - } - - return $value; -} - sub parse_threshold { my $self = shift; - @{$self->{perfdata_chars}} = split //, $self->trim($_[0]); - $self->{perfdata_pos} = 0; - $self->{perfdata_size} = scalar(@{$self->{perfdata_chars}}); - - my $neg = 1; - my $value_tmp = ""; + my $perf = $self->trim($_[0]); my $arobase = 0; my $infinite_neg = 0; @@ -153,63 +121,26 @@ sub parse_threshold { my $value_end = ""; my $global_status = 1; - if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "@") { - $arobase = 1; - $self->{perfdata_pos}++; - } - - if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "~") { - $infinite_neg = 1; - $self->{perfdata_pos}++; - } else { - if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "-") { - $neg = -1; - $self->{perfdata_pos}++; - } - $value_tmp = $self->continue_to(undef, "[^0-9\.,]"); - if (defined($value_tmp) && $value_tmp ne "") { - $value_tmp =~ s/,/./g; - $value_tmp = $value_tmp * $neg; - } - $neg = 1; - } - - if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq ":") { - if ($value_tmp ne "") { - $value_start = $value_tmp; - } else { - $value_start = 0; - } - $self->{perfdata_pos}++; - - if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "-") { - $neg = -1; - $self->{perfdata_pos}++; - } - $value_end = $self->continue_to(undef, "[^0-9\.,]"); - if (defined($value_tmp) && $value_end ne "") { - $value_end =~ s/,/./g; - $value_end = $value_end * $neg; - } else { + if ($perf =~ /^(\@?)((?:~|(?:\+|-)?\d+(?:[\.,]\d+)?|):)?((?:\+|-)?\d+(?:[\.,]\d+)?)?$/) { + ($exclusive, $value_start, $value_end) = ($1, $2, $3); + $value_start =~ s/[\+:]//g; + $value_end =~ s/\+//; + if (!defined($value_end)) { + $value_end = 1e500; $infinite_pos = 1; } + $value_start = 0 if (!defined($value_start) || $value_start eq ''); + $value_start =~ s/,/\./; + $value_end =~ s/,/\./; + + if ($value_start eq '~') { + $value_start = -1e500; + $infinite_neg = 1; + } } else { - $value_start = 0; - $value_end = $value_tmp; - } - - my $value = $self->continue_to(undef, "[ \t;]"); - if ($value ne '') { $global_status = 0; } - if ($infinite_neg == 1) { - $value_start = '-1e500'; - } - if ($infinite_pos == 1) { - $value_end = '1e500'; - } - return ($global_status, $value_start, $value_end, $arobase, $infinite_neg, $infinite_pos); } From 6a83ff0582318e4b30a9ac3ca2050acf2ca0cebc Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 7 May 2014 11:40:16 +0200 Subject: [PATCH 2/5] Refs #5528 Add 'use strict' and some fix in core --- centreon/plugins/options.pm | 11 +++++++---- centreon/plugins/output.pm | 3 +++ centreon/plugins/perfdata.pm | 11 ++++++++--- centreon/plugins/statefile.pm | 3 +++ hardware/sensors/sequoia/em01/web/mode/contact.pm | 2 -- hardware/sensors/sequoia/em01/web/mode/humidity.pm | 2 -- .../sensors/sequoia/em01/web/mode/illumination.pm | 2 -- hardware/sensors/sequoia/em01/web/mode/temperature.pm | 2 -- hardware/sensors/sequoia/em01/web/mode/voltage.pm | 2 -- 9 files changed, 21 insertions(+), 17 deletions(-) diff --git a/centreon/plugins/options.pm b/centreon/plugins/options.pm index 73acddc6c..52743ffd0 100644 --- a/centreon/plugins/options.pm +++ b/centreon/plugins/options.pm @@ -34,11 +34,14 @@ #################################################################################### package centreon::plugins::options; + use Pod::Usage; use Pod::Find qw(pod_where); use Getopt::Long; Getopt::Long::Configure("pass_through"); Getopt::Long::Configure('bundling'); +use strict; +use warnings; sub new { my $class = shift; @@ -61,9 +64,9 @@ sub set_output { sub display_help { my ($self, %options) = @_; + my $stdout; foreach (@{$self->{pod_package}}) { - my $stdout; - + { local *STDOUT; open STDOUT, '>', \$stdout; @@ -88,9 +91,9 @@ sub add_help { } if (defined($options{help_first})) { - shift @{$self->{pod_package}}, {package => $options{package}, sections => $options{sections}}; + unshift @{$self->{pod_package}}, {package => $options{package}, sections => $options{sections}}; } else { - push @{$self->{pod_package}}, {package => $options{package}, sections => $options{sections}}; + push @{$self->{pod_package}}, { package => $options{package}, sections => $options{sections} }; } $self->{pod_packages_once}->{$options{package}} = 1; diff --git a/centreon/plugins/output.pm b/centreon/plugins/output.pm index 69b3ef2e9..fb1c4f8db 100644 --- a/centreon/plugins/output.pm +++ b/centreon/plugins/output.pm @@ -34,8 +34,11 @@ #################################################################################### package centreon::plugins::output; + use Encode; use centreon::plugins::misc; +use strict; +use warnings; sub new { my ($class, %options) = @_; diff --git a/centreon/plugins/perfdata.pm b/centreon/plugins/perfdata.pm index f8ebb617e..c689e6201 100644 --- a/centreon/plugins/perfdata.pm +++ b/centreon/plugins/perfdata.pm @@ -35,6 +35,9 @@ package centreon::plugins::perfdata; +use strict; +use warnings; + sub new { my ($class, %options) = @_; my $self = {}; @@ -122,14 +125,16 @@ sub parse_threshold { my $global_status = 1; if ($perf =~ /^(\@?)((?:~|(?:\+|-)?\d+(?:[\.,]\d+)?|):)?((?:\+|-)?\d+(?:[\.,]\d+)?)?$/) { - ($exclusive, $value_start, $value_end) = ($1, $2, $3); + $value_start = $2 if (defined($2)); + $value_end = $3 if (defined($3)); + $arobase = 1 if (defined($1) && $1 eq '@'); $value_start =~ s/[\+:]//g; $value_end =~ s/\+//; - if (!defined($value_end)) { + if ($value_end eq '') { $value_end = 1e500; $infinite_pos = 1; } - $value_start = 0 if (!defined($value_start) || $value_start eq ''); + $value_start = 0 if ($value_start eq ''); $value_start =~ s/,/\./; $value_end =~ s/,/\./; diff --git a/centreon/plugins/statefile.pm b/centreon/plugins/statefile.pm index 3a4f6c200..a4379a963 100644 --- a/centreon/plugins/statefile.pm +++ b/centreon/plugins/statefile.pm @@ -34,6 +34,9 @@ #################################################################################### package centreon::plugins::statefile; + +use strict; +use warnings; use Data::Dumper; use vars qw($datas); diff --git a/hardware/sensors/sequoia/em01/web/mode/contact.pm b/hardware/sensors/sequoia/em01/web/mode/contact.pm index 1c32fd2ff..b5f3afdb1 100644 --- a/hardware/sensors/sequoia/em01/web/mode/contact.pm +++ b/hardware/sensors/sequoia/em01/web/mode/contact.pm @@ -156,8 +156,6 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--password> - =item B<--timeout> Threshold for HTTP timeout diff --git a/hardware/sensors/sequoia/em01/web/mode/humidity.pm b/hardware/sensors/sequoia/em01/web/mode/humidity.pm index e81b2ea49..ce356d3ac 100644 --- a/hardware/sensors/sequoia/em01/web/mode/humidity.pm +++ b/hardware/sensors/sequoia/em01/web/mode/humidity.pm @@ -157,8 +157,6 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--password> - =item B<--timeout> Threshold for HTTP timeout diff --git a/hardware/sensors/sequoia/em01/web/mode/illumination.pm b/hardware/sensors/sequoia/em01/web/mode/illumination.pm index be97ca196..0618ff12e 100644 --- a/hardware/sensors/sequoia/em01/web/mode/illumination.pm +++ b/hardware/sensors/sequoia/em01/web/mode/illumination.pm @@ -157,8 +157,6 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--password> - =item B<--timeout> Threshold for HTTP timeout diff --git a/hardware/sensors/sequoia/em01/web/mode/temperature.pm b/hardware/sensors/sequoia/em01/web/mode/temperature.pm index 17fe3ab6b..12c973283 100644 --- a/hardware/sensors/sequoia/em01/web/mode/temperature.pm +++ b/hardware/sensors/sequoia/em01/web/mode/temperature.pm @@ -156,8 +156,6 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--password> - =item B<--timeout> Threshold for HTTP timeout diff --git a/hardware/sensors/sequoia/em01/web/mode/voltage.pm b/hardware/sensors/sequoia/em01/web/mode/voltage.pm index a42be9400..206463b59 100644 --- a/hardware/sensors/sequoia/em01/web/mode/voltage.pm +++ b/hardware/sensors/sequoia/em01/web/mode/voltage.pm @@ -157,8 +157,6 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--password> - =item B<--timeout> Threshold for HTTP timeout From 4a50af1a7b289aa06c2e22dc847831e20a0d647f Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 7 May 2014 23:13:30 +0200 Subject: [PATCH 3/5] Fix #5494 --- apps/apache/serverstatus/mode/cpuload.pm | 2 - apps/apache/serverstatus/mode/requests.pm | 2 - centreon/plugins/output.pm | 2 +- os/linux/snmp/plugin.pm | 1 + snmp_standard/mode/tcpcon.pm | 396 ++++++++++++++++++++++ 5 files changed, 398 insertions(+), 5 deletions(-) create mode 100644 snmp_standard/mode/tcpcon.pm diff --git a/apps/apache/serverstatus/mode/cpuload.pm b/apps/apache/serverstatus/mode/cpuload.pm index 031edd36f..2c02c695e 100644 --- a/apps/apache/serverstatus/mode/cpuload.pm +++ b/apps/apache/serverstatus/mode/cpuload.pm @@ -161,8 +161,6 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--password> - =item B<--timeout> Threshold for HTTP timeout diff --git a/apps/apache/serverstatus/mode/requests.pm b/apps/apache/serverstatus/mode/requests.pm index 0776a4fbb..2b74dab7a 100644 --- a/apps/apache/serverstatus/mode/requests.pm +++ b/apps/apache/serverstatus/mode/requests.pm @@ -243,8 +243,6 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--password> - =item B<--timeout> Threshold for HTTP timeout diff --git a/centreon/plugins/output.pm b/centreon/plugins/output.pm index fb1c4f8db..8e77873f8 100644 --- a/centreon/plugins/output.pm +++ b/centreon/plugins/output.pm @@ -384,7 +384,7 @@ sub output_txt { print (($options{nolabel} == 0 ? 'UNKNOWN: ' : '') . $self->{global_short_concat_outputs}->{UNKNOWN} . " "); } if (uc($options{exit_litteral}) eq 'OK') { - print (($options{nolabel} == 0 ? 'OK: ' : '') . $self->{global_short_concat_outputs}->{OK} . " "); + print (($options{nolabel} == 0 ? 'OK: ' : '') . (defined($self->{global_short_concat_outputs}->{OK}) ? $self->{global_short_concat_outputs}->{OK} : '') . " "); } if ($force_ignore_perfdata == 1) { diff --git a/os/linux/snmp/plugin.pm b/os/linux/snmp/plugin.pm index 186b23122..ec43d5227 100644 --- a/os/linux/snmp/plugin.pm +++ b/os/linux/snmp/plugin.pm @@ -61,6 +61,7 @@ sub new { 'processcount' => 'snmp_standard::mode::processcount', 'storage' => 'snmp_standard::mode::storage', 'swap' => 'snmp_standard::mode::swap', + 'tcpcon' => 'snmp_standard::mode::tcpcon', 'traffic' => 'snmp_standard::mode::traffic', 'uptime' => 'snmp_standard::mode::uptime', ); diff --git a/snmp_standard/mode/tcpcon.pm b/snmp_standard/mode/tcpcon.pm new file mode 100644 index 000000000..153ff7d59 --- /dev/null +++ b/snmp_standard/mode/tcpcon.pm @@ -0,0 +1,396 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation ; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::tcpcon; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_states = ( + 1 => 'closed', + 2 => 'listen', + 3 => 'synSent', + 4 => 'synReceived', + 5 => 'established', + 6 => 'finWait1', + 7 => 'finWait2', + 8 => 'closeWait', + 9 => 'lastAck', + 10 => 'closing', + 11 => 'timeWait', + 12 => 'deleteTCB', +); + +my %map_addr_type = ( + 0 => 'unknown', + 1 => 'ipv4', + 2 => 'ipv6', + 3 => 'ipv4z', + 4 => 'ipv6z', + 16 => 'dns', +); + +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 => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "service:s@" => { name => 'service', }, + "application:s@" => { name => 'application', }, + }); + @{$self->{connections}} = (); + $self->{services} = { total => { filter => '.*?#.*?#.*?#.*?#.*?#(?!(listen))', builtin => 1, number => 0, msg => 'Total connections: %d' } }; + $self->{applications} = {}; + return $self; +} + +sub get_ipv6 { + my ($self, %options) = @_; + + my $ipv6 = ''; + my $num = 1; + foreach my $val (split /\./, $options{value}) { + if ($num % 3 == 0) { + $ipv6 .= ':'; + $num++; + } + $ipv6 .= sprintf("%02x", $val); + $num++; + } + + return $ipv6; +} + +sub get_from_rfc4022 { + my ($self, %options) = @_; + + my $oid_tcpConnectionState = '.1.3.6.1.2.1.6.19.1.7'; + my $result = $self->{snmp}->get_table(oid => $oid_tcpConnectionState); + + my $oid_tcpListenerProcess = '.1.3.6.1.2.1.6.20.1.4'; + my $result2 = $self->{snmp}->get_table(oid => $oid_tcpListenerProcess); + return 0 if (scalar(keys %$result) + scalar(keys %$result2) == 0); + + # Listener + foreach (keys %$result2) { + /^$oid_tcpListenerProcess\.(\d+)/; + my $ipv = $map_addr_type{$1}; + next if ($ipv !~ /^ipv4|ipv6$/); # manage only 'ipv4' (1) and 'ipv6' (2) for now + + my ($src_addr, $src_port, $dst_addr); + if ($ipv eq 'ipv6') { + $dst_addr = '0000:0000:0000:0000:0000:0000:0000:0000'; + /^$oid_tcpListenerProcess\.\d+\.\d+\.((?:\d+\.){16})(\d+)/; + ($src_addr, $src_port) = ($self->get_ipv6(value => $1), $2); + } else { + /^$oid_tcpListenerProcess\.\d+\.\d+\.(\d+\.\d+\.\d+\.\d+)\.(\d+)/; + $dst_addr = '0.0.0.0'; + ($src_addr, $src_port) = ($1, $2); + } + push @{$self->{connections}}, $ipv . "#$src_addr#$src_port#$dst_addr#0#listen"; + } + + foreach (keys %$result) { + /^$oid_tcpConnectionState\.(\d+)/; + my $ipv = $map_addr_type{$1}; + next if ($ipv !~ /^ipv4|ipv6$/); # manage only 'ipv4' (1) and 'ipv6' (2) for now + + my ($src_addr, $src_port, $dst_addr, $dst_port); + if ($ipv eq 'ipv6') { + /^$oid_tcpConnectionState\.\d+\.\d+\.((?:\d+\.){16})(\d+)\.\d+\.((?:\d+\.){16})(\d+)/; + ($src_addr, $src_port, $dst_addr, $dst_port) = ($self->get_ipv6(value => $1), $2, $self->get_ipv6(value => $3), $4); + } else { + /^$oid_tcpConnectionState\.\d+\.\d+\.(\d+\.\d+\.\d+\.\d+)\.(\d+)\.\d+\.(\d+\.\d+\.\d+\.\d+)\.(\d+)/; + ($src_addr, $src_port, $dst_addr, $dst_port) = ($1, $2, $3, $4); + } + push @{$self->{connections}}, $ipv . "#$src_addr#$src_port#$dst_addr#$dst_port#" . lc($map_states{$result->{$_}}); + } + + return 1; +} + +sub get_from_rfc1213 { + my ($self, %options) = @_; + + my $oid_tcpConnState = '.1.3.6.1.2.1.6.13.1.1'; + my $result = $self->{snmp}->get_table(oid => $oid_tcpConnState, nothing_quit => 1); + + # Construct + foreach (keys %$result) { + /(\d+\.\d+\.\d+\.\d+).(\d+)\.(\d+\.\d+\.\d+\.\d+).(\d+)$/; + push @{$self->{connections}}, "ipv4#$1#$2#$3#$4#" . lc($map_states{$result->{$_}}); + } +} + +sub build_connections { + my ($self, %options) = @_; + + if ($self->get_from_rfc4022() == 0) { + $self->get_from_rfc1213(); + } +} + +sub check_services { + my ($self, %options) = @_; + + foreach my $service (@{$self->{option_results}->{service}}) { + my ($tag, $ipv, $state, $port_src, $port_dst, $filter_ip_src, $filter_ip_dst, $warn, $crit) = split /,/, $service; + + if (!defined($tag) || $tag eq '') { + $self->{output}->add_option_msg(short_msg => "Tag for service '" . $service . "' must be defined."); + $self->{output}->option_exit(); + } + if (defined($self->{services}->{$tag})) { + $self->{output}->add_option_msg(short_msg => "Tag '" . $tag . "' (service) already exists."); + $self->{output}->option_exit(); + } + + $self->{services}->{$tag} = { filter => ((defined($ipv) && $ipv ne '') ? $ipv : '.*?') . '#' . + ((defined($filter_ip_src) && $filter_ip_src ne '') ? $filter_ip_src : '.*?') . '#' . + ((defined($port_src) && $port_src ne '') ? $port_src : '.*?') . '#' . + ((defined($filter_ip_dst) && $filter_ip_dst ne '') ? $filter_ip_dst : '.*?') . '#' . + ((defined($port_dst) && $port_dst ne '') ? $port_dst : '.*?') . '#' . + ((defined($state) && $state ne '') ? lc($state) : '(?!(listen))') + , + builtin => 0, number => 0 }; + if (($self->{perfdata}->threshold_validate(label => 'warning-service-' . $tag, value => $warn)) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $warn . "' for service '$tag'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-service-' . $tag, value => $crit)) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $crit . "' for service '$tag'."); + $self->{output}->option_exit(); + } + } +} + +sub check_applications { + my ($self, %options) = @_; + + foreach my $app (@{$self->{option_results}->{application}}) { + my ($tag, $services, $warn, $crit) = split /,/, $app; + + if (!defined($tag) || $tag eq '') { + $self->{output}->add_option_msg(short_msg => "Tag for application '" . $app . "' must be defined."); + $self->{output}->option_exit(); + } + if (defined($self->{applications}->{$tag})) { + $self->{output}->add_option_msg(short_msg => "Tag '" . $tag . "' (application) already exists."); + $self->{output}->option_exit(); + } + + $self->{applications}->{$tag} = { + services => {}, + }; + foreach my $service (split /\|/, $services) { + if (!defined($self->{services}->{$service})) { + $self->{output}->add_option_msg(short_msg => "Service '" . $service . "' is not defined."); + $self->{output}->option_exit(); + } + $self->{applications}->{$tag}->{services}->{$service} = 1; + } + + if (($self->{perfdata}->threshold_validate(label => 'warning-app-' . $tag, value => $warn)) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $warn . "' for application '$tag'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-app-' . $tag, value => $crit)) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $crit . "' for application '$tag'."); + $self->{output}->option_exit(); + } + } +} + +sub test_services { + my ($self, %options) = @_; + + foreach my $tag (keys %{$self->{services}}) { + foreach (@{$self->{connections}}) { + if (/$self->{services}->{$tag}->{filter}/) { + $self->{services}->{$tag}->{number}++; + } + } + + my $exit_code = $self->{perfdata}->threshold_check(value => $self->{services}->{$tag}->{number}, + threshold => [ { label => 'critical-service-' . $tag, 'exit_litteral' => 'critical' }, { label => 'warning-service-' . $tag, exit_litteral => 'warning' } ]); + my ($perf_label, $msg) = ('service_' . $tag, "Service '$tag' connections: %d"); + if ($self->{services}->{$tag}->{builtin} == 1) { + ($perf_label, $msg) = ($tag, $self->{services}->{$tag}->{msg}); + } + + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf($msg, $self->{services}->{$tag}->{number})); + $self->{output}->perfdata_add(label => $perf_label, + value => $self->{services}->{$tag}->{number}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-service-' . $tag), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-service-' . $tag), + min => 0); + } +} + +sub test_applications { + my ($self, %options) = @_; + + foreach my $tag (keys %{$self->{applications}}) { + my $number = 0; + + foreach (keys %{$self->{applications}->{$tag}->{services}}) { + $number += $self->{services}->{$_}->{number}; + } + + my $exit_code = $self->{perfdata}->threshold_check(value => $number, + threshold => [ { label => 'critical-app-' . $tag, 'exit_litteral' => 'critical' }, { label => 'warning-app-' . $tag, exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Applicatin '%s' connections: %d", $tag, $number)); + $self->{output}->perfdata_add(label => 'app_' . $tag, + value => $number, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-app-' . $tag), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-app-' . $tag), + min => 0); + } +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning-service-total', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-service-total', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } + $self->check_services(); + $self->check_applications(); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->build_connections(); + $self->test_services(); + $self->test_applications(); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check tcp connections. + +=over 8 + +=item B<--warning> + +Threshold warning for total connections. + +=item B<--critical> + +Threshold critical for total connections. + +=item B<--service> + +Check tcp connections following rules: +tag,[type],[state],[port-src],[port-dst],[filter-ip-src],[filter-ip-dst],[threshold-warning],[threshold-critical] + +Example to test SSH connections on the server: --service="ssh,,,22,,,,10,20" + +=over 16 + +=item + +Name to identify service (must be unique and couldn't be 'total'). + +=item + +regexp - can use 'ipv4', 'ipv6'. Empty means all. + +=item + +regexp - can use 'finWait1', 'established',... Empty means all (minus listen). + +=item + +regexp - can use to exclude or include some IPs. + +=item + +nagios-perfdata - number of connections. + +=back + +=item B<--application> + +Check tcp connections of mutiple services: +tag,[services],[threshold-warning],[threshold-critical] + +Example: +--application="web,http|https,100,200" + +=over 16 + +=item + +Name to identify application (must be unique). + +=item + +List of services (used the tag name. Separated by '|'). + +=item + +nagios-perfdata - number of connections. + +=back + +=back + +=cut From c558ddc9b39d81fdf1b58444e58e227b990ba56d Mon Sep 17 00:00:00 2001 From: Florian Asche Date: Thu, 8 May 2014 15:29:59 +0200 Subject: [PATCH 4/5] Ref #5529 Bugfix: Added uri_unescape --- apps/tomcat/web/mode/requestinfo.pm | 2 ++ apps/tomcat/web/mode/threads.pm | 2 ++ apps/tomcat/web/mode/traffic.pm | 2 ++ 3 files changed, 6 insertions(+) diff --git a/apps/tomcat/web/mode/requestinfo.pm b/apps/tomcat/web/mode/requestinfo.pm index 4412a7139..ab0a9f815 100644 --- a/apps/tomcat/web/mode/requestinfo.pm +++ b/apps/tomcat/web/mode/requestinfo.pm @@ -42,6 +42,7 @@ use centreon::plugins::httplib; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); use XML::XPath; +use URI::Escape; sub new { my ($class, %options) = @_; @@ -203,6 +204,7 @@ sub manage_selection { my $connector_name = $node->getParentNode()->getParentNode()->getAttribute("name"); $connector_name =~ s/^["'\s]+//; $connector_name =~ s/["'\s]+$//; + $connector_name = uri_unescape($connector_name); next if (defined($self->{option_results}->{name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $connector_name !~ /$self->{option_results}->{name}/i); diff --git a/apps/tomcat/web/mode/threads.pm b/apps/tomcat/web/mode/threads.pm index 89fbcaea0..6e386ba0b 100644 --- a/apps/tomcat/web/mode/threads.pm +++ b/apps/tomcat/web/mode/threads.pm @@ -40,6 +40,7 @@ use strict; use warnings; use centreon::plugins::httplib; use XML::XPath; +use URI::Escape; sub new { my ($class, %options) = @_; @@ -160,6 +161,7 @@ sub manage_selection { my $connector_name = $node->getParentNode()->getParentNode()->getAttribute("name"); $connector_name =~ s/^["'\s]+//; $connector_name =~ s/["'\s]+$//; + $connector_name = uri_unescape($connector_name); next if (defined($self->{option_results}->{name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $connector_name !~ /$self->{option_results}->{name}/i); diff --git a/apps/tomcat/web/mode/traffic.pm b/apps/tomcat/web/mode/traffic.pm index f212c2572..a8f02933e 100644 --- a/apps/tomcat/web/mode/traffic.pm +++ b/apps/tomcat/web/mode/traffic.pm @@ -43,6 +43,7 @@ use centreon::plugins::misc; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); use XML::XPath; +use URI::Escape; sub new { my ($class, %options) = @_; @@ -188,6 +189,7 @@ sub manage_selection { my $connector_name = $node->getParentNode()->getParentNode()->getAttribute("name"); $connector_name =~ s/^["'\s]+//; $connector_name =~ s/["'\s]+$//; + $connector_name = uri_unescape($connector_name); next if (defined($self->{option_results}->{name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $connector_name !~ /$self->{option_results}->{name}/i); From 2d6297c266994d170109cc66ad85db2ff544646e Mon Sep 17 00:00:00 2001 From: Florian Asche Date: Fri, 9 May 2014 11:27:18 +0200 Subject: [PATCH 5/5] Refs #5529: Bugfix - Added Port to Cache File to avoid problems with multiple tomcat instances on one server. --- apps/tomcat/web/mode/requestinfo.pm | 2 +- apps/tomcat/web/mode/traffic.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/tomcat/web/mode/requestinfo.pm b/apps/tomcat/web/mode/requestinfo.pm index ab0a9f815..1c888cf01 100644 --- a/apps/tomcat/web/mode/requestinfo.pm +++ b/apps/tomcat/web/mode/requestinfo.pm @@ -238,7 +238,7 @@ sub run { $self->manage_selection(); my $new_datas = {}; - $self->{statefile_value}->read(statefile => "cache_apps_tomcat_web_" . $self->{hostname} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); + $self->{statefile_value}->read(statefile => 'cache_apps_tomcat_web_' . $self->{option_results}->{hostname} . '_' . $self->{option_results}->{port} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); $new_datas->{last_timestamp} = time(); my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); diff --git a/apps/tomcat/web/mode/traffic.pm b/apps/tomcat/web/mode/traffic.pm index a8f02933e..0b0d7a117 100644 --- a/apps/tomcat/web/mode/traffic.pm +++ b/apps/tomcat/web/mode/traffic.pm @@ -223,7 +223,7 @@ sub run { $self->manage_selection(); my $new_datas = {}; - $self->{statefile_value}->read(statefile => "cache_apps_tomcat_web_" . $self->{hostname} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); + $self->{statefile_value}->read(statefile => 'cache_apps_tomcat_web_' . $self->{option_results}->{hostname} . '_' . $self->{option_results}->{port} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); $new_datas->{last_timestamp} = time(); my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp');