diff --git a/cloud/google/gcp/compute/computeengine/mode/cpu.pm b/cloud/google/gcp/compute/computeengine/mode/cpu.pm index 82cf6e01f..d90dcdea5 100644 --- a/cloud/google/gcp/compute/computeengine/mode/cpu.pm +++ b/cloud/google/gcp/compute/computeengine/mode/cpu.pm @@ -20,117 +20,52 @@ package cloud::google::gcp::compute::computeengine::mode::cpu; -use base qw(centreon::plugins::templates::counter); +use base qw(cloud::google::gcp::custom::mode); use strict; use warnings; -use cloud::google::gcp::custom::misc; -sub prefix_metric_output { - my ($self, %options) = @_; - - return "Instance '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; -} - -sub custom_metric_calc { - my ($self, %options) = @_; - - $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; - $self->{result_values}->{metric} = $options{extra_options}->{metric}; - $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; - $self->{result_values}->{metric_label} = $options{extra_options}->{metric_label}; - $self->{result_values}->{metric_perf} = $options{extra_options}->{metric_perf}; - $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric} . '_' . $self->{result_values}->{stat}} * 100; - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - return 0; -} - -sub custom_metric_threshold { +sub get_metrics_mapping { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check( - value => $self->{result_values}->{value}, - threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] - ); - return $exit; -} + my $metrics_mapping = { + 'instance/cpu/utilization' => { + 'output_string' => 'Cpu Utilization: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.cpu.utilization.percentage', + 'min' => '0', + 'max' => '100', + 'unit' => '%', + 'format' => '%.2f', + }, + }, + 'threshold' => 'utilization', + 'calc' => '* 100', + }, + 'instance/cpu/reserved_cores' => { + 'output_string' => 'Cpu Reserved Cores: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.cpu.cores.reserved.count', + 'format' => '%.2f', + } + }, + 'threshold' => 'cores-reserved', + }, + }; -sub custom_usage_perfdata { - my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add( - label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => '%', - value => sprintf("%.2f", $self->{result_values}->{value}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - min => 0, max => 100 - ); -} - -sub custom_usage_output { - my ($self, %options) = @_; - - my $msg = sprintf("%s: %.2f%%", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); - return $msg; -} - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', - message_multiple => "All CPU metrics are ok", skipped_code => { -10 => 1 } }, - ]; - - foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { - foreach my $metric ('instance/cpu/utilization') { - my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); - my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); - my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); - my $entry = { label => $metric_label . '-' . $aggregation, set => { - key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], - closure_custom_calc => $self->can('custom_metric_calc'), - closure_custom_calc_extra_options => { metric_perf => $metric_perf, - metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, - closure_custom_output => $self->can('custom_usage_output'), - closure_custom_perfdata => $self->can('custom_usage_perfdata'), - closure_custom_threshold_check => $self->can('custom_metric_threshold'), - } - }; - push @{$self->{maps_counters}->{metric}}, $entry; - } - foreach my $metric ('instance/cpu/reserved_cores') { - my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); - my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); - my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); - my $entry = { label => $metric_label . '-' . $aggregation, set => { - key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], - output_template => $metric_name . ': %.2f', - perfdatas => [ - { label => $metric_perf . '_' . $aggregation, value => $metric . '_' . $aggregation . '_absolute', - template => '%.2f', unit => '', label_extra_instance => 1, instance_use => 'display_absolute', - min => 0 }, - ], - } - }; - push @{$self->{maps_counters}->{metric}}, $entry; - } - } + return $metrics_mapping; } 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 => { - "instance:s@" => { name => 'instance' }, - "filter-metric:s" => { name => 'filter_metric' }, + 'instance:s@' => { name => 'instance' }, + 'filter-metric:s' => { name => 'filter_metric' }, }); return $self; @@ -145,6 +80,8 @@ sub check_options { $self->{output}->option_exit(); } + $self->{gcp_api} = "compute.googleapis.com"; + $self->{gcp_dimension} = 'metric.labels.instance_name'; $self->{gcp_instance} = $self->{option_results}->{instance}; $self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; $self->{gcp_aggregations} = ['average']; @@ -157,45 +94,12 @@ sub check_options { } } - foreach my $metric ('instance/cpu/utilization', 'instance/cpu/reserved_cores') { + foreach my $metric (keys %{$self->{metrics_mapping}}) { next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' && $metric !~ /$self->{option_results}->{filter_metric}/); push @{$self->{gcp_metrics}}, $metric; } - - $self->{gcp_api} = "compute.googleapis.com"; -} - -sub manage_selection { - my ($self, %options) = @_; - - my $metric_results; - foreach my $instance (@{$self->{gcp_instance}}) { - foreach my $metric (@{$self->{gcp_metrics}}) { - ($metric_results, undef) = $options{custom}->gcp_get_metrics( - dimension => 'metric.labels.instance_name', - instance => $instance, - metric => $metric, - api => $self->{gcp_api}, - aggregations => $self->{gcp_aggregations}, - timeframe => $self->{gcp_timeframe}, - ); - - foreach my $aggregation (@{$self->{gcp_aggregations}}) { - next if (!defined($metric_results->{$metric}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); - - $self->{metric}->{$instance . "_" . lc($aggregation)}->{display} = $metric_results->{labels}->{instance_name}; - $self->{metric}->{$instance . "_" . lc($aggregation)}->{stat} = lc($aggregation); - $self->{metric}->{$instance . "_" . lc($aggregation)}->{$metric . "_" . lc($aggregation)} = defined($metric_results->{$metric}->{lc($aggregation)}) ? $metric_results->{$metric}->{lc($aggregation)} : 0; - } - } - } - - if (scalar(keys %{$self->{metric}}) <= 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; @@ -208,9 +112,9 @@ Check Compute Engine instances CPU metrics. Example: -perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin --custommode=api --mode=cpu ---instance=mycomputeinstance --filter-metric='utilization' --aggregation='average' ---critical-cpu-utilization-average='10' --verbose +perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin +--custommode=api --mode=cpu --instance=mycomputeinstance --filter-metric='utilization' +--aggregation='average' --critical-cpu-utilization-average='10' --verbose Default aggregation: 'average' / All aggregations are valid. @@ -225,17 +129,10 @@ Set instance name (Required). Filter metrics (Can be: 'instance/cpu/utilization', 'instance/cpu/reserved_cores') (Can be a regexp). -=item B<--warning-$metric$-$aggregation$> +=item B<--warning-*> B<--critical-*> -Thresholds warning ($metric$ can be: 'cpu-utilization', -'cpu-reserved-cores', $aggregation$ can be: 'minimum', -'maximum', 'average', 'total'). - -=item B<--critical-$metric$-$aggregation$> - -Thresholds critical ($metric$ can be: 'cpu-utilization', -'cpu-reserved-cores', $aggregation$ can be: 'minimum', -'maximum', 'average', 'total'). +Thresholds critical (Can be: 'utilization', +'cores-reserved'). =back diff --git a/cloud/google/gcp/compute/computeengine/mode/diskio.pm b/cloud/google/gcp/compute/computeengine/mode/diskio.pm index 32b1c62b0..65ed55b11 100644 --- a/cloud/google/gcp/compute/computeengine/mode/diskio.pm +++ b/cloud/google/gcp/compute/computeengine/mode/diskio.pm @@ -20,164 +20,129 @@ package cloud::google::gcp::compute::computeengine::mode::diskio; -use base qw(centreon::plugins::templates::counter); +use base qw(cloud::google::gcp::custom::mode); use strict; use warnings; -use cloud::google::gcp::custom::misc; -sub prefix_metric_output { - my ($self, %options) = @_; - - return "Instance '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; -} - -sub custom_metric_calc { - my ($self, %options) = @_; - - $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; - $self->{result_values}->{metric_perf} = $options{extra_options}->{metric_perf}; - $self->{result_values}->{metric_label} = $options{extra_options}->{metric_label}; - $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; - $self->{result_values}->{metric} = $options{extra_options}->{metric}; - $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; - $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric} . '_' . $self->{result_values}->{stat}}; - $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - return 0; -} - -sub custom_usage_threshold { +sub get_metrics_mapping { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check( - value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, - threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] - ); - return $exit; -} + my $metrics_mapping = { + 'instance/disk/read_bytes_count' => { + 'output_string' => 'Read Bytes: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.disk.read.volume.bytes', + 'format' => '%.2f', + 'unit' => 'B', + 'change_bytes' => 1, + }, + 'per_second' => { + 'nlabel' => 'computeengine.disk.read.volume.bytespersecond', + 'format' => '%.2f', + 'unit' => 'B/s', + 'change_bytes' => 1, + }, + }, + 'threshold' => 'read-volume', + }, + 'instance/disk/throttled_read_bytes_count' => { + 'output_string' => 'Throttled Read Bytes: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.disk.throttled.read.volume.bytes', + 'format' => '%.2f', + 'unit' => 'B', + 'change_bytes' => 1, + }, + 'per_second' => { + 'nlabel' => 'computeengine.disk.throttled.read.volume.bytespersecond', + 'format' => '%.2f', + 'unit' => 'B/s', + 'change_bytes' => 1, + }, + }, + 'threshold' => 'throttled-read-volume', + }, + 'instance/disk/write_bytes_count' => { + 'output_string' => 'Write Bytes: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.disk.write.volume.bytes', + 'format' => '%.2f', + 'unit' => 'B', + 'change_bytes' => 1, + }, + 'per_second' => { + 'nlabel' => 'computeengine.disk.write.volume.bytespersecond', + 'format' => '%.2f', + 'unit' => 'B/s', + 'change_bytes' => 1, + }, + }, + 'threshold' => 'write-volume', + }, + 'instance/disk/throttled_write_bytes_count' => { + 'output_string' => 'Throttled Write Bytes: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.disk.throttled.write.volume.bytes', + 'format' => '%.2f', + 'unit' => 'B', + 'change_bytes' => 1, + }, + 'per_second' => { + 'nlabel' => 'computeengine.disk.throttled.write.volume.bytespersecond', + 'format' => '%.2f', + 'unit' => 'B/s', + 'change_bytes' => 1, + }, + }, + 'threshold' => 'throttled-write-volume', + }, + 'instance/disk/read_ops_count' => { + 'output_string' => 'Read OPS: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.disk.read.ops.count', + 'format' => '%.2f', + }, + 'per_second' => { + 'nlabel' => 'computeengine.disk.read.ops.persecond', + 'format' => '%.2f', + }, + }, + 'threshold' => 'read-ops', + }, + 'instance/disk/write_ops_count' => { + 'output_string' => 'Write OPS: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.disk.write.ops.count', + 'format' => '%.2f', + }, + 'per_second' => { + 'nlabel' => 'computeengine.disk.write.ops.persecond', + 'format' => '%.2f', + }, + }, + 'threshold' => 'write-ops', + }, + }; -sub custom_usage_perfdata { - my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add( - label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%d", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - min => 0 - ); -} - -sub custom_usage_output { - my ($self, %options) = @_; - my $msg = ""; - - if (defined($self->{instance_mode}->{option_results}->{per_sec})) { - my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); - $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; - } else { - my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); - $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; - } - return $msg; -} - -sub custom_ops_threshold { - my ($self, %options) = @_; - - my $exit = $self->{perfdata}->threshold_check( - value => $self->{result_values}->{value}, - threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] - ); - return $exit; -} - -sub custom_ops_perfdata { - my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add( - label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => 'ops/s', - value => sprintf("%.2f", $self->{result_values}->{value}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - min => 0 - ); -} - -sub custom_ops_output { - my ($self, %options) = @_; - - my $msg = sprintf("%s: %.2f ops/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); - - return $msg; -} - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All disk metrics are ok", skipped_code => { -10 => 1 } }, - ]; - - foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { - foreach my $metric ('instance/disk/read_bytes_count', 'instance/disk/throttled_read_bytes_count', - 'instance/disk/write_bytes_count', 'instance/disk/throttled_write_bytes_count') { - my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); - my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); - my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); - my $entry = { label => $metric_label . '-' . $aggregation, set => { - key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, - { name => 'stat' }, { name => 'timeframe' } ], - closure_custom_calc => $self->can('custom_metric_calc'), - closure_custom_calc_extra_options => { metric_perf => $metric_perf, - metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, - closure_custom_output => $self->can('custom_usage_output'), - closure_custom_perfdata => $self->can('custom_usage_perfdata'), - closure_custom_threshold_check => $self->can('custom_usage_threshold'), - } - }; - push @{$self->{maps_counters}->{metric}}, $entry; - } - foreach my $metric ('instance/disk/read_ops_count', 'instance/disk/write_ops_count') { - my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); - my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); - my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); - my $entry = { label => $metric_label . '-' . $aggregation, set => { - key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, - { name => 'stat' }, { name => 'timeframe' } ], - closure_custom_calc => $self->can('custom_metric_calc'), - closure_custom_calc_extra_options => { metric_perf => $metric_perf, - metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, - closure_custom_output => $self->can('custom_ops_output'), - closure_custom_perfdata => $self->can('custom_ops_perfdata'), - closure_custom_threshold_check => $self->can('custom_ops_threshold'), - } - }; - push @{$self->{maps_counters}->{metric}}, $entry; - } - } + return $metrics_mapping; } 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 => { - "instance:s@" => { name => 'instance' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, + 'instance:s@' => { name => 'instance' }, + 'filter-metric:s' => { name => 'filter_metric' }, + "per-second" => { name => 'per_second' }, }); return $self; @@ -192,6 +157,8 @@ sub check_options { $self->{output}->option_exit(); } + $self->{gcp_api} = "compute.googleapis.com"; + $self->{gcp_dimension} = 'metric.labels.instance_name'; $self->{gcp_instance} = $self->{option_results}->{instance}; $self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; $self->{gcp_aggregations} = ['average']; @@ -204,48 +171,12 @@ sub check_options { } } - foreach my $metric ('instance/disk/read_bytes_count', 'instance/disk/throttled_read_bytes_count', - 'instance/disk/write_bytes_count', 'instance/disk/throttled_write_bytes_count', - 'instance/disk/read_ops_count', 'instance/disk/write_ops_count') { + foreach my $metric (keys %{$self->{metrics_mapping}}) { next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' && $metric !~ /$self->{option_results}->{filter_metric}/); push @{$self->{gcp_metrics}}, $metric; } - - $self->{gcp_api} = "compute.googleapis.com"; -} - -sub manage_selection { - my ($self, %options) = @_; - - my $metric_results; - foreach my $instance (@{$self->{gcp_instance}}) { - foreach my $metric (@{$self->{gcp_metrics}}) { - ($metric_results, undef) = $options{custom}->gcp_get_metrics( - dimension => 'metric.labels.instance_name', - instance => $instance, - metric => $metric, - api => $self->{gcp_api}, - aggregations => $self->{gcp_aggregations}, - timeframe => $self->{gcp_timeframe}, - ); - - foreach my $aggregation (@{$self->{gcp_aggregations}}) { - next if (!defined($metric_results->{$metric}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); - - $self->{metric}->{$instance . "_" . lc($aggregation)}->{display} = $metric_results->{labels}->{instance_name}; - $self->{metric}->{$instance . "_" . lc($aggregation)}->{timeframe} = $self->{gcp_timeframe}; - $self->{metric}->{$instance . "_" . lc($aggregation)}->{stat} = lc($aggregation); - $self->{metric}->{$instance . "_" . lc($aggregation)}->{$metric . "_" . lc($aggregation)} = defined($metric_results->{$metric}->{lc($aggregation)}) ? $metric_results->{$metric}->{lc($aggregation)} : 0; - } - } - } - - if (scalar(keys %{$self->{metric}}) <= 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; @@ -258,9 +189,9 @@ Check Compute Engine instances disk IO metrics. Example: -perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin --custommode=api --mode=diskio ---instance=mycomputeinstance --filter-metric='throttled' --aggregation='average' ---critical-disk-throttled-write-bytes-count-average='10' --verbose +perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin +--custommode=api --mode=diskio --instance=mycomputeinstance --filter-metric='throttled' +--aggregation='average' --critical-throttled-write-volume='10' --verbose Default aggregation: 'average' / All aggregations are valid. @@ -276,19 +207,12 @@ Filter metrics (Can be: 'instance/disk/read_bytes_count', 'instance/disk/throttl 'instance/disk/write_bytes_count', 'instance/disk/throttled_write_bytes_count', 'instance/disk/read_ops_count', 'instance/disk/write_ops_count') (Can be a regexp). -=item B<--warning-$metric$-$aggregation$> +=item B<--warning-*> B<--critical-*> -Thresholds warning ($metric$ can be: 'disk-read-bytes-count', 'disk-throttled-read-bytes-count', -'disk-write-bytes-count', 'disk-throttled-write-bytes-count','disk-read-ops-count', -'disk-write-ops-count', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). +Thresholds warning (Can be: 'read-volume', 'throttled-read-volume', +'write-volume', 'throttled-write-volume', 'read-ops', 'write-ops'). -=item B<--critical-$metric$-$aggregation$> - -Thresholds critical ($metric$ can be: 'disk-read-bytes-count', 'disk-throttled-read-bytes-count', -'disk-write-bytes-count', 'disk-throttled-write-bytes-count','disk-read-ops-count', -'disk-write-ops-count', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). - -=item B<--per-sec> +=item B<--per-second> Change the data to be unit/sec. diff --git a/cloud/google/gcp/compute/computeengine/mode/network.pm b/cloud/google/gcp/compute/computeengine/mode/network.pm index 3ce0a1e32..82353a5a0 100644 --- a/cloud/google/gcp/compute/computeengine/mode/network.pm +++ b/cloud/google/gcp/compute/computeengine/mode/network.pm @@ -20,157 +20,97 @@ package cloud::google::gcp::compute::computeengine::mode::network; -use base qw(centreon::plugins::templates::counter); +use base qw(cloud::google::gcp::custom::mode); use strict; use warnings; -use cloud::google::gcp::custom::misc; -sub prefix_metric_output { - my ($self, %options) = @_; - - return "Instance '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; -} - -sub custom_metric_calc { - my ($self, %options) = @_; - - $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; - $self->{result_values}->{metric_perf} = $options{extra_options}->{metric_perf}; - $self->{result_values}->{metric_label} = $options{extra_options}->{metric_label}; - $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; - $self->{result_values}->{metric} = $options{extra_options}->{metric}; - $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; - $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric} . '_' . $self->{result_values}->{stat}}; - $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - return 0; -} - -sub custom_metric_threshold { +sub get_metrics_mapping { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check( - value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, - threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] - ); - return $exit; -} + my $metrics_mapping = { + 'instance/network/received_bytes_count' => { + 'output_string' => 'Received Bytes: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.network.received.volume.bytes', + 'format' => '%.2f', + 'unit' => 'B', + 'change_bytes' => 1, + }, + 'per_second' => { + 'nlabel' => 'computeengine.network.received.volume.bytespersecond', + 'format' => '%.2f', + 'unit' => 'B/s', + 'change_bytes' => 1, + }, + }, + 'threshold' => 'received-volume', + }, + 'instance/network/sent_bytes_count' => { + 'output_string' => 'Sent Bytes: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.network.sent.volume.bytes', + 'format' => '%.2f', + 'unit' => 'B', + 'change_bytes' => 1, + }, + 'per_second' => { + 'nlabel' => 'computeengine.network.sent.volume.bytespersecond', + 'format' => '%.2f', + 'unit' => 'B/s', + 'change_bytes' => 1, + }, + }, + 'threshold' => 'sent-volume', + }, + 'instance/network/received_packets_count' => { + 'output_string' => 'Received Packets: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.network.received.packets.count', + 'format' => '%.2f', + 'unit' => 'packets', + }, + 'per_second' => { + 'nlabel' => 'computeengine.network.received.packets.persecond', + 'format' => '%.2f', + 'unit' => 'packets/s', + }, + }, + 'threshold' => 'received-packets', + }, + 'instance/network/sent_packets_count' => { + 'output_string' => 'Sent Packets: %.2f', + 'perfdata' => { + 'absolute' => { + 'nlabel' => 'computeengine.network.sent.packets.count', + 'format' => '%.2f', + 'unit' => 'packets', + }, + 'per_second' => { + 'nlabel' => 'computeengine.network.sent.packets.persecond', + 'format' => '%.2f', + 'unit' => 'packets/s', + }, + }, + 'threshold' => 'sent-packets', + }, + }; -sub custom_traffic_perfdata { - my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add( - label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%d", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - min => 0 - ); -} - -sub custom_traffic_output { - my ($self, %options) = @_; - my $msg = ""; - - if (defined($self->{instance_mode}->{option_results}->{per_sec})) { - my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); - $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; - } else { - my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); - $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; - } - return $msg; -} - -sub custom_packet_perfdata { - my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add( - label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'packet/s' : 'packet', - value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), - min => 0 - ); -} - -sub custom_packet_output { - my ($self, %options) = @_; - my $msg = ""; - - if (defined($self->{instance_mode}->{option_results}->{per_sec})) { - $msg = sprintf("%s: %.2f packets/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value_per_sec}); - } else { - $msg = sprintf("%s: %.2f packets", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); - } - return $msg; -} - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', - message_multiple => "All network metrics are ok", skipped_code => { -10 => 1 } }, - ]; - - foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { - foreach my $metric ('instance/network/received_bytes_count', 'instance/network/sent_bytes_count') { - my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); - my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); - my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); - my $entry = { label => $metric_label . '-' . $aggregation, set => { - key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, - { name => 'stat' }, { name => 'timeframe' } ], - closure_custom_calc => $self->can('custom_metric_calc'), - closure_custom_calc_extra_options => { metric_perf => $metric_perf, - metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, - closure_custom_output => $self->can('custom_traffic_output'), - closure_custom_perfdata => $self->can('custom_traffic_perfdata'), - closure_custom_threshold_check => $self->can('custom_metric_threshold'), - } - }; - push @{$self->{maps_counters}->{metric}}, $entry; - } - foreach my $metric ('instance/network/received_packets_count', 'instance/network/sent_packets_count') { - my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); - my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); - my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); - my $entry = { label => $metric_label . '-' . $aggregation, set => { - key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, - { name => 'stat' }, { name => 'timeframe' } ], - closure_custom_calc => $self->can('custom_metric_calc'), - closure_custom_calc_extra_options => { metric_perf => $metric_perf, - metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, - closure_custom_output => $self->can('custom_packet_output'), - closure_custom_perfdata => $self->can('custom_packet_perfdata'), - closure_custom_threshold_check => $self->can('custom_metric_threshold'), - } - }; - push @{$self->{maps_counters}->{metric}}, $entry; - } - } + return $metrics_mapping; } 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 => { - "instance:s@" => { name => 'instance' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, + 'instance:s@' => { name => 'instance' }, + 'filter-metric:s' => { name => 'filter_metric' }, + "per-second" => { name => 'per_second' }, }); return $self; @@ -185,6 +125,8 @@ sub check_options { $self->{output}->option_exit(); } + $self->{gcp_api} = "compute.googleapis.com"; + $self->{gcp_dimension} = 'metric.labels.instance_name'; $self->{gcp_instance} = $self->{option_results}->{instance}; $self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; $self->{gcp_aggregations} = ['average']; @@ -197,47 +139,12 @@ sub check_options { } } - foreach my $metric ('instance/network/received_bytes_count', 'instance/network/sent_bytes_count', - 'instance/network/received_packets_count', 'instance/network/sent_packets_count') { + foreach my $metric (keys %{$self->{metrics_mapping}}) { next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' && $metric !~ /$self->{option_results}->{filter_metric}/); push @{$self->{gcp_metrics}}, $metric; } - - $self->{gcp_api} = "compute.googleapis.com"; -} - -sub manage_selection { - my ($self, %options) = @_; - - my $metric_results; - foreach my $instance (@{$self->{gcp_instance}}) { - foreach my $metric (@{$self->{gcp_metrics}}) { - ($metric_results, undef) = $options{custom}->gcp_get_metrics( - dimension => 'metric.labels.instance_name', - instance => $instance, - metric => $metric, - api => $self->{gcp_api}, - aggregations => $self->{gcp_aggregations}, - timeframe => $self->{gcp_timeframe}, - ); - - foreach my $aggregation (@{$self->{gcp_aggregations}}) { - next if (!defined($metric_results->{$metric}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); - - $self->{metric}->{$instance . "_" . lc($aggregation)}->{display} = $metric_results->{labels}->{instance_name}; - $self->{metric}->{$instance . "_" . lc($aggregation)}->{timeframe} = $self->{gcp_timeframe}; - $self->{metric}->{$instance . "_" . lc($aggregation)}->{stat} = lc($aggregation); - $self->{metric}->{$instance . "_" . lc($aggregation)}->{$metric . "_" . lc($aggregation)} = defined($metric_results->{$metric}->{lc($aggregation)}) ? $metric_results->{$metric}->{lc($aggregation)} : 0; - } - } - } - - if (scalar(keys %{$self->{metric}}) <= 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; @@ -250,9 +157,9 @@ Check Compute Engine instances network metrics. Example: -perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin --custommode=api --mode=network ---instance=mycomputeinstance --filter-metric='bytes' --aggregation='average' ---critical-network-received-bytes-count-average='10' --verbose +perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin +--custommode=api --mode=network --instance=mycomputeinstance --filter-metric='bytes' +--aggregation='average' --critical-received-volume='10' --verbose Default aggregation: 'average' / All aggregations are valid. @@ -268,19 +175,12 @@ Filter metrics (Can be: 'instance/network/received_bytes_count', 'instance/network/sent_bytes_count', 'instance/network/received_packets_count', 'instance/network/sent_packets_count') (Can be a regexp). -=item B<--warning-$metric$-$aggregation$> +=item B<--warning-*> B<--critical-*> -Thresholds warning ($metric$ can be: 'network-received-bytes-count', 'network-sent-bytes-count', -'network-received-packets-count','network-sent-packets-count', -$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). +Thresholds warning (Can be: 'received-volume', 'sent-volume', +'received-packets', 'sent-packets'). -=item B<--critical-$metric$-$aggregation$> - -Thresholds critical ($metric$ can be: 'network-received-bytes-count', 'network-sent-bytes-count', -'network-received-packets-count','network-sent-packets-count', -$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). - -=item B<--per-sec> +=item B<--per-second> Change the data to be unit/sec. diff --git a/cloud/google/gcp/custom/api.pm b/cloud/google/gcp/custom/api.pm index 673dc1e4a..a5e449ea4 100644 --- a/cloud/google/gcp/custom/api.pm +++ b/cloud/google/gcp/custom/api.pm @@ -46,15 +46,15 @@ sub new { if (!defined($options{noptions})) { $options{options}->add_options(arguments => { - "key-file:s" => { name => 'key_file' }, - "authorization-endpoint:s" => { name => 'authorization_endpoint' }, - "monitoring-endpoint:s" => { name => 'monitoring_endpoint' }, - "scope-endpoint:s" => { name => 'scope_endpoint' }, - "timeframe:s" => { name => 'timeframe' }, - "interval:s" => { name => 'interval' }, - "aggregation:s@" => { name => 'aggregation' }, - "zeroed" => { name => 'zeroed' }, - "timeout:s" => { name => 'timeout' }, + 'key-file:s' => { name => 'key_file' }, + 'authorization-endpoint:s' => { name => 'authorization_endpoint' }, + 'monitoring-endpoint:s' => { name => 'monitoring_endpoint' }, + 'scope-endpoint:s' => { name => 'scope_endpoint' }, + 'timeframe:s' => { name => 'timeframe' }, + 'interval:s' => { name => 'interval' }, + 'aggregation:s@' => { name => 'aggregation' }, + 'zeroed' => { name => 'zeroed' }, + 'timeout:s' => { name => 'timeout' }, }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); @@ -106,11 +106,11 @@ sub check_options { $self->{step} = (defined($self->{option_results}->{step})) ? $self->{option_results}->{step} : undef; $self->{key_file} = (defined($self->{option_results}->{key_file})) ? $self->{option_results}->{key_file} : undef; $self->{authorization_endpoint} = (defined($self->{option_results}->{authorization_endpoint})) ? - $self->{option_results}->{authorization_endpoint} : 'https://www.googleapis.com/oauth2/v4/token'; + $self->{option_results}->{authorization_endpoint} : 'https://www.googleapis.com/oauth2/v4/token'; $self->{monitoring_endpoint} = (defined($self->{option_results}->{monitoring_endpoint})) ? - $self->{option_results}->{monitoring_endpoint} : 'https://monitoring.googleapis.com/v3'; + $self->{option_results}->{monitoring_endpoint} : 'https://monitoring.googleapis.com/v3'; $self->{scope_endpoint} = (defined($self->{option_results}->{scope_endpoint})) ? - $self->{option_results}->{scope_endpoint} : 'https://www.googleapis.com/auth/cloud-platform'; + $self->{option_results}->{scope_endpoint} : 'https://www.googleapis.com/auth/cloud-platform'; if (!defined($self->{key_file}) || $self->{key_file} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --key-file option."); @@ -153,8 +153,10 @@ sub get_access_token { if ($has_cache_file == 0 || !defined($access_token) || (($expires_on - time()) < 10)) { local $/ = undef; if (!open(FILE, "<", $self->{key_file})) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot read file '%s': %s", $self->{key_file}, $!)); + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => sprintf("Cannot read file '%s': %s", $self->{key_file}, $!) + ); $self->{output}->display(); $self->{output}->exit(); } @@ -190,7 +192,10 @@ sub get_access_token { hostname => ''); if (!defined($content) || $content eq '') { - $self->{output}->add_option_msg(short_msg => "Authorization endpoint API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->add_option_msg( + short_msg => "Authorization endpoint API returns empty content [code: '" . $self->{http}->get_code() . + "'] [message: '" . $self->{http}->get_message() . "']" + ); $self->{output}->option_exit(); } @@ -200,12 +205,17 @@ sub get_access_token { }; if ($@) { $self->{output}->output_add(long_msg => $content, debug => 1); - $self->{output}->add_option_msg(short_msg => "Cannot decode json response (add --debug option to display returned content)"); + $self->{output}->add_option_msg( + short_msg => "Cannot decode json response (add --debug option to display returned content)" + ); $self->{output}->option_exit(); } if (defined($decoded->{error})) { $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error_description}, debug => 1); - $self->{output}->add_option_msg(short_msg => "Authorization endpoint API return error code '" . $decoded->{error} . "' (add --debug option for detailed message)"); + $self->{output}->add_option_msg( + short_msg => "Authorization endpoint API return error code '" . $decoded->{error} . + "' (add --debug option for detailed message)" + ); $self->{output}->option_exit(); } @@ -222,8 +232,10 @@ sub get_project_id { local $/ = undef; if (!open(FILE, "<", $self->{key_file})) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot read file '%s': %s", $self->{key_file}, $!)); + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => sprintf("Cannot read file '%s': %s", $self->{key_file}, $!) + ); $self->{output}->display(); $self->{output}->exit(); } @@ -256,7 +268,10 @@ sub request_api { my $content = $self->{http}->request(%options); if (!defined($content) || $content eq '') { - $self->{output}->add_option_msg(short_msg => "Monitoring endpoint API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->add_option_msg( + short_msg => "Monitoring endpoint API returns empty content [code: '" . $self->{http}->get_code() . + "'] [message: '" . $self->{http}->get_message() . "']" + ); $self->{output}->option_exit(); } @@ -266,12 +281,17 @@ sub request_api { }; if ($@) { $self->{output}->output_add(long_msg => $content, debug => 1); - $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->add_option_msg( + short_msg => "Cannot decode response (add --debug option to display returned content)" + ); $self->{output}->option_exit(); } if (defined($decoded->{error})) { $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1); - $self->{output}->add_option_msg(short_msg => "Monitoring endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)"); + $self->{output}->add_option_msg( + short_msg => "Monitoring endpoint API return error code '" . $decoded->{error}->{code} . + "' (add --debug option for detailed message)" + ); $self->{output}->option_exit(); } @@ -284,7 +304,8 @@ sub gcp_get_metrics_set_url { my $uri = URI::Encode->new({encode_reserved => 1}); my $encoded_filter = $uri->encode('metric.type = "' . $options{api} . '/' . $options{metric} . '"'); $encoded_filter .= $uri->encode(' AND ' . $options{dimension} . ' = starts_with(' . $options{instance} . ')'); - $encoded_filter .= ' AND ' . $uri->encode(join(' AND ', @{$options{extra_filters}})) if (defined($options{extra_filters}) && $options{extra_filters} ne ''); + $encoded_filter .= ' AND ' . $uri->encode(join(' AND ', @{$options{extra_filters}})) + if (defined($options{extra_filters}) && $options{extra_filters} ne ''); my $encoded_start_time = $uri->encode($options{start_time}); my $encoded_end_time = $uri->encode($options{end_time}); my $project_id = $self->get_project_id(); diff --git a/cloud/google/gcp/custom/misc.pm b/cloud/google/gcp/custom/misc.pm deleted file mode 100644 index 6b93aaab4..000000000 --- a/cloud/google/gcp/custom/misc.pm +++ /dev/null @@ -1,62 +0,0 @@ -# -# 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::google::gcp::custom::misc; - -use strict; -use warnings; - -sub format_metric_label { - my (%options) = @_; - - my $metric = $options{metric}; - $metric =~ s/$options{remove}// if (defined($options{remove}) && $options{remove} ne ''); - $metric = lc($metric); - $metric =~ s/(\/)|(_)/-/g; - - return $metric; -} - -sub format_metric_perf { - my (%options) = @_; - - my $metric = $options{metric}; - $metric =~ s/$options{remove}// if (defined($options{remove}) && $options{remove} ne ''); - $metric = lc($metric); - $metric =~ s/\//_/g; - - return $metric; -} - -sub format_metric_name { - my (%options) = @_; - - my $metric = $options{metric}; - $metric =~ s/$options{remove}// if (defined($options{remove}) && $options{remove} ne ''); - $metric =~ s/(\/)|(_)/ /g; - $metric =~ s/(\w+)/\u$1/g; - - return $metric; -} - -1; - -__END__ - diff --git a/cloud/google/gcp/custom/mode.pm b/cloud/google/gcp/custom/mode.pm new file mode 100644 index 000000000..aa7991ae3 --- /dev/null +++ b/cloud/google/gcp/custom/mode.pm @@ -0,0 +1,211 @@ +# +# 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::google::gcp::custom::mode; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_aggregations_output { + my ($self, %options) = @_; + + return "Aggregation '" . $options{instance_value}->{display} . "' Metrics "; +} + +sub long_output { + my ($self, %options) = @_; + + return "Checking '" . $options{instance_value}->{display} . "' "; +} + +sub custom_calc { + my ($self, %options) = @_; + + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value}->{absolute} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{metric}}; + $self->{result_values}->{value}->{absolute} = eval $self->{result_values}->{value}->{absolute} . $self->{instance_mode}->{metrics_mapping}->{$options{extra_options}->{metric}}->{calc} + if (defined($self->{instance_mode}->{metrics_mapping}->{$options{extra_options}->{metric}}->{calc})); + $self->{result_values}->{value}->{per_second} = $self->{result_values}->{value}->{absolute} / $self->{result_values}->{timeframe}; + $self->{result_values}->{metric} = $options{extra_options}->{metric}; + return 0; +} + +sub custom_threshold { + my ($self, %options) = @_; + + my $threshold = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{threshold}; + my $value = $self->{result_values}->{value}->{absolute}; + if (defined($self->{instance_mode}->{option_results}->{per_second})) { + $value = $self->{result_values}->{value}->{per_second}; + } + my $exit = $self->{perfdata}->threshold_check( + value => $value, + threshold => [ + { label => 'critical-' . $threshold, exit_litteral => 'critical' }, + { label => 'warning-' . $threshold, exit_litteral => 'warning' } + ] + ); + return $exit; +} + +sub custom_perfdata { + my ($self, %options) = @_; + + my $threshold = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{threshold}; + my $options = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{absolute}; + my $value = sprintf( + $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{absolute}->{format}, + $self->{result_values}->{value}->{absolute} + ); + if (defined($self->{instance_mode}->{option_results}->{per_second})) { + $value = sprintf( + $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{per_second}->{format}, + $self->{result_values}->{value}->{per_second} + ); + $options = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{per_second}; + } + + $self->{output}->perfdata_add( + instances => $self->{instance}, + label => $threshold, + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $threshold), + critical => $self->{perfdata}->get_perfdata_for_output( label => 'critical-' . $threshold), + %{$options} + ); +} + +sub custom_output { + my ($self, %options) = @_; + + my $unit = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{absolute}->{unit}; + my $output = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{output_string}; + + my $value = $self->{result_values}->{value}->{absolute}; + if (defined($self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{absolute}->{change_bytes})) { + ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}->{absolute}); + } + if (defined($self->{instance_mode}->{option_results}->{per_second})) { + $unit = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{per_second}->{unit}; + $value = $self->{result_values}->{value}->{per_second}; + + if (defined($self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{per_second}->{change_bytes})) { + ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}->{per_second}); + $unit .= "/s"; + } + } + + my $msg = sprintf($output, $value); + $msg .= " " . $unit if (defined($unit) && $unit ne ""); + + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{metrics_mapping} = $self->get_metrics_mapping; + + $self->{maps_counters_type} = [ + { + type => 3, + name => 'metrics', + cb_prefix_output => 'prefix_output', + cb_long_output => 'long_output', + message_multiple => 'All metrics are ok', + indent_long_output => ' ', + group => [ + { + type => 1, + name => 'aggregations', + cb_prefix_output => 'prefix_aggregations_output', + display_long => 1, + message_multiple => 'All metrics are ok', + skipped_code => { -10 => 1 } + }, + ] + } + ]; + + foreach my $metric (keys %{$self->{metrics_mapping}}) { + my $entry = { + label => $self->{metrics_mapping}->{$metric}->{threshold}, + set => { + key_values => [ { name => $metric }, { name => 'timeframe' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_calc'), + closure_custom_calc_extra_options => { metric => $metric }, + closure_custom_output => $self->can('custom_output'), + closure_custom_perfdata => $self->can('custom_perfdata'), + closure_custom_threshold_check => $self->can('custom_threshold'), + } + }; + push @{$self->{maps_counters}->{aggregations}}, $entry; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $metric_results; + foreach my $instance (@{$self->{gcp_instance}}) { + foreach my $metric (@{$self->{gcp_metrics}}) { + ($metric_results, undef) = $options{custom}->gcp_get_metrics( + dimension => $self->{gcp_dimension}, + instance => $instance, + metric => $metric, + api => $self->{gcp_api}, + aggregations => $self->{gcp_aggregations}, + timeframe => $self->{gcp_timeframe}, + ); + + foreach my $aggregation (@{$self->{gcp_aggregations}}) { + next if (!defined($metric_results->{$metric}->{lc($aggregation)}) && + defined($self->{option_results}->{zeroed})); + + $self->{metrics}->{$instance}->{display} = $metric_results->{labels}->{instance_name}; + $self->{metrics}->{$instance}->{aggregations}->{lc($aggregation)}->{display} = $aggregation; + $self->{metrics}->{$instance}->{aggregations}->{lc($aggregation)}->{timeframe} = $self->{gcp_timeframe}; + $self->{metrics}->{$instance}->{aggregations}->{lc($aggregation)}->{$metric} = + defined($metric_results->{$metric}->{lc($aggregation)}) ? + $metric_results->{$metric}->{lc($aggregation)} : 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__ + diff --git a/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm b/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm index bf39ff211..ab60c30e1 100644 --- a/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm +++ b/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm @@ -189,9 +189,10 @@ Check GCP metrics. Example: -perl centreon_plugins.pl --plugin=cloud::google::gcp::management::stackdriver::plugin --custommode=api --mode=get-metrics ---api='compute.googleapis.com' --metric='instance/cpu/utilization' --instance=mycomputeinstance --aggregation=average --timeframe=600 --warning-metric= --critical-metric= +perl centreon_plugins.pl --plugin=cloud::google::gcp::management::stackdriver::plugin +--custommode=api --mode=get-metrics --api='compute.googleapis.com' --dimension='metric.labels.instance_name' +--metric='instance/cpu/utilization' --instance=mycomputeinstance --aggregation=average +--timeframe=600 --warning-metric= --critical-metric= =over 8