diff --git a/cloud/aws/elb/application/mode/connections.pm b/cloud/aws/elb/application/mode/connections.pm new file mode 100644 index 000000000..f0f105464 --- /dev/null +++ b/cloud/aws/elb/application/mode/connections.pm @@ -0,0 +1,235 @@ +# +# 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 cloud::aws::elb::application::mode::connections; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my %metrics_mapping = ( + 'ActiveConnectionCount' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'Active Connection', + 'label' => 'connection-active', + 'nlabel' => 'elb.connection.active.count', + }, + 'NewConnectionCount' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'New Connection', + 'label' => 'connection-new', + 'nlabel' => 'elb.connection.new.count', + }, + 'RejectedConnectionCount' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'Rejected Connection', + 'label' => 'connection-rejected', + 'nlabel' => 'elb.rejected.new.count', + }, + 'TargetConnectionErrorCount' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'Target Connection Error', + 'label' => 'target-connection-error', + 'nlabel' => 'elb.target.connection.error.count', + }, +); + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "ELB '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub prefix_statistics_output { + my ($self, %options) = @_; + + return "Statistic '" . $options{instance_value}->{display} . "' Metrics "; +} + +sub long_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "Checking '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metrics', type => 3, cb_prefix_output => 'prefix_metric_output', cb_long_output => 'long_output', + message_multiple => 'All elb metrics are ok', indent_long_output => ' ', + group => [ + { name => 'statistics', display_long => 1, cb_prefix_output => 'prefix_statistics_output', + message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } }, + ] + } + ]; + + foreach my $metric (keys %metrics_mapping) { + my $entry = { + label => $metrics_mapping{$metric}->{label}, + nlabel => $metrics_mapping{$metric}->{nlabel}, + set => { + key_values => [ { name => $metric }, { name => 'display' } ], + output_template => $metrics_mapping{$metric}->{output} . ': %.2f', + perfdatas => [ + { value => $metric . '_absolute', template => '%.2f', label_extra_instance => 1 } + ], + } + }; + push @{$self->{maps_counters}->{statistics}}, $entry; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "availability-zone:s" => { name => 'availability_zone' }, + "filter-metric:s" => { name => 'filter_metric' }, + "statistic:s@" => { name => 'statistic' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{name}) || $self->{option_results}->{name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --name option."); + $self->{output}->option_exit(); + } + + foreach my $instance (@{$self->{option_results}->{name}}) { + if ($instance ne '') { + push @{$self->{aws_instance}}, $instance; + } + } + + $self->{aws_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 600; + $self->{aws_period} = defined($self->{option_results}->{period}) ? $self->{option_results}->{period} : 60; + + $self->{aws_statistics} = ['Sum']; + if (defined($self->{option_results}->{statistic})) { + $self->{aws_statistics} = []; + foreach my $stat (@{$self->{option_results}->{statistic}}) { + if ($stat ne '') { + push @{$self->{aws_statistics}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %metrics_mapping) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{aws_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $instance (@{$self->{aws_instance}}) { + push @{$self->{aws_dimensions}}, { Name => 'LoadBalancer', Value => $instance }; + if (defined($self->{option_results}->{availability_zone}) && $self->{option_results}->{availability_zone} ne '') { + push @{$self->{aws_dimensions}}, { Name => 'AvailabilityZone', Value => $self->{option_results}->{availability_zone} }; + } + $metric_results{$instance} = $options{custom}->cloudwatch_get_metrics( + region => $self->{option_results}->{region}, + namespace => 'AWS/ApplicationELB', + dimensions => $self->{aws_dimensions}, + metrics => $self->{aws_metrics}, + statistics => $self->{aws_statistics}, + timeframe => $self->{aws_timeframe}, + period => $self->{aws_period}, + ); + + foreach my $metric (@{$self->{aws_metrics}}) { + foreach my $statistic (@{$self->{aws_statistics}}) { + next if (!defined($metric_results{$instance}->{$metric}->{lc($statistic)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metrics}->{$instance}->{display} = $instance; + $self->{metrics}->{$instance}->{availability_zone} = $self->{option_results}->{availability_zone}; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{display} = $statistic; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{$metric} = defined($metric_results{$instance}->{$metric}->{lc($statistic)}) ? $metric_results{$instance}->{$metric}->{lc($statistic)} : 0; + } + } + } + + if (scalar(keys %{$self->{metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Application ELB connections metrics. + +Example: +perl centreon_plugins.pl --plugin=cloud::aws::elb::application::plugin --custommode=paws --mode=connections +--region='eu-west-1' --name='app/AppProd/7c8ecfbd1093c5bd' --critical-connection-rejected='10' --verbose + +See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html' for more informations. + +Default statistic: 'sum' / Most usefull statistics: 'sum'. + +=over 8 + +=item B<--name> + +Set the instance name (Required) (Can be multiple). + +=item B<--availability-zone> + +Add Availability Zone dimension. + +=item B<--filter-metric> + +Filter metrics (Can be: ActiveConnectionCount', 'NewConnectionCount', +'RejectedConnectionCount', 'TargetConnectionErrorCount') +(Can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds warning (Can be: 'connection-active', 'connection-new', +'connection-rejected', 'target-connection-error'). + +=back + +=cut diff --git a/cloud/aws/elb/application/mode/discovery.pm b/cloud/aws/elb/application/mode/discovery.pm new file mode 100644 index 000000000..54ee9a644 --- /dev/null +++ b/cloud/aws/elb/application/mode/discovery.pm @@ -0,0 +1,111 @@ +# +# 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 cloud::aws::elb::application::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + "prettify" => { name => 'prettify' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $load_balancers = $options{custom}->discovery( + region => $self->{option_results}->{region}, + service => 'elbv2', + command => 'describe-load-balancers' + ); + + foreach my $load_balancer (@{$load_balancers->{LoadBalancers}}) { + next if (!defined($load_balancer->{LoadBalancerArn}) || $load_balancer->{Type} ne 'application'); + my %elb; + $elb{type} = "application"; + $elb{name} = $1 if ($load_balancer->{LoadBalancerArn} =~ /arn:aws:elasticloadbalancing:.*:loadbalancer\/(.*)/); + $elb{dns_name} = $load_balancer->{DNSName}; + $elb{availability_zones} = $load_balancer->{AvailabilityZones}; + $elb{vpc_id} = $load_balancer->{VpcId}; + $elb{security_groups} = $load_balancer->{SecurityGroups}; + $elb{state} = $load_balancer->{State}->{Code}; + push @disco_data, \%elb; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Application ELB discovery. + +=over 8 + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/cloud/aws/elb/application/mode/httpcodes.pm b/cloud/aws/elb/application/mode/httpcodes.pm new file mode 100644 index 000000000..c7a7ec7a4 --- /dev/null +++ b/cloud/aws/elb/application/mode/httpcodes.pm @@ -0,0 +1,250 @@ +# +# 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 cloud::aws::elb::application::mode::httpcodes; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my %metrics_mapping = ( + 'HTTPCode_Target_2XX_Count' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'Target HTTP 2XXs', + 'label' => 'httpcode-target-2xx', + 'nlabel' => 'elb.httpcode.target.2xx.count', + }, + 'HTTPCode_Target_3XX_Count' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'Target HTTP 3XXs', + 'label' => 'httpcode-target-3xx', + 'nlabel' => 'elb.httpcode.target.3xx.count', + }, + 'HTTPCode_Target_4XX_Count' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'Target HTTP 4XXs', + 'label' => 'httpcode-target-4xx', + 'nlabel' => 'elb.httpcode.target.4xx.count', + }, + 'HTTPCode_Target_5XX_Count' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'Target HTTP 5XXs', + 'label' => 'httpcode-target-5xx', + 'nlabel' => 'elb.httpcode.target.5xx.count', + }, + 'HTTPCode_ELB_3XX_Count' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'ELB HTTP 3XXs', + 'label' => 'httpcode-elb-3xx', + 'nlabel' => 'elb.httpcode.elb.3xx.count', + }, + 'HTTPCode_ELB_4XX_Count' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'ELB HTTP 4XXs', + 'label' => 'httpcode-elb-4xx', + 'nlabel' => 'elb.httpcode.elb.4xx.count', + }, + 'HTTP_Redirect_Count' => { # Minimum, Maximum, and Average all return 1. + 'output' => 'HTTP Redirect', + 'label' => 'http-redirect', + 'nlabel' => 'elb.http.redirect.count', + }, +); + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "ELB '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub prefix_statistics_output { + my ($self, %options) = @_; + + return "Statistic '" . $options{instance_value}->{display} . "' Metrics "; +} + +sub long_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "Checking '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metrics', type => 3, cb_prefix_output => 'prefix_metric_output', cb_long_output => 'long_output', + message_multiple => 'All elb metrics are ok', indent_long_output => ' ', + group => [ + { name => 'statistics', display_long => 1, cb_prefix_output => 'prefix_statistics_output', + message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } }, + ] + } + ]; + + foreach my $metric (keys %metrics_mapping) { + my $entry = { + label => $metrics_mapping{$metric}->{label}, + nlabel => $metrics_mapping{$metric}->{nlabel}, + set => { + key_values => [ { name => $metric }, { name => 'display' } ], + output_template => $metrics_mapping{$metric}->{output} . ': %.2f', + perfdatas => [ + { value => $metric . '_absolute', template => '%.2f', label_extra_instance => 1 } + ], + } + }; + push @{$self->{maps_counters}->{statistics}}, $entry; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "availability-zone:s" => { name => 'availability_zone' }, + "filter-metric:s" => { name => 'filter_metric' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{name}) || $self->{option_results}->{name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --name option."); + $self->{output}->option_exit(); + } + + foreach my $instance (@{$self->{option_results}->{name}}) { + if ($instance ne '') { + push @{$self->{aws_instance}}, $instance; + } + } + + $self->{aws_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 600; + $self->{aws_period} = defined($self->{option_results}->{period}) ? $self->{option_results}->{period} : 60; + + $self->{aws_statistics} = ['Sum']; + if (defined($self->{option_results}->{statistic})) { + $self->{aws_statistics} = []; + foreach my $stat (@{$self->{option_results}->{statistic}}) { + if ($stat ne '') { + push @{$self->{aws_statistics}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %metrics_mapping) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{aws_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $instance (@{$self->{aws_instance}}) { + push @{$self->{aws_dimensions}}, { Name => 'LoadBalancer', Value => $instance }; + if (defined($self->{option_results}->{availability_zone}) && $self->{option_results}->{availability_zone} ne '') { + push @{$self->{aws_dimensions}}, { Name => 'AvailabilityZone', Value => $self->{option_results}->{availability_zone} }; + } + $metric_results{$instance} = $options{custom}->cloudwatch_get_metrics( + region => $self->{option_results}->{region}, + namespace => 'AWS/ApplicationELB', + dimensions => $self->{aws_dimensions}, + metrics => $self->{aws_metrics}, + statistics => $self->{aws_statistics}, + timeframe => $self->{aws_timeframe}, + period => $self->{aws_period}, + ); + + foreach my $metric (@{$self->{aws_metrics}}) { + foreach my $statistic (@{$self->{aws_statistics}}) { + next if (!defined($metric_results{$instance}->{$metric}->{lc($statistic)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metrics}->{$instance}->{display} = $instance; + $self->{metrics}->{$instance}->{availability_zone} = $self->{option_results}->{availability_zone}; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{display} = $statistic; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{$metric} = defined($metric_results{$instance}->{$metric}->{lc($statistic)}) ? $metric_results{$instance}->{$metric}->{lc($statistic)} : 0; + } + } + } + + if (scalar(keys %{$self->{metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Application ELB HTTP codes metrics. + +Example: +perl centreon_plugins.pl --plugin=cloud::aws::elb::application::plugin --custommode=paws --mode=http-codes +--region='eu-west-1' --name='app/AppProd/7c8ecfbd1093c5bd' --critical-httpcode-target-4xx='10' --verbose + +See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html' for more informations. + +Default statistic: 'sum' / Most usefull statistics: 'sum'. + +=over 8 + +=item B<--name> + +Set the instance name (Required) (Can be multiple). + +=item B<--availability-zone> + +Add Availability Zone dimension. + +=item B<--filter-metric> + +Filter metrics (Can be: 'HTTPCode_Target_2XX_Count', 'HTTPCode_Target_3XX_Count', +'HTTPCode_Target_4XX_Count', 'HTTPCode_Target_5XX_Count', 'HTTPCode_ELB_3XX_Count', +'HTTPCode_ELB_4XX_Count', 'HTTP_Redirect_Count') +(Can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds warning (Can be: 'httpcode-target-2xx', 'httpcode-target-3xx', 'httpcode-target-4xx', +'httpcode-target-5xx', 'httpcode-elb-3xx', 'httpcode-elb-4xx', 'http-redirect') + +=back + +=cut diff --git a/cloud/aws/elb/application/mode/targetshealth.pm b/cloud/aws/elb/application/mode/targetshealth.pm new file mode 100644 index 000000000..bdd9f0ffb --- /dev/null +++ b/cloud/aws/elb/application/mode/targetshealth.pm @@ -0,0 +1,223 @@ +# +# 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 cloud::aws::elb::application::mode::targetshealth; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my %metrics_mapping = ( + 'HealthyHostCount' => { + 'output' => 'Healthy Hosts', + 'label' => 'healthyhostcount', + 'nlabel' => 'elb.healthyhostcount.count', + }, + 'UnHealthyHostCount' => { + 'output' => 'Unhealthy Hosts', + 'label' => 'unhealthyhostcount', + 'nlabel' => 'elb.unhealthyhostcount.count', + }, +); + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "ELB '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub prefix_statistics_output { + my ($self, %options) = @_; + + return "Statistic '" . $options{instance_value}->{display} . "' Metrics "; +} + +sub long_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "Checking '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metrics', type => 3, cb_prefix_output => 'prefix_metric_output', cb_long_output => 'long_output', + message_multiple => 'All elb metrics are ok', indent_long_output => ' ', + group => [ + { name => 'statistics', display_long => 1, cb_prefix_output => 'prefix_statistics_output', + message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } }, + ] + } + ]; + + foreach my $metric (keys %metrics_mapping) { + my $entry = { + label => $metrics_mapping{$metric}->{label}, + nlabel => $metrics_mapping{$metric}->{nlabel}, + set => { + key_values => [ { name => $metric }, { name => 'display' } ], + output_template => $metrics_mapping{$metric}->{output} . ': %.2f', + perfdatas => [ + { value => $metric . '_absolute', template => '%.2f', label_extra_instance => 1 } + ], + } + }; + push @{$self->{maps_counters}->{statistics}}, $entry; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "availability-zone:s" => { name => 'availability_zone' }, + "filter-metric:s" => { name => 'filter_metric' }, + "statistic:s@" => { name => 'statistic' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{name}) || $self->{option_results}->{name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --name option."); + $self->{output}->option_exit(); + } + + foreach my $instance (@{$self->{option_results}->{name}}) { + if ($instance ne '') { + push @{$self->{aws_instance}}, $instance; + } + } + + $self->{aws_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 600; + $self->{aws_period} = defined($self->{option_results}->{period}) ? $self->{option_results}->{period} : 60; + + $self->{aws_statistics} = ['Average']; + if (defined($self->{option_results}->{statistic})) { + $self->{aws_statistics} = []; + foreach my $stat (@{$self->{option_results}->{statistic}}) { + if ($stat ne '') { + push @{$self->{aws_statistics}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %metrics_mapping) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{aws_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $instance (@{$self->{aws_instance}}) { + push @{$self->{aws_dimensions}}, { Name => 'LoadBalancer', Value => $instance }; + if (defined($self->{option_results}->{availability_zone}) && $self->{option_results}->{availability_zone} ne '') { + push @{$self->{aws_dimensions}}, { Name => 'AvailabilityZone', Value => $self->{option_results}->{availability_zone} }; + } + $metric_results{$instance} = $options{custom}->cloudwatch_get_metrics( + region => $self->{option_results}->{region}, + namespace => 'AWS/ApplicationELB', + dimensions => $self->{aws_dimensions}, + metrics => $self->{aws_metrics}, + statistics => $self->{aws_statistics}, + timeframe => $self->{aws_timeframe}, + period => $self->{aws_period}, + ); + + foreach my $metric (@{$self->{aws_metrics}}) { + foreach my $statistic (@{$self->{aws_statistics}}) { + next if (!defined($metric_results{$instance}->{$metric}->{lc($statistic)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metrics}->{$instance}->{display} = $instance; + $self->{metrics}->{$instance}->{availability_zone} = $self->{option_results}->{availability_zone}; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{display} = $statistic; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{$metric} = defined($metric_results{$instance}->{$metric}->{lc($statistic)}) ? $metric_results{$instance}->{$metric}->{lc($statistic)} : 0; + } + } + } + + if (scalar(keys %{$self->{metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Application ELB targets health. + +Example: +perl centreon_plugins.pl --plugin=cloud::aws::elb::application::plugin --custommode=paws --mode=targets-health +--region='eu-west-1' --name='app/AppProd/7c8ecfbd1093c5bd' --critical-unhealthyhostcount='10' --verbose + +See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html' for more informations. + +Default statistic: 'average' / Most usefull statistics: 'average', 'minimum', 'maximum'. + +=over 8 + +=item B<--name> + +Set the instance name (Required) (Can be multiple). + +=item B<--availability-zone> + +Add Availability Zone dimension. + +=item B<--filter-metric> + +Filter metrics (Can be: 'HealthyHostCount', 'UnHealthyHostCount') +(Can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds warning (Can be: 'healthyhostcount', 'unhealthyhostcount'). + +=back + +=cut diff --git a/cloud/aws/elb/application/plugin.pm b/cloud/aws/elb/application/plugin.pm new file mode 100644 index 000000000..24279ae82 --- /dev/null +++ b/cloud/aws/elb/application/plugin.pm @@ -0,0 +1,53 @@ +# +# 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 cloud::aws::elb::application::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'connections' => 'cloud::aws::elb::application::mode::connections', + 'discovery' => 'cloud::aws::elb::application::mode::discovery', + 'http-codes' => 'cloud::aws::elb::application::mode::httpcodes', + 'targets-health' => 'cloud::aws::elb::application::mode::targetshealth', + ); + + $self->{custom_modes}{paws} = 'cloud::aws::custom::paws'; + $self->{custom_modes}{awscli} = 'cloud::aws::custom::awscli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Amazon Application Elastic Load Balancing (Amazon Application ELB). + +=cut diff --git a/cloud/aws/elb/mode/discovery.pm b/cloud/aws/elb/classic/mode/discovery.pm similarity index 96% rename from cloud/aws/elb/mode/discovery.pm rename to cloud/aws/elb/classic/mode/discovery.pm index bdb54d4bb..21c551943 100644 --- a/cloud/aws/elb/mode/discovery.pm +++ b/cloud/aws/elb/classic/mode/discovery.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package cloud::aws::elb::mode::discovery; +package cloud::aws::elb::classic::mode::discovery; use base qw(centreon::plugins::mode); @@ -60,7 +60,7 @@ sub run { foreach my $load_balancer (@{$load_balancers->{LoadBalancerDescriptions}}) { next if (!defined($load_balancer->{LoadBalancerName})); my %elb; - $elb{type} = "elb"; + $elb{type} = "classic"; $elb{name} = $load_balancer->{LoadBalancerName}; $elb{dns_name} = $load_balancer->{DNSName}; $elb{availability_zones} = $load_balancer->{AvailabilityZones}; @@ -99,7 +99,7 @@ __END__ =head1 MODE -ELB discovery. +Classic ELB discovery. =over 8 diff --git a/cloud/aws/elb/mode/httpcodes.pm b/cloud/aws/elb/classic/mode/httpcodes.pm similarity index 96% rename from cloud/aws/elb/mode/httpcodes.pm rename to cloud/aws/elb/classic/mode/httpcodes.pm index 7e6c91a46..39449871a 100644 --- a/cloud/aws/elb/mode/httpcodes.pm +++ b/cloud/aws/elb/classic/mode/httpcodes.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package cloud::aws::elb::mode::httpcodes; +package cloud::aws::elb::classic::mode::httpcodes; use base qw(centreon::plugins::templates::counter); @@ -234,10 +234,10 @@ __END__ =head1 MODE -Check ELB http codes. +Check Classic ELB HTTP codes metrics. Example: -perl centreon_plugins.pl --plugin=cloud::aws::elb::plugin --custommode=paws --mode=http-codes --region='eu-west-1' +perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode=paws --mode=http-codes --region='eu-west-1' --type='loadbalancer' --name='elb-www-fr' --critical-httpcode-backend-4xx='10' --verbose See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. @@ -264,18 +264,12 @@ Filter metrics (Can be: 'HTTPCode_Backend_2XX', 'HTTPCode_Backend_3XX', 'HTTPCod 'HTTPCode_Backend_5XX', 'HTTPCode_ELB_4XX', 'HTTPCode_ELB_5XX', 'BackendConnectionErrors') (Can be a regexp). -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> Thresholds warning (Can be: 'httpcode-backend-2xx', 'httpcode-backend-3xx', 'httpcode-backend-4xx', 'httpcode-backend-5xx', 'httpcode-elb-4xx', 'httpcode-elb-5xx', 'backendconnectionerrors') -=item B<--critical-*> - -Thresholds critical (Can be: 'httpcode-backend-2xx', 'httpcode-backend-3xx', -'httpcode-backend-4xx', 'httpcode-backend-5xx', 'httpcode-elb-4xx', -'httpcode-elb-5xx', 'backendconnectionerrors') - =back =cut diff --git a/cloud/aws/elb/mode/performances.pm b/cloud/aws/elb/classic/mode/performances.pm similarity index 96% rename from cloud/aws/elb/mode/performances.pm rename to cloud/aws/elb/classic/mode/performances.pm index 1ba00b2b6..43dfb4dd6 100644 --- a/cloud/aws/elb/mode/performances.pm +++ b/cloud/aws/elb/classic/mode/performances.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package cloud::aws::elb::mode::performances; +package cloud::aws::elb::classic::mode::performances; use base qw(centreon::plugins::templates::counter); @@ -209,11 +209,11 @@ __END__ =head1 MODE -Check ELB performances. +Check Classic ELB performances. Example: -perl centreon_plugins.pl --plugin=cloud::aws::elb::plugin --custommode=paws --mode=performances --region='eu-west-1' ---type='loadbalancer' --name='elb-www-fr' --critical-requestcount='10' --verbose +perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode=paws --mode=performances +--region='eu-west-1' --type='loadbalancer' --name='elb-www-fr' --critical-requestcount='10' --verbose See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. @@ -238,14 +238,10 @@ Add Availability Zone dimension (only with --type='loadbalancer'). Filter metrics (Can be: 'RequestCount', 'Latency') (Can be a regexp). -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> Thresholds warning (Can be: 'requestcount', 'latency'). -=item B<--critical-*> - -Thresholds critical (Can be: 'requestcount', 'latency'). - =back =cut diff --git a/cloud/aws/elb/mode/queues.pm b/cloud/aws/elb/classic/mode/queues.pm similarity index 94% rename from cloud/aws/elb/mode/queues.pm rename to cloud/aws/elb/classic/mode/queues.pm index a2c94ba65..1f3b1a5cd 100644 --- a/cloud/aws/elb/mode/queues.pm +++ b/cloud/aws/elb/classic/mode/queues.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package cloud::aws::elb::mode::queues; +package cloud::aws::elb::classic::mode::queues; use base qw(centreon::plugins::templates::counter); @@ -210,10 +210,10 @@ __END__ =head1 MODE -Check ELB surge queue. +Check Classic ELB surge queue. Example: -perl centreon_plugins.pl --plugin=cloud::aws::elb::plugin --custommode=paws --mode=queues --region='eu-west-1' +perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode=paws --mode=queues --region='eu-west-1' --type='loadbalancer' --name='elb-www-fr' --critical-spillovercount-sum='10' --verbose See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. @@ -239,15 +239,9 @@ Add Availability Zone dimension (only with --type='loadbalancer'). Filter metrics (Can be: 'SpilloverCount', 'SurgeQueueLength') (Can be a regexp). -=item B<--warning-$metric$-$statistic$> +=item B<--warning-*> B<--critical-*> -Thresholds warning ($metric$ can be: 'spillovercount', 'surgequeuelength', -$statistic$ can be: 'minimum', 'maximum', 'average', 'sum'). - -=item B<--critical-$metric$-$statistic$> - -Thresholds critical ($metric$ can be: 'spillovercount', 'surgequeuelength', -$statistic$ can be: 'minimum', 'maximum', 'average', 'sum'). +Thresholds warning (Can be: 'spillovercount', 'surgequeuelength'). =back diff --git a/cloud/aws/elb/mode/targetshealth.pm b/cloud/aws/elb/classic/mode/targetshealth.pm similarity index 96% rename from cloud/aws/elb/mode/targetshealth.pm rename to cloud/aws/elb/classic/mode/targetshealth.pm index 517e174a7..2c4b69fc4 100644 --- a/cloud/aws/elb/mode/targetshealth.pm +++ b/cloud/aws/elb/classic/mode/targetshealth.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package cloud::aws::elb::mode::targetshealth; +package cloud::aws::elb::classic::mode::targetshealth; use base qw(centreon::plugins::templates::counter); @@ -210,10 +210,10 @@ __END__ =head1 MODE -Check ELB instances health. +Check Classic ELB instances health. Example: -perl centreon_plugins.pl --plugin=cloud::aws::elb::plugin --custommode=paws --mode=instancehealth --region='eu-west-1' +perl centreon_plugins.pl --plugin=cloud::aws::elb::classic::plugin --custommode=paws --mode=instancehealth --region='eu-west-1' --type='loadbalancer' --name='elb-www-fr' --critical-healthyhostcount='10' --verbose See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html' for more informations. @@ -239,14 +239,10 @@ Add Availability Zone dimension (only with --type='loadbalancer'). Filter metrics (Can be: 'HealthyHostCount', 'UnHealthyHostCount') (Can be a regexp). -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> Thresholds warning (Can be: 'healthyhostcount', 'unhealthyhostcount'). -=item B<--critical-*> - -Thresholds critical (Can be: 'healthyhostcount', 'unhealthyhostcount'). - =back =cut diff --git a/cloud/aws/elb/classic/plugin.pm b/cloud/aws/elb/classic/plugin.pm new file mode 100644 index 000000000..b068306f7 --- /dev/null +++ b/cloud/aws/elb/classic/plugin.pm @@ -0,0 +1,54 @@ +# +# 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 cloud::aws::elb::classic::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'discovery' => 'cloud::aws::elb::classic::mode::discovery', + 'http-codes' => 'cloud::aws::elb::classic::mode::httpcodes', + 'performances' => 'cloud::aws::elb::classic::mode::performances', + 'queues' => 'cloud::aws::elb::classic::mode::queues', + 'targets-health' => 'cloud::aws::elb::classic::mode::targetshealth', + ); + + $self->{custom_modes}{paws} = 'cloud::aws::custom::paws'; + $self->{custom_modes}{awscli} = 'cloud::aws::custom::awscli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Amazon Classic Elastic Load Balancing (Amazon Classic ELB). + +=cut diff --git a/cloud/aws/elb/network/mode/discovery.pm b/cloud/aws/elb/network/mode/discovery.pm new file mode 100644 index 000000000..75ef93b7d --- /dev/null +++ b/cloud/aws/elb/network/mode/discovery.pm @@ -0,0 +1,111 @@ +# +# 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 cloud::aws::elb::network::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + "prettify" => { name => 'prettify' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $load_balancers = $options{custom}->discovery( + region => $self->{option_results}->{region}, + service => 'elbv2', + command => 'describe-load-balancers' + ); + + foreach my $load_balancer (@{$load_balancers->{LoadBalancers}}) { + next if (!defined($load_balancer->{LoadBalancerArn}) || $load_balancer->{Type} ne 'network'); + my %elb; + $elb{type} = "network"; + $elb{name} = $1 if ($load_balancer->{LoadBalancerArn} =~ /arn:aws:elasticloadbalancing:.*:loadbalancer\/(.*)/); + $elb{dns_name} = $load_balancer->{DNSName}; + $elb{availability_zones} = $load_balancer->{AvailabilityZones}; + $elb{vpc_id} = $load_balancer->{VpcId}; + $elb{security_groups} = $load_balancer->{SecurityGroups}; + $elb{state} = $load_balancer->{State}->{Code}; + push @disco_data, \%elb; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Network ELB discovery. + +=over 8 + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/cloud/aws/elb/network/mode/targetshealth.pm b/cloud/aws/elb/network/mode/targetshealth.pm new file mode 100644 index 000000000..14924f2ce --- /dev/null +++ b/cloud/aws/elb/network/mode/targetshealth.pm @@ -0,0 +1,223 @@ +# +# 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 cloud::aws::elb::network::mode::targetshealth; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my %metrics_mapping = ( + 'HealthyHostCount' => { + 'output' => 'Healthy Hosts', + 'label' => 'healthyhostcount', + 'nlabel' => 'elb.healthyhostcount.count', + }, + 'UnHealthyHostCount' => { + 'output' => 'Unhealthy Hosts', + 'label' => 'unhealthyhostcount', + 'nlabel' => 'elb.unhealthyhostcount.count', + }, +); + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "ELB '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub prefix_statistics_output { + my ($self, %options) = @_; + + return "Statistic '" . $options{instance_value}->{display} . "' Metrics "; +} + +sub long_output { + my ($self, %options) = @_; + + my $availability_zone = ""; + if (defined($options{instance_value}->{availability_zone}) && $options{instance_value}->{availability_zone} ne '') { + $availability_zone = "[$options{instance_value}->{availability_zone}] "; + } + + return "Checking '" . $options{instance_value}->{display} . "' " . $availability_zone; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metrics', type => 3, cb_prefix_output => 'prefix_metric_output', cb_long_output => 'long_output', + message_multiple => 'All elb metrics are ok', indent_long_output => ' ', + group => [ + { name => 'statistics', display_long => 1, cb_prefix_output => 'prefix_statistics_output', + message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } }, + ] + } + ]; + + foreach my $metric (keys %metrics_mapping) { + my $entry = { + label => $metrics_mapping{$metric}->{label}, + nlabel => $metrics_mapping{$metric}->{nlabel}, + set => { + key_values => [ { name => $metric }, { name => 'display' } ], + output_template => $metrics_mapping{$metric}->{output} . ': %.2f', + perfdatas => [ + { value => $metric . '_absolute', template => '%.2f', label_extra_instance => 1 } + ], + } + }; + push @{$self->{maps_counters}->{statistics}}, $entry; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "availability-zone:s" => { name => 'availability_zone' }, + "filter-metric:s" => { name => 'filter_metric' }, + "statistic:s@" => { name => 'statistic' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{name}) || $self->{option_results}->{name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --name option."); + $self->{output}->option_exit(); + } + + foreach my $instance (@{$self->{option_results}->{name}}) { + if ($instance ne '') { + push @{$self->{aws_instance}}, $instance; + } + } + + $self->{aws_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 600; + $self->{aws_period} = defined($self->{option_results}->{period}) ? $self->{option_results}->{period} : 60; + + $self->{aws_statistics} = ['Average']; + if (defined($self->{option_results}->{statistic})) { + $self->{aws_statistics} = []; + foreach my $stat (@{$self->{option_results}->{statistic}}) { + if ($stat ne '') { + push @{$self->{aws_statistics}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric (keys %metrics_mapping) { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{aws_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $instance (@{$self->{aws_instance}}) { + push @{$self->{aws_dimensions}}, { Name => 'LoadBalancer', Value => $instance }; + if (defined($self->{option_results}->{availability_zone}) && $self->{option_results}->{availability_zone} ne '') { + push @{$self->{aws_dimensions}}, { Name => 'AvailabilityZone', Value => $self->{option_results}->{availability_zone} }; + } + $metric_results{$instance} = $options{custom}->cloudwatch_get_metrics( + region => $self->{option_results}->{region}, + namespace => 'AWS/ApplicationELB', + dimensions => $self->{aws_dimensions}, + metrics => $self->{aws_metrics}, + statistics => $self->{aws_statistics}, + timeframe => $self->{aws_timeframe}, + period => $self->{aws_period}, + ); + + foreach my $metric (@{$self->{aws_metrics}}) { + foreach my $statistic (@{$self->{aws_statistics}}) { + next if (!defined($metric_results{$instance}->{$metric}->{lc($statistic)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metrics}->{$instance}->{display} = $instance; + $self->{metrics}->{$instance}->{availability_zone} = $self->{option_results}->{availability_zone}; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{display} = $statistic; + $self->{metrics}->{$instance}->{statistics}->{lc($statistic)}->{$metric} = defined($metric_results{$instance}->{$metric}->{lc($statistic)}) ? $metric_results{$instance}->{$metric}->{lc($statistic)} : 0; + } + } + } + + if (scalar(keys %{$self->{metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Network ELB targets health. + +Example: +perl centreon_plugins.pl --plugin=cloud::aws::elb::network::plugin --custommode=paws --mode=targets-health +--region='eu-west-1' --name='net/NetProd/7c8ecfbd1093c5bd' --critical-unhealthyhostcount='10' --verbose + +See 'https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-cloudwatch-metrics.html' for more informations. + +Default statistic: 'average' / Most usefull statistics: 'average', 'minimum', 'maximum'. + +=over 8 + +=item B<--name> + +Set the instance name (Required) (Can be multiple). + +=item B<--availability-zone> + +Add Availability Zone dimension. + +=item B<--filter-metric> + +Filter metrics (Can be: 'HealthyHostCount', 'UnHealthyHostCount') +(Can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds warning (Can be: 'healthyhostcount', 'unhealthyhostcount'). + +=back + +=cut diff --git a/cloud/aws/elb/plugin.pm b/cloud/aws/elb/network/plugin.pm similarity index 73% rename from cloud/aws/elb/plugin.pm rename to cloud/aws/elb/network/plugin.pm index 9d234ee98..85e0de8aa 100644 --- a/cloud/aws/elb/plugin.pm +++ b/cloud/aws/elb/network/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package cloud::aws::elb::plugin; +package cloud::aws::elb::network::plugin; use strict; use warnings; @@ -31,11 +31,8 @@ sub new { $self->{version} = '0.1'; %{ $self->{modes} } = ( - 'discovery' => 'cloud::aws::elb::mode::discovery', - 'http-codes' => 'cloud::aws::elb::mode::httpcodes', - 'performances' => 'cloud::aws::elb::mode::performances', - 'queues' => 'cloud::aws::elb::mode::queues', - 'targets-health' => 'cloud::aws::elb::mode::targetshealth', + 'discovery' => 'cloud::aws::elb::network::mode::discovery', + 'targets-health' => 'cloud::aws::elb::network::mode::targetshealth', ); $self->{custom_modes}{paws} = 'cloud::aws::custom::paws'; @@ -49,6 +46,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check Amazon Elastic Load Balancing (Amazon ELB). +Check Amazon Network Elastic Load Balancing (Amazon Network ELB). =cut