add gcp plugins (#2538)
This commit is contained in:
parent
920f5f903f
commit
876f910977
|
@ -30,29 +30,31 @@ sub get_metrics_mapping {
|
|||
|
||||
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',
|
||||
output_string => 'cpu utilization: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'computeengine.cpu.utilization.percentage',
|
||||
min => 0,
|
||||
max => 100,
|
||||
unit => '%',
|
||||
format => '%.2f'
|
||||
}
|
||||
},
|
||||
'threshold' => 'cores-reserved',
|
||||
threshold => 'utilization',
|
||||
calc => '* 100',
|
||||
order => 1
|
||||
},
|
||||
'instance/cpu/reserved_cores' => {
|
||||
output_string => 'cpu reserved cores: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'computeengine.cpu.reserved_cores.count',
|
||||
format => '%.2f'
|
||||
}
|
||||
},
|
||||
threshold => 'cores-reserved',
|
||||
order => 2
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
|
@ -64,8 +66,12 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'instance:s@' => { name => 'instance' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'metric.labels.instance_name' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
|
@ -75,31 +81,12 @@ sub check_options {
|
|||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if (!defined($self->{option_results}->{instance})) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --instance <name>.");
|
||||
$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'];
|
||||
if (defined($self->{option_results}->{aggregation})) {
|
||||
$self->{gcp_aggregations} = [];
|
||||
foreach my $stat (@{$self->{option_results}->{aggregation}}) {
|
||||
if ($stat ne '') {
|
||||
push @{$self->{gcp_aggregations}}, $stat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'metric.labels.instance_name' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'metric.labels.instance_name';
|
||||
$self->{gcp_instance_key} = 'metric.labels.instance_name';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -113,26 +100,41 @@ 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'
|
||||
--mode=cpu --dimension-value=mycomputeinstance --filter-metric='utilization'
|
||||
--aggregation='average' --critical-cpu-utilization-average='10' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--instance>
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set instance name (Required).
|
||||
Set dimension name (Default: 'metric.labels.instance_name').
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
Filter metrics (Can be: 'instance/cpu/utilization',
|
||||
'instance/cpu/reserved_cores') (Can be a regexp).
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds critical (Can be: 'utilization',
|
||||
'cores-reserved').
|
||||
Thresholds (Can be: 'utilization', 'cores-reserved').
|
||||
|
||||
=back
|
||||
|
||||
|
|
|
@ -30,105 +30,111 @@ sub get_metrics_mapping {
|
|||
|
||||
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,
|
||||
output_string => 'read: %.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',
|
||||
threshold => 'read-volume',
|
||||
order => 1
|
||||
},
|
||||
'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,
|
||||
output_string => 'throttled read: %.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',
|
||||
threshold => 'throttled-read-volume',
|
||||
order => 2
|
||||
},
|
||||
'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,
|
||||
output_string => 'write: %.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',
|
||||
threshold => 'write-volume',
|
||||
order => 3
|
||||
},
|
||||
'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,
|
||||
output_string => 'throttled write: %.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',
|
||||
threshold => 'throttled-write-volume',
|
||||
order => 4
|
||||
},
|
||||
'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',
|
||||
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',
|
||||
threshold => 'read-ops',
|
||||
order => 5
|
||||
},
|
||||
'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',
|
||||
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',
|
||||
},
|
||||
threshold => 'write-ops',
|
||||
order => 6
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
|
@ -140,9 +146,13 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'instance:s@' => { name => 'instance' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'metric.labels.instance_name' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
|
@ -152,31 +162,12 @@ sub check_options {
|
|||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if (!defined($self->{option_results}->{instance})) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --instance <name>.");
|
||||
$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'];
|
||||
if (defined($self->{option_results}->{aggregation})) {
|
||||
$self->{gcp_aggregations} = [];
|
||||
foreach my $stat (@{$self->{option_results}->{aggregation}}) {
|
||||
if ($stat ne '') {
|
||||
push @{$self->{gcp_aggregations}}, $stat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'metric.labels.instance_name' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'metric.labels.instance_name';
|
||||
$self->{gcp_instance_key} = 'metric.labels.instance_name';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -190,16 +181,24 @@ 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'
|
||||
--mode=diskio --dimension-value=mycomputeinstance --filter-metric='throttled'
|
||||
--aggregation='average' --critical-throttled-write-volume='10' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--instance>
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set instance name (Required).
|
||||
Set dimension name (Default: 'metric.labels.instance_name').
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
|
@ -207,9 +206,17 @@ 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<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds warning (Can be: 'read-volume', 'throttled-read-volume',
|
||||
Thresholds (Can be: 'read-volume', 'throttled-read-volume',
|
||||
'write-volume', 'throttled-write-volume', 'read-ops', 'write-ops').
|
||||
|
||||
=item B<--per-second>
|
||||
|
|
|
@ -30,73 +30,77 @@ sub get_metrics_mapping {
|
|||
|
||||
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,
|
||||
output_string => 'received: %.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',
|
||||
threshold => 'received-volume',
|
||||
order => 1
|
||||
},
|
||||
'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,
|
||||
output_string => 'sent: %.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',
|
||||
threshold => 'sent-volume',
|
||||
order => 2
|
||||
},
|
||||
'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',
|
||||
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',
|
||||
threshold => 'received-packets',
|
||||
order => 3
|
||||
},
|
||||
'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',
|
||||
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',
|
||||
},
|
||||
threshold => 'sent-packets',
|
||||
order => 4
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
|
@ -108,9 +112,13 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
'instance:s@' => { name => 'instance' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'metric.labels.instance_name' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
|
@ -120,31 +128,12 @@ sub check_options {
|
|||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if (!defined($self->{option_results}->{instance})) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --instance <name>.");
|
||||
$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'];
|
||||
if (defined($self->{option_results}->{aggregation})) {
|
||||
$self->{gcp_aggregations} = [];
|
||||
foreach my $stat (@{$self->{option_results}->{aggregation}}) {
|
||||
if ($stat ne '') {
|
||||
push @{$self->{gcp_aggregations}}, $stat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'metric.labels.instance_name' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'metric.labels.instance_name';
|
||||
$self->{gcp_instance_key} = 'metric.labels.instance_name';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -158,16 +147,24 @@ 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'
|
||||
--mode=network --dimension-value=mycomputeinstance --filter-metric='bytes'
|
||||
--aggregation='average' --critical-received-volume='10' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--instance>
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set instance name (Required).
|
||||
Set dimension name (Default: 'metric.labels.instance_name').
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
|
@ -175,9 +172,17 @@ 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<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds warning (Can be: 'received-volume', 'sent-volume',
|
||||
Thresholds (Can be: 'received-volume', 'sent-volume',
|
||||
'received-packets', 'sent-packets').
|
||||
|
||||
=item B<--per-second>
|
||||
|
|
|
@ -30,13 +30,13 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$self->{version} = '0.1';
|
||||
%{ $self->{modes} } = (
|
||||
'cpu' => 'cloud::google::gcp::compute::computeengine::mode::cpu',
|
||||
'diskio' => 'cloud::google::gcp::compute::computeengine::mode::diskio',
|
||||
'network' => 'cloud::google::gcp::compute::computeengine::mode::network',
|
||||
);
|
||||
$self->{modes} = {
|
||||
'cpu' => 'cloud::google::gcp::compute::computeengine::mode::cpu',
|
||||
'diskio' => 'cloud::google::gcp::compute::computeengine::mode::diskio',
|
||||
'network' => 'cloud::google::gcp::compute::computeengine::mode::network'
|
||||
};
|
||||
|
||||
$self->{custom_modes}{api} = 'cloud::google::gcp::custom::api';
|
||||
$self->{custom_modes}->{api} = 'cloud::google::gcp::custom::api';
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ use DateTime;
|
|||
use centreon::plugins::http;
|
||||
use centreon::plugins::statefile;
|
||||
use JSON::XS;
|
||||
use URI::Encode;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
use JSON::WebToken;
|
||||
|
||||
|
@ -46,15 +45,12 @@ 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' },
|
||||
'zeroed' => { name => 'zeroed' },
|
||||
'timeout:s' => { name => 'timeout' }
|
||||
});
|
||||
}
|
||||
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
|
||||
|
@ -77,18 +73,7 @@ sub set_defaults {}
|
|||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
if (defined($self->{option_results}->{aggregation})) {
|
||||
foreach my $aggregation (@{$self->{option_results}->{aggregation}}) {
|
||||
if ($aggregation !~ /average|maximum|minimum|total/i) {
|
||||
$self->{output}->add_option_msg(short_msg => "Aggregation '" . $aggregation . "' is not handled");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10;
|
||||
$self->{timeframe} = (defined($self->{option_results}->{timeframe})) ? $self->{option_results}->{timeframe} : undef;
|
||||
$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';
|
||||
|
@ -121,10 +106,6 @@ sub settings {
|
|||
|
||||
$self->build_options_for_httplib();
|
||||
$self->{http}->add_header(key => 'Accept', value => 'application/json');
|
||||
$self->{http}->add_header(key => 'Content-Type', value => 'application/x-www-form-urlencoded');
|
||||
if (defined($self->{access_token})) {
|
||||
$self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{access_token});
|
||||
}
|
||||
$self->{http}->set_options(%{$self->{option_results}});
|
||||
}
|
||||
|
||||
|
@ -167,14 +148,16 @@ sub get_access_token {
|
|||
exp => $exp,
|
||||
iat => $iat,
|
||||
}, $decoded_key_file->{private_key}, 'RS256');
|
||||
|
||||
my $post_data = 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=' . $jwt;
|
||||
|
||||
$self->settings();
|
||||
|
||||
my $content = $self->{http}->request(method => 'POST', query_form_post => $post_data,
|
||||
full_url => $self->{authorization_endpoint},
|
||||
hostname => '');
|
||||
my $content = $self->{http}->request(
|
||||
method => 'POST',
|
||||
full_url => $self->{authorization_endpoint},
|
||||
hostname => '',
|
||||
post_param => [
|
||||
'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||
'assertion=' . $jwt
|
||||
]
|
||||
);
|
||||
|
||||
if (!defined($content) || $content eq '') {
|
||||
$self->{output}->add_option_msg(
|
||||
|
@ -208,8 +191,9 @@ sub get_access_token {
|
|||
my $datas = { last_timestamp => time(), access_token => $decoded->{access_token}, expires_on => $exp };
|
||||
$options{statefile}->write(data => $datas);
|
||||
}
|
||||
|
||||
return $access_token;
|
||||
|
||||
$self->{access_token} = $access_token;
|
||||
$self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{access_token});
|
||||
}
|
||||
|
||||
sub get_project_id {
|
||||
|
@ -217,12 +201,10 @@ sub get_project_id {
|
|||
|
||||
local $/ = undef;
|
||||
if (!open(FILE, "<", $self->{key_file})) {
|
||||
$self->{output}->output_add(
|
||||
severity => 'UNKNOWN',
|
||||
$self->{output}->add_option_msg(
|
||||
short_msg => sprintf("Cannot read file '%s': %s", $self->{key_file}, $!)
|
||||
);
|
||||
$self->{output}->display();
|
||||
$self->{output}->exit();
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
my $key_file = <FILE>;
|
||||
close FILE;
|
||||
|
@ -242,13 +224,10 @@ sub get_project_id {
|
|||
sub request_api {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
if (!defined($self->{access_token})) {
|
||||
$self->{access_token} = $self->get_access_token(statefile => $self->{cache});
|
||||
}
|
||||
|
||||
$self->settings();
|
||||
|
||||
$self->{output}->output_add(long_msg => "URL: '" . $options{full_url} . "'", debug => 1);
|
||||
if (!defined($self->{access_token})) {
|
||||
$self->get_access_token(statefile => $self->{cache});
|
||||
}
|
||||
|
||||
my $content = $self->{http}->request(%options);
|
||||
|
||||
|
@ -286,69 +265,115 @@ sub request_api {
|
|||
sub gcp_get_metrics_set_url {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
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}}))
|
||||
my $filter_instance = $options{dimension_name};
|
||||
if (defined($options{dimension_operator}) && $options{dimension_operator} eq 'starts') {
|
||||
$filter_instance .= ' = starts_with("' . $options{dimension_value} . '")';
|
||||
} elsif (defined($options{dimension_operator}) && $options{dimension_operator} eq 'regexp') {
|
||||
$filter_instance .= ' = monitoring.regex.full_match("' . $options{dimension_value} . '")';
|
||||
} else {
|
||||
$filter_instance .= ' = "' . $options{dimension_value} . '"';
|
||||
}
|
||||
my $filter = 'metric.type = "' . $options{api} . '/' . $options{metric} . '" AND ' . $filter_instance;
|
||||
$filter .= ' AND ' . 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 $get_param = [
|
||||
'filter=' . $filter,
|
||||
'interval.startTime=' . $options{start_time},
|
||||
'interval.endTime=' . $options{end_time}
|
||||
];
|
||||
my $project_id = $self->get_project_id();
|
||||
my $url = $self->{monitoring_endpoint} . '/projects/' . $project_id . '/timeSeries/';
|
||||
|
||||
my $url = $self->{monitoring_endpoint} . "/projects/" . $project_id . "/timeSeries/?filter=" . $encoded_filter .
|
||||
"&interval.startTime=" . $encoded_start_time . "&interval.endTime=" . $encoded_end_time;
|
||||
return ($url, $get_param);
|
||||
}
|
||||
|
||||
return $url;
|
||||
sub get_instance {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $timeserie = $options{timeserie};
|
||||
foreach (@{$options{instance_key}}) {
|
||||
$timeserie = $timeserie->{$_};
|
||||
}
|
||||
if (ref($timeserie) !~ /ARRAY|HASH/) {
|
||||
return $timeserie;
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub gcp_get_metrics {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $start_time = DateTime->now->subtract(seconds => $options{timeframe})->iso8601() . '.000000Z';
|
||||
my $end_time = DateTime->now->iso8601() . '.000000Z';
|
||||
|
||||
my ($url, $get_param) = $self->gcp_get_metrics_set_url(%options, start_time => $start_time, end_time => $end_time);
|
||||
my $response = $self->request_api(
|
||||
method => 'GET',
|
||||
full_url => $url,
|
||||
hostname => '',
|
||||
get_param => $get_param
|
||||
);
|
||||
|
||||
my %aggregations = map { $_ => 1 } @{$options{aggregations}};
|
||||
my $instance_key = [split /\./, $options{instance_key}];
|
||||
my $results = {};
|
||||
my $start_time = DateTime->now->subtract(seconds => $options{timeframe})->iso8601.'.000000Z';
|
||||
my $end_time = DateTime->now->iso8601.'.000000Z';
|
||||
|
||||
my $full_url = $self->gcp_get_metrics_set_url(%options, start_time => $start_time, end_time => $end_time);
|
||||
my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => '');
|
||||
|
||||
my %aggregations = map {$_ => 1} @{$options{aggregations}};
|
||||
|
||||
foreach my $timeserie (@{$response->{timeSeries}}) {
|
||||
my $instance = $self->get_instance(
|
||||
timeserie => $timeserie,
|
||||
instance_key => $instance_key
|
||||
);
|
||||
next if (!defined($instance));
|
||||
|
||||
my $metric_name = lc($timeserie->{metric}->{type});
|
||||
$metric_name =~ s/$options{api}\///;
|
||||
|
||||
$results->{$metric_name} = { points => 0 };
|
||||
|
||||
if (!defined($results->{$instance})) {
|
||||
$results->{$instance} = {};
|
||||
}
|
||||
|
||||
my $metric_calc = { points => 0 };
|
||||
foreach my $point (@{$timeserie->{points}}) {
|
||||
if (defined($point->{value})) {
|
||||
my $value = $point->{value}->{lc($timeserie->{valueType}) . 'Value'};
|
||||
my $value = $point->{value}->{ lc($timeserie->{valueType}) . 'Value' };
|
||||
if (defined($aggregations{average})) {
|
||||
$results->{$metric_name}->{average} = 0 if (!defined($results->{$metric_name}->{average}));
|
||||
$results->{$metric_name}->{average} += $value;
|
||||
$results->{$metric_name}->{points}++;
|
||||
$metric_calc->{average} = 0 if (!defined($metric_calc->{average}));
|
||||
$metric_calc->{average} += $value;
|
||||
$metric_calc->{points}++;
|
||||
}
|
||||
if (defined($aggregations{minimum})) {
|
||||
$results->{$metric_name}->{minimum} = $value
|
||||
if (!defined($results->{$metric_name}->{minimum}) || $value < $results->{$metric_name}->{minimum});
|
||||
$metric_calc->{minimum} = $value
|
||||
if (!defined($metric_calc->{$metric_name}->{minimum}) || $value < $$metric_calc->{minimum});
|
||||
}
|
||||
if (defined($aggregations{maximum})) {
|
||||
$results->{$metric_name}->{maximum} = $value
|
||||
if (!defined($results->{$metric_name}->{maximum}) || $value > $results->{$metric_name}->{maximum});
|
||||
$metric_calc->{maximum} = $value
|
||||
if (!defined($metric_calc->{maximum}) || $value > $metric_calc->{maximum});
|
||||
}
|
||||
if (defined($aggregations{total})) {
|
||||
$results->{$metric_name}->{total} = 0 if (!defined($results->{$metric_name}->{total}));
|
||||
$results->{$metric_name}->{total} += $value;
|
||||
$results->{$metric_name}->{points}++;
|
||||
$metric_calc->{total} = 0 if (!defined($metric_calc->{total}));
|
||||
$metric_calc->{total} += $value;
|
||||
$metric_calc->{points}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defined($results->{$metric_name}->{average})) {
|
||||
$results->{$metric_name}->{average} /= $results->{$metric_name}->{points};
|
||||
|
||||
if (defined($metric_calc->{average})) {
|
||||
$metric_calc->{average} /= $metric_calc->{points};
|
||||
}
|
||||
$results->{resource} = $timeserie->{resource};
|
||||
$results->{labels} = $timeserie->{metric}->{labels};
|
||||
$results->{$instance}->{$metric_name} = $metric_calc;
|
||||
$results->{$instance}->{resource} = $timeserie->{resource};
|
||||
$results->{$instance}->{labels} = $timeserie->{metric}->{labels};
|
||||
}
|
||||
|
||||
return $results, $response;
|
||||
|
||||
if (defined($self->{option_results}->{zeroed}) && (!defined($options{dimension_operator}) || $options{dimension_operator} eq '' || $options{dimension_operator} eq 'equals')) {
|
||||
if ($options{dimension_name} eq $options{dimension_zeroed} && !defined($results->{ $options{dimension_value} })) {
|
||||
$results->{ $options{dimension_value} } = {
|
||||
$options{metric} => { average => 0, minimum => 0, maximum => 0, total => 0 }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -385,14 +410,6 @@ Set GCP monitoring endpoint URL (Default: 'https://monitoring.googleapis.com/v3'
|
|||
|
||||
Set GCP scope endpoint URL (Default: 'https://www.googleapis.com/auth/monitoring.read')
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--zeroed>
|
||||
|
||||
Set metrics value to 0 if none. Usefull when Stackdriver
|
||||
|
|
|
@ -34,7 +34,7 @@ sub prefix_output {
|
|||
sub prefix_aggregations_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
return "Aggregation '" . $options{instance_value}->{display} . "' Metrics ";
|
||||
return "aggregation '" . $options{instance_value}->{display} . "' metrics ";
|
||||
}
|
||||
|
||||
sub long_output {
|
||||
|
@ -46,8 +46,8 @@ sub long_output {
|
|||
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}->{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};
|
||||
|
@ -58,7 +58,7 @@ sub custom_calc {
|
|||
sub custom_threshold {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $threshold = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{threshold};
|
||||
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};
|
||||
|
@ -76,23 +76,23 @@ sub custom_threshold {
|
|||
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 $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->{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})) {
|
||||
if (defined($self->{instance_mode}->{option_results}->{per_second}) &&
|
||||
defined($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{perfdata}->{per_second})) {
|
||||
$value = sprintf(
|
||||
$self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{per_second}->{format},
|
||||
$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};
|
||||
$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),
|
||||
|
@ -110,7 +110,8 @@ sub custom_output {
|
|||
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})) {
|
||||
if (defined($self->{instance_mode}->{option_results}->{per_second}) &&
|
||||
defined($self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{per_second})) {
|
||||
$unit = $self->{instance_mode}->{metrics_mapping}->{$self->{result_values}->{metric}}->{perfdata}->{per_second}->{unit};
|
||||
$value = $self->{result_values}->{value}->{per_second};
|
||||
|
||||
|
@ -129,7 +130,7 @@ sub custom_output {
|
|||
sub set_counters {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
$self->{metrics_mapping} = $self->get_metrics_mapping;
|
||||
$self->{metrics_mapping} = $self->get_metrics_mapping();
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{
|
||||
|
@ -145,14 +146,14 @@ sub set_counters {
|
|||
name => 'aggregations',
|
||||
cb_prefix_output => 'prefix_aggregations_output',
|
||||
display_long => 1,
|
||||
message_multiple => 'All metrics are ok',
|
||||
message_multiple => 'all metrics are ok',
|
||||
skipped_code => { -10 => 1 }
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
foreach my $metric (keys %{$self->{metrics_mapping}}) {
|
||||
foreach my $metric (sort { $self->{metrics_mapping}->{$a}->{order} <=> $self->{metrics_mapping}->{$b}->{order} } keys %{$self->{metrics_mapping}}) {
|
||||
my $entry = {
|
||||
label => $self->{metrics_mapping}->{$metric}->{threshold},
|
||||
set => {
|
||||
|
@ -161,38 +162,81 @@ sub set_counters {
|
|||
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'),
|
||||
closure_custom_threshold_check => $self->can('custom_threshold')
|
||||
}
|
||||
};
|
||||
push @{$self->{maps_counters}->{aggregations}}, $entry;
|
||||
}
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if (!defined($self->{option_results}->{dimension_value})) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --dimension-value <value>.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
$self->{gcp_timeframe} = (defined($self->{option_results}->{timeframe})) ? $self->{option_results}->{timeframe} : 900;
|
||||
|
||||
my $aggregations = [];
|
||||
if (defined($self->{option_results}->{aggregation})) {
|
||||
foreach my $aggregation (@{$self->{option_results}->{aggregation}}) {
|
||||
if ($aggregation !~ /average|maximum|minimum|total/i) {
|
||||
$self->{output}->add_option_msg(short_msg => "Aggregation '" . $aggregation . "' is not handled");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
push @$aggregations, $aggregation;
|
||||
}
|
||||
}
|
||||
$self->{gcp_aggregations} = ['average'];
|
||||
if (scalar(@$aggregations) > 0) {
|
||||
$self->{gcp_aggregations} = $aggregations;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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} = {};
|
||||
foreach my $metric (@{$self->{gcp_metrics}}) {
|
||||
my ($metric_results) = $options{custom}->gcp_get_metrics(
|
||||
dimension_name => $self->{gcp_dimension_name},
|
||||
dimension_operator => $self->{gcp_dimension_operator},
|
||||
dimension_value => $self->{gcp_dimension_value},
|
||||
instance_key => $self->{gcp_instance_key},
|
||||
metric => $metric,
|
||||
api => $self->{gcp_api},
|
||||
aggregations => $self->{gcp_aggregations},
|
||||
timeframe => $self->{gcp_timeframe},
|
||||
dimension_zeroed => $self->{gcp_dimension_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;
|
||||
foreach my $instance_name (keys %$metric_results) {
|
||||
foreach my $aggregation (@{$self->{gcp_aggregations}}) {
|
||||
if (!defined($self->{metrics}->{$instance_name})) {
|
||||
$self->{metrics}->{$instance_name} = {
|
||||
display => $instance_name,
|
||||
aggregations => {}
|
||||
};
|
||||
}
|
||||
if (!defined($self->{metrics}->{$instance_name}->{aggregations}->{lc($aggregation)})) {
|
||||
$self->{metrics}->{$instance_name}->{aggregations}->{lc($aggregation)} = {
|
||||
display => $aggregation,
|
||||
timeframe => $self->{gcp_timeframe}
|
||||
};
|
||||
}
|
||||
$self->{metrics}->{$instance_name}->{aggregations}->{lc($aggregation)}->{$metric} =
|
||||
defined($metric_results->{$instance_name}->{$metric}->{lc($aggregation)}) ? $metric_results->{$instance_name}->{$metric}->{lc($aggregation)} : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
#
|
||||
# Copyright 2020 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::database::common::mode::cpu;
|
||||
|
||||
use base qw(cloud::google::gcp::custom::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub get_metrics_mapping {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $metrics_mapping = {
|
||||
'database/cpu/utilization' => {
|
||||
output_string => 'cpu utilization: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.cpu.utilization.percentage',
|
||||
min => 0,
|
||||
max => 100,
|
||||
unit => '%',
|
||||
format => '%.2f'
|
||||
}
|
||||
},
|
||||
threshold => 'utilization',
|
||||
calc => '* 100',
|
||||
order => 1
|
||||
},
|
||||
'database/cpu/reserved_cores' => {
|
||||
output_string => 'cpu reserved cores: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.cpu.reserved_cores.count',
|
||||
format => '%.2f'
|
||||
}
|
||||
},
|
||||
threshold => 'cores-reserved',
|
||||
order => 2
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
}
|
||||
|
||||
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 => {
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'resource.labels.database_id' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->{gcp_api} = 'cloudsql.googleapis.com';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'resource.labels.database_id' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'resource.labels.database_id';
|
||||
$self->{gcp_instance_key} = 'resource.labels.database_id';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check database CPU metrics.
|
||||
|
||||
Example:
|
||||
|
||||
perl centreon_plugins.pl --plugin=cloud::google::gcp::database::mysql::plugin
|
||||
--mode=cpu --dimension-value=mydatabaseid --filter-metric='utilization'
|
||||
--aggregation='average' --critical-cpu-utilization-average='10' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set dimension name (Default: 'resource.labels.database_id'). Can be: 'resources.labels.region'.
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
Filter metrics (Can be: 'database/cpu/utilization',
|
||||
'database/cpu/reserved_cores') (Can be a regexp).
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds (Can be: 'utilization', 'cores-reserved').
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -0,0 +1,175 @@
|
|||
#
|
||||
# Copyright 2020 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::database::common::mode::network;
|
||||
|
||||
use base qw(cloud::google::gcp::custom::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub get_metrics_mapping {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $metrics_mapping = {
|
||||
'database/network/connections' => {
|
||||
output_string => 'connections: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.network.connections.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'connections',
|
||||
order => 1
|
||||
},
|
||||
'database/network/received_bytes_count' => {
|
||||
output_string => 'received: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.network.received.volume.bytes',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B',
|
||||
change_bytes => 1
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.network.received.volume.bytespersecond',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B/s',
|
||||
change_bytes => 1
|
||||
}
|
||||
},
|
||||
threshold => 'received-volume',
|
||||
order => 2
|
||||
},
|
||||
'database/network/sent_bytes_count' => {
|
||||
output_string => 'sent: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.network.sent.volume.bytes',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B',
|
||||
change_bytes => 1
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.network.sent.volume.bytespersecond',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B/s',
|
||||
change_bytes => 1
|
||||
}
|
||||
},
|
||||
threshold => 'sent-volume',
|
||||
order => 3
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
}
|
||||
|
||||
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 => {
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'resource.labels.database_id' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->{gcp_api} = 'cloudsql.googleapis.com';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'resource.labels.database_id' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'resource.labels.database_id';
|
||||
$self->{gcp_instance_key} = 'resource.labels.database_id';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check database instances network metrics.
|
||||
|
||||
Example:
|
||||
|
||||
perl centreon_plugins.pl --plugin=cloud::google::gcp::database::mysql::plugin
|
||||
--mode=network --dimension-value=mydatabaseid --filter-metric='bytes'
|
||||
--aggregation='average' --critical-received-volume='10' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set dimension name (Default: 'resource.labels.database_id'). Can be: 'resources.labels.region'.
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
Filter metrics (Can be: 'database/network/received_bytes_count',
|
||||
'database/network/sent_bytes_count', 'database/network/connections') (Can be a regexp).
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds (Can be: 'received-volume', 'sent-volume',
|
||||
'connections').
|
||||
|
||||
=item B<--per-second>
|
||||
|
||||
Change the data to be unit/sec.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -0,0 +1,163 @@
|
|||
#
|
||||
# Copyright 2020 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::database::common::mode::storage;
|
||||
|
||||
use base qw(cloud::google::gcp::custom::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub get_metrics_mapping {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $metrics_mapping = {
|
||||
'database/disk/bytes_used' => {
|
||||
output_string => 'disk space usage: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.space.usage.bytes',
|
||||
format => '%d',
|
||||
unit => 'B',
|
||||
change_bytes => 1
|
||||
}
|
||||
},
|
||||
threshold => 'space-usage',
|
||||
order => 1
|
||||
},
|
||||
'database/disk/read_ops_count' => {
|
||||
output_string => 'disk read IO operations: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.disk.read.io.operations.count',
|
||||
format => '%.2f'
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.disk.read.io.operations.persecond',
|
||||
format => '%.2f'
|
||||
}
|
||||
},
|
||||
threshold => 'read-operations',
|
||||
order => 2
|
||||
},
|
||||
'database/disk/write_ops_count' => {
|
||||
output_string => 'disk write IO operations: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.disk.write.io.operations.count',
|
||||
format => '%.2f'
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.disk.write.io.operations.persecond',
|
||||
format => '%.2f'
|
||||
}
|
||||
},
|
||||
threshold => 'write-operations',
|
||||
order => 3
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
}
|
||||
|
||||
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 => {
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'resource.labels.database_id' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->{gcp_api} = 'cloudsql.googleapis.com';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'resource.labels.database_id' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'resource.labels.database_id';
|
||||
$self->{gcp_instance_key} = 'resource.labels.database_id';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check database storage metrics.
|
||||
|
||||
Example:
|
||||
|
||||
perl centreon_plugins.pl --plugin=cloud::google::gcp::database::mysql::plugin
|
||||
--mode=diskio --dimension-value=mydatabaseid --filter-metric='space'
|
||||
--aggregation='average' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set dimension name (Default: 'resource.labels.database_id'). Can be: 'resources.labels.region'.
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
Filter metrics (Can be: 'database/disk/bytes_used',
|
||||
'database/disk/read_ops_count', 'databse/disk/write_ops_count') (Can be a regexp).
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds (Can be: 'space-usage', 'read-operations', 'write-operations').
|
||||
|
||||
=item B<--per-second>
|
||||
|
||||
Change the data to be unit/sec.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -0,0 +1,189 @@
|
|||
#
|
||||
# Copyright 2020 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::database::mysql::mode::innodb;
|
||||
|
||||
use base qw(cloud::google::gcp::custom::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub get_metrics_mapping {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $metrics_mapping = {
|
||||
'database/mysql/innodb_data_fsyncs' => {
|
||||
output_string => 'fsync calls: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.mysql.innodb.data_fsyncs.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.mysql.innodb.data_fsyncs.persecond',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'fsyncs-calls',
|
||||
order => 1
|
||||
},
|
||||
'database/mysql/innodb_os_log_fsyncs' => {
|
||||
output_string => 'fsync calls to the log file: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.mysql.innodb.os_log_fsyncs.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.mysql.innodb.os_log_fsyncs.persecond',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'fsync-calls-logfile',
|
||||
order => 2
|
||||
},
|
||||
'database/mysql/innodb_pages_read' => {
|
||||
output_string => 'pages read: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.mysql.innodb.pages_read.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.mysql.innodb.pages_read.persecond',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'pages-read',
|
||||
order => 3
|
||||
},
|
||||
'database/mysql/innodb_pages_written' => {
|
||||
output_string => 'pages written: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.mysql.innodb.pages_written.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.mysql.innodb.pages_written.persecond',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'pages-written',
|
||||
order => 4
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
}
|
||||
|
||||
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 => {
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'resource.labels.database_id' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->{gcp_api} = 'cloudsql.googleapis.com';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'resource.labels.database_id' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'resource.labels.database_id';
|
||||
$self->{gcp_instance_key} = 'resource.labels.database_id';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check mysql innodb metrics.
|
||||
|
||||
Example:
|
||||
|
||||
perl centreon_plugins.pl --plugin=cloud::google::gcp::database::mysql::plugin
|
||||
--mode=diskio --dimension-value=mydatabaseid --filter-metric='queries'
|
||||
--aggregation='average' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set dimension name (Default: 'resource.labels.database_id'). Can be: 'resources.labels.region'.
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
Filter metrics (Can be: 'database/mysql/innodb_data_fsyncs', 'database/mysql/innodb_os_log_fsyncs',
|
||||
'database/mysql/innodb_pages_read', 'database/mysql/innodb_pages_write') (Can be a regexp).
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds (Can be: 'fsyncs-calls', 'fsync-calls-logfile',
|
||||
'pages-read', 'pages-written').
|
||||
|
||||
=item B<--per-second>
|
||||
|
||||
Change the data to be unit/sec.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -0,0 +1,153 @@
|
|||
#
|
||||
# Copyright 2020 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::database::mysql::mode::queries;
|
||||
|
||||
use base qw(cloud::google::gcp::custom::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub get_metrics_mapping {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $metrics_mapping = {
|
||||
'database/mysql/questions' => {
|
||||
output_string => 'questions: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.mysql.questions.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.mysql.questions.persecond',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'questions',
|
||||
order => 1
|
||||
},
|
||||
'database/mysql/queries' => {
|
||||
output_string => 'queries: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'database.mysql.queries.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'database.mysql.queries.persecond',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'queries',
|
||||
order => 2
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
}
|
||||
|
||||
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 => {
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'resource.labels.database_id' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->{gcp_api} = 'cloudsql.googleapis.com';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'resource.labels.database_id' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'resource.labels.database_id';
|
||||
$self->{gcp_instance_key} = 'resource.labels.database_id';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check mysql queries metrics.
|
||||
|
||||
Example:
|
||||
|
||||
perl centreon_plugins.pl --plugin=cloud::google::gcp::database::mysql::plugin
|
||||
--mode=diskio --dimension-value=mydatabaseid --filter-metric='queries'
|
||||
--aggregation='average' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set dimension name (Default: 'resource.labels.database_id'). Can be: 'resources.labels.region'.
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
Filter metrics (Can be: 'database/mysql/questions', 'database/mysql/queries') (Can be a regexp).
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds (Can be: 'queries', 'questions').
|
||||
|
||||
=item B<--per-second>
|
||||
|
||||
Change the data to be unit/sec.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -0,0 +1,53 @@
|
|||
#
|
||||
# Copyright 2020 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::database::mysql::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} = {
|
||||
'cpu' => 'cloud::google::gcp::database::common::mode::cpu',
|
||||
'innodb' => 'cloud::google::gcp::database::mysql::mode::innodb',
|
||||
'network' => 'cloud::google::gcp::database::common::mode::network',
|
||||
'queries' => 'cloud::google::gcp::database::mysql::mode::queries',
|
||||
'storage' => 'cloud::google::gcp::database::common::mode::storage'
|
||||
};
|
||||
|
||||
$self->{custom_modes}->{api} = 'cloud::google::gcp::custom::api';
|
||||
return $self;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 PLUGIN DESCRIPTION
|
||||
|
||||
Check Google Cloud Platform MySQL.
|
||||
|
||||
=cut
|
|
@ -24,7 +24,6 @@ use base qw(centreon::plugins::templates::counter);
|
|||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Dumper;
|
||||
|
||||
sub custom_metric_perfdata {
|
||||
my ($self, %options) = @_;
|
||||
|
@ -33,7 +32,7 @@ sub custom_metric_perfdata {
|
|||
label => $self->{result_values}->{perf_label},
|
||||
value => $self->{result_values}->{value},
|
||||
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-metric'),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-metric'),
|
||||
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-metric')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -42,16 +41,18 @@ sub custom_metric_threshold {
|
|||
|
||||
my $exit = $self->{perfdata}->threshold_check(
|
||||
value => $self->{result_values}->{value},
|
||||
threshold => [ { label => 'critical-metric', exit_litteral => 'critical' },
|
||||
{ label => 'warning-metric', exit_litteral => 'warning' } ]);
|
||||
threshold => [
|
||||
{ label => 'critical-metric', exit_litteral => 'critical' },
|
||||
{ label => 'warning-metric', exit_litteral => 'warning' }
|
||||
]
|
||||
);
|
||||
return $exit;
|
||||
}
|
||||
|
||||
sub custom_metric_output {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $msg = "Metric '" . $self->{result_values}->{label} . "' of resource '" . $self->{result_values}->{display} . "' value is " . $self->{result_values}->{value};
|
||||
return $msg;
|
||||
return "Metric '" . $self->{result_values}->{label} . "' of resource '" . $self->{result_values}->{display} . "' value is " . $self->{result_values}->{value};
|
||||
}
|
||||
|
||||
sub custom_metric_calc {
|
||||
|
@ -69,17 +70,19 @@ sub set_counters {
|
|||
my ($self, %options) = @_;
|
||||
|
||||
$self->{maps_counters_type} = [
|
||||
{ name => 'metrics', type => 0 },
|
||||
{ name => 'metrics', type => 1 }
|
||||
];
|
||||
|
||||
$self->{maps_counters}->{metrics} = [
|
||||
{ label => 'metric', set => {
|
||||
key_values => [ { name => 'value' }, { name => 'label' }, { name => 'aggregation' },
|
||||
{ name => 'perf_label' }, { name => 'display' } ],
|
||||
key_values => [
|
||||
{ name => 'label' }, { name => 'value' }, { name => 'aggregation' },
|
||||
{ name => 'perf_label' }, { name => 'display' }
|
||||
],
|
||||
closure_custom_calc => $self->can('custom_metric_calc'),
|
||||
closure_custom_output => $self->can('custom_metric_output'),
|
||||
closure_custom_perfdata => $self->can('custom_metric_perfdata'),
|
||||
closure_custom_threshold_check => $self->can('custom_metric_threshold'),
|
||||
closure_custom_threshold_check => $self->can('custom_metric_threshold')
|
||||
}
|
||||
}
|
||||
];
|
||||
|
@ -89,15 +92,18 @@ sub new {
|
|||
my ($class, %options) = @_;
|
||||
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
|
||||
bless $self, $class;
|
||||
|
||||
|
||||
$options{options}->add_options(arguments => {
|
||||
"dimension:s" => { name => 'dimension' },
|
||||
"instance:s" => { name => 'instance' },
|
||||
"metric:s" => { name => 'metric' },
|
||||
"api:s" => { name => 'api' },
|
||||
"extra-filter:s@" => { name => 'extra_filter' },
|
||||
'dimension-name:s' => { name => 'dimension_name' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'instance-key:s' => { name => 'instance_key' },
|
||||
'metric:s' => { name => 'metric' },
|
||||
'api:s' => { name => 'api' },
|
||||
'extra-filter:s@' => { name => 'extra_filter' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
@ -105,12 +111,12 @@ sub check_options {
|
|||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
if (!defined($self->{option_results}->{dimension})) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --dimension <name>.");
|
||||
if (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --dimension-name <name>.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
if (!defined($self->{option_results}->{instance})) {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --instance <name>.");
|
||||
if (!defined($self->{option_results}->{dimension_value}) || $self->{option_results}->{dimension_value} eq '') {
|
||||
$self->{output}->add_option_msg(short_msg => "Need to specify --dimension-value <value>.");
|
||||
$self->{output}->option_exit();
|
||||
}
|
||||
if (!defined($self->{option_results}->{metric})) {
|
||||
|
@ -122,8 +128,11 @@ sub check_options {
|
|||
$self->{output}->option_exit();
|
||||
}
|
||||
|
||||
$self->{gcp_dimension} = $self->{option_results}->{dimension};
|
||||
$self->{gcp_instance} = $self->{option_results}->{instance};
|
||||
$self->{gcp_dimension_name} = $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
$self->{gcp_instance_key} = defined($self->{option_results}->{instance_key}) && $self->{option_results}->{instance_key} ne '' ?
|
||||
$self->{option_results}->{instance_key} : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_metric} = $self->{option_results}->{metric};
|
||||
$self->{gcp_api} = $self->{option_results}->{api};
|
||||
$self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 600;
|
||||
|
@ -136,47 +145,52 @@ sub check_options {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->{gcp_aggregation} = ['average'];
|
||||
|
||||
my $aggregations = [];
|
||||
if (defined($self->{option_results}->{aggregation})) {
|
||||
$self->{gcp_aggregation} = [];
|
||||
foreach my $aggregation (@{$self->{option_results}->{aggregation}}) {
|
||||
if ($aggregation ne '') {
|
||||
push @{$self->{gcp_aggregation}}, lc($aggregation);
|
||||
push @$aggregations, lc($aggregation);
|
||||
}
|
||||
}
|
||||
}
|
||||
$self->{gcp_aggregations} = ['average'];
|
||||
if (scalar(@$aggregations) > 0) {
|
||||
$self->{gcp_aggregations} = @$aggregations;
|
||||
}
|
||||
}
|
||||
|
||||
sub manage_selection {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $results = $options{custom}->gcp_get_metrics(
|
||||
dimension_name => $self->{gcp_dimension_name},
|
||||
dimension_operator => $self->{gcp_dimension_operator},
|
||||
dimension_value => $self->{gcp_dimension_value},
|
||||
instance_key => $self->{gcp_instance_key},
|
||||
metric => $self->{gcp_metric},
|
||||
api => $self->{gcp_api},
|
||||
extra_filters => $self->{gcp_extra_filters},
|
||||
aggregations => $self->{gcp_aggregations},
|
||||
timeframe => $self->{gcp_timeframe}
|
||||
);
|
||||
|
||||
$self->{metrics} = {};
|
||||
|
||||
my ($results, $raw_results) = $options{custom}->gcp_get_metrics(
|
||||
dimension => $self->{gcp_dimension},
|
||||
instance => $self->{gcp_instance},
|
||||
metric => $self->{gcp_metric},
|
||||
api => $self->{gcp_api},
|
||||
extra_filters => $self->{gcp_extra_filters},
|
||||
aggregations => $self->{gcp_aggregation},
|
||||
timeframe => $self->{gcp_timeframe},
|
||||
);
|
||||
|
||||
foreach my $label (keys %{$results}) {
|
||||
foreach my $aggregation (('minimum', 'maximum', 'average', 'total')) {
|
||||
next if (!defined($results->{$label}->{$aggregation}));
|
||||
$self->{metrics} = {
|
||||
display => $self->{gcp_instance},
|
||||
label => $label,
|
||||
aggregation => $aggregation,
|
||||
value => $results->{$label}->{$aggregation},
|
||||
perf_label => $label . '_' . $aggregation,
|
||||
};
|
||||
foreach my $instance_name (keys %$results) {
|
||||
foreach my $label (keys %{$results->{$instance_name}}) {
|
||||
foreach my $aggregation (@{$self->{gcp_aggregations}}) {
|
||||
next if (!defined($results->{$instance_name}->{$label}->{$aggregation}));
|
||||
|
||||
$self->{metrics}->{ $label . '_' . $aggregation } = {
|
||||
display => $instance_name,
|
||||
label => $label,
|
||||
aggregation => $aggregation,
|
||||
value => $results->{$instance_name}->{$label}->{$aggregation},
|
||||
perf_label => $label . '_' . $aggregation
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->{output}->output_add(long_msg => sprintf("Raw data:\n%s", Dumper($raw_results)), debug => 1);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -190,8 +204,8 @@ Check GCP metrics.
|
|||
Example:
|
||||
|
||||
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
|
||||
--custommode=api --mode=get-metrics --api='compute.googleapis.com' --metric='instance/cpu/utilization'
|
||||
--dimension-name='metric.labels.instance_name' --dimension-operator=equals --dimension-value=mycomputeinstance --aggregation=average
|
||||
--timeframe=600 --warning-metric= --critical-metric=
|
||||
|
||||
=over 8
|
||||
|
@ -204,13 +218,21 @@ Set GCP API (Required).
|
|||
|
||||
Set stackdriver metric (Required).
|
||||
|
||||
=item B<--dimension>
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set dimension primary filter (Required).
|
||||
Set dimension name (Required).
|
||||
|
||||
=item B<--instance>
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set instance name (Required).
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--instance-key>
|
||||
|
||||
Set instance key (By default, --dimension-name option is used).
|
||||
|
||||
=item B<--warning-metric>
|
||||
|
||||
|
|
|
@ -30,11 +30,11 @@ sub new {
|
|||
bless $self, $class;
|
||||
|
||||
$self->{version} = '1.0';
|
||||
%{$self->{modes}} = (
|
||||
'get-metrics' => 'cloud::google::gcp::management::stackdriver::mode::getmetrics',
|
||||
);
|
||||
$self->{modes} = {
|
||||
'get-metrics' => 'cloud::google::gcp::management::stackdriver::mode::getmetrics'
|
||||
};
|
||||
|
||||
$self->{custom_modes}{api} = 'cloud::google::gcp::custom::api';
|
||||
$self->{custom_modes}->{api} = 'cloud::google::gcp::custom::api';
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
#
|
||||
# Copyright 2020 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::storage::mode::bucket;
|
||||
|
||||
use base qw(cloud::google::gcp::custom::mode);
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub get_metrics_mapping {
|
||||
my ($self, %options) = @_;
|
||||
|
||||
my $metrics_mapping = {
|
||||
'storage/object_count' => {
|
||||
output_string => 'objects: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'storage.bucket.objects.count',
|
||||
format => '%.2f',
|
||||
min => 0
|
||||
}
|
||||
},
|
||||
threshold => 'bucket-objects',
|
||||
order => 1
|
||||
},
|
||||
'network/received_bytes_count' => {
|
||||
output_string => 'received: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'storage.network.received.volume.bytes',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B',
|
||||
change_bytes => 1
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'storage.network.received.volume.bytespersecond',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B/s',
|
||||
change_bytes => 1
|
||||
}
|
||||
},
|
||||
threshold => 'received-volume',
|
||||
order => 2
|
||||
},
|
||||
'network/sent_bytes_count' => {
|
||||
output_string => 'sent: %.2f',
|
||||
perfdata => {
|
||||
absolute => {
|
||||
nlabel => 'storage.network.sent.volume.bytes',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B',
|
||||
change_bytes => 1
|
||||
},
|
||||
per_second => {
|
||||
nlabel => 'storage.network.sent.volume.bytespersecond',
|
||||
format => '%.2f',
|
||||
min => 0,
|
||||
unit => 'B/s',
|
||||
change_bytes => 1
|
||||
}
|
||||
},
|
||||
threshold => 'sent-volume',
|
||||
order => 3
|
||||
}
|
||||
};
|
||||
|
||||
return $metrics_mapping;
|
||||
}
|
||||
|
||||
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 => {
|
||||
'dimension-name:s' => { name => 'dimension_name', default => 'resource.labels.bucket_name' },
|
||||
'dimension-operator:s' => { name => 'dimension_operator', default => 'equals' },
|
||||
'dimension-value:s' => { name => 'dimension_value' },
|
||||
'filter-metric:s' => { name => 'filter_metric' },
|
||||
"per-second" => { name => 'per_second' },
|
||||
'timeframe:s' => { name => 'timeframe' },
|
||||
'aggregation:s@' => { name => 'aggregation' }
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub check_options {
|
||||
my ($self, %options) = @_;
|
||||
$self->SUPER::check_options(%options);
|
||||
|
||||
$self->{gcp_api} = 'storage.googleapis.com';
|
||||
$self->{gcp_dimension_name} = (!defined($self->{option_results}->{dimension_name}) || $self->{option_results}->{dimension_name} eq '') ? 'resource.labels.bucket_name' : $self->{option_results}->{dimension_name};
|
||||
$self->{gcp_dimension_zeroed} = 'resource.labels.bucket_name';
|
||||
$self->{gcp_instance_key} = 'resource.labels.bucket_name';
|
||||
$self->{gcp_dimension_operator} = $self->{option_results}->{dimension_operator};
|
||||
$self->{gcp_dimension_value} = $self->{option_results}->{dimension_value};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 MODE
|
||||
|
||||
Check storage network metrics.
|
||||
|
||||
Example:
|
||||
|
||||
perl centreon_plugins.pl --plugin=cloud::google::gcp::storage::plugin
|
||||
--mode=network --dimension-value=mydatabaseid --filter-metric='sent'
|
||||
--aggregation='average' --critical-received-volume='10' --verbose
|
||||
|
||||
Default aggregation: 'average' / All aggregations are valid.
|
||||
|
||||
=over 8
|
||||
|
||||
=item B<--dimension-name>
|
||||
|
||||
Set dimension name (Default: 'resource.labels.bucket_name'). Can be: 'resources.labels.location'.
|
||||
|
||||
=item B<--dimension-operator>
|
||||
|
||||
Set dimension operator (Default: 'equals'. Can also be: 'regexp', 'starts').
|
||||
|
||||
=item B<--dimension-value>
|
||||
|
||||
Set dimension value (Required).
|
||||
|
||||
=item B<--filter-metric>
|
||||
|
||||
Filter metrics (Can be: 'storage/object_count', 'network/received_bytes_count',
|
||||
'network/sent_bytes_count') (Can be a regexp).
|
||||
|
||||
=item B<--timeframe>
|
||||
|
||||
Set timeframe in seconds (i.e. 3600 to check last hour).
|
||||
|
||||
=item B<--aggregation>
|
||||
|
||||
Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total').
|
||||
|
||||
=item B<--warning-*> B<--critical-*>
|
||||
|
||||
Thresholds (Can be: 'bucket-objects', 'received-volume', 'sent-volume').
|
||||
|
||||
=item B<--per-second>
|
||||
|
||||
Change the data to be unit/sec.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
|
@ -0,0 +1,49 @@
|
|||
#
|
||||
# Copyright 2020 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::storage::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} = {
|
||||
'bucket' => 'cloud::google::gcp::storage::mode::bucket'
|
||||
};
|
||||
|
||||
$self->{custom_modes}->{api} = 'cloud::google::gcp::custom::api';
|
||||
return $self;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 PLUGIN DESCRIPTION
|
||||
|
||||
Check Google Cloud Platform Storage.
|
||||
|
||||
=cut
|
Loading…
Reference in New Issue