Skip to content

Commit

Permalink
enh(netapp-ontap-restapi): add metrics to volumes mode + optimization…
Browse files Browse the repository at this point in the history
…s + tests (#5368)

Refs: CTOR-1039
  • Loading branch information
itoussies authored Jan 13, 2025
1 parent 56e8d8c commit 942c0b7
Show file tree
Hide file tree
Showing 18 changed files with 897 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/storage/netapp/ontap/restapi/mode/aggregates.pm
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;

my $aggregates = $options{custom}->request_api(endpoint => '/api/storage/aggregates?fields=*');
my $aggregates = $options{custom}->request_api(endpoint => '/api/storage/aggregates?fields=name,uuid,state,space');

$self->{aggregates} = {};
foreach (@{$aggregates->{records}}) {
Expand Down
12 changes: 6 additions & 6 deletions src/storage/netapp/ontap/restapi/mode/cluster.pm
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;

my $cluster = $options{custom}->request_api(endpoint => '/api/cluster?fields=*');
my $cluster = $options{custom}->request_api(endpoint => '/api/cluster?fields=name,statistics,metric');

$self->{clusters} = {
$cluster->{name} => {
Expand All @@ -219,7 +219,7 @@ sub manage_selection {
}
};

my $nodes = $options{custom}->request_api(endpoint => '/api/cluster/nodes?fields=*');
my $nodes = $options{custom}->request_api(endpoint => '/api/cluster/nodes?fields=name,service_processor');
foreach (@{$nodes->{records}}) {
$self->{clusters}->{ $cluster->{name} }->{nodes}->{ $_->{name} } = {
display => $_->{name},
Expand All @@ -245,7 +245,7 @@ Check cluster.
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='node-status'
Example: C<--filter-counters='node-status'>
=item B<--unknown-node-status>
Expand All @@ -265,9 +265,9 @@ You can use the following variables: %{state}, %{link_status}, %{display}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'cpu-utilization' (%), 'read' (B/s), 'write' (B/s), 'read-iops', 'write-iops',
'read-latency' (ms), 'write-lantency' (ms), 'other-latency' (ms), 'total-latency' (ms),
'other' (B/s), 'total' (B/s), 'other-iops', 'total-iops'.
Can be: C<cpu-utilization> (%), C<read> (B/s), C<write> (B/s), C<read-iops>, C<write-iops>,
C<read-latency> (ms), C<write-latency> (ms), C<other-latency> (ms), C<total-latency> (ms),
C<other> (B/s), C<total> (B/s), C<other-iops>, C<total-iops>.
=back
Expand Down
2 changes: 1 addition & 1 deletion src/storage/netapp/ontap/restapi/mode/components/fru.pm
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ sub check {
next if ($self->check_filter(section => 'shelf', instance => $shelf_instance));

foreach my $fru (@{$shelf->{frus}}) {
my $name = $fru->{type} . ':' . $fru->{id};
my $name = $fru->{type} . ':' . (defined($fru->{id}) ? $fru->{id} : '');

if ($fru->{installed} !~ /true|1/i) {
$self->{output}->output_add(
Expand Down
8 changes: 4 additions & 4 deletions src/storage/netapp/ontap/restapi/mode/hardware.pm
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ sub new {
sub get_disks {
my ($self, %options) = @_;

return $self->{custom}->request_api(endpoint => '/api/storage/disks?fields=*');
return $self->{custom}->request_api(endpoint => '/api/storage/disks?fields=name,state,serial_number,bay');
}

sub get_shelves {
my ($self, %options) = @_;

return if (defined($self->{shelves}));

$self->{shelves} = $self->{custom}->request_api(endpoint => '/api/storage/shelves?fields=*');
$self->{shelves} = $self->{custom}->request_api(endpoint => '/api/storage/shelves?fields=name,state,serial_number,bay,frus');
}

sub save_custom {
Expand All @@ -96,7 +96,7 @@ Check hardware.
=item B<--component>
Which component to check (default: '.*').
Can be: 'bay', 'disk', 'fru', 'shelf'.
Can be: C<bay>, C<disk>, C<fru>, C<shelf>.
=item B<--filter>
Expand All @@ -110,7 +110,7 @@ Define the expected status if no components are found (default: critical).
=item B<--threshold-overload>
Use this option to override the status returned by the plugin when the status label matches a regular expression (syntax: section,[instance,]status,regexp).
Example: --threshold-overload='fru,OK,error'
Example: C<--threshold-overload='fru,OK,error'>
=back
Expand Down
2 changes: 1 addition & 1 deletion src/storage/netapp/ontap/restapi/mode/listvolumes.pm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sub check_options {
sub manage_selection {
my ($self, %options) = @_;

return $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=*');
return $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=svm,state,name');
}

sub run {
Expand Down
2 changes: 1 addition & 1 deletion src/storage/netapp/ontap/restapi/mode/luns.pm
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;

my $luns = $options{custom}->request_api(endpoint => '/api/storage/luns?fields=*');
my $luns = $options{custom}->request_api(endpoint => '/api/storage/luns?fields=name,status');

$self->{luns} = {};
foreach (@{$luns->{records}}) {
Expand Down
6 changes: 3 additions & 3 deletions src/storage/netapp/ontap/restapi/mode/quotas.pm
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;

my $quotas = $options{custom}->request_api(endpoint => '/api/storage/quota/reports?fields=*');
my $quotas = $options{custom}->request_api(endpoint => '/api/storage/quota/reports?fields=index,qtree,volume,svm,space');

$self->{duplicated} = {};

Expand Down Expand Up @@ -318,15 +318,15 @@ Filter by index (identified entry in the /etc/quotas) (can be a regexp).
=item B<--filter-vserver>
Filter by vserver name (can be a regexp).
Filter by Vserver name (can be a regexp).
=item B<--filter-volume>
Filter by volume name (can be a regexp).
=item B<--filter-qtree>
Filter by qtree name (can be a regexp).
Filter by Qtree name (can be a regexp).
=item B<--warning-*> B<--critical-*>
Expand Down
8 changes: 4 additions & 4 deletions src/storage/netapp/ontap/restapi/mode/snapmirrors.pm
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;

my $snapmirrors = $options{custom}->request_api(endpoint => '/api/snapmirror/relationships?fields=*');
my $snapmirrors = $options{custom}->request_api(endpoint => '/api/snapmirror/relationships?fields=source,destination,healthy,state,transfer');

$self->{snapmirrors} = {};
foreach (@{$snapmirrors->{records}}) {
Expand All @@ -89,7 +89,7 @@ sub manage_selection {

$self->{snapmirrors}->{$name} = {
display => $name,
healthy => $_->{healthy} =~ /true|1/i ? 'true' : 'false',
healthy => (defined($_->{healthy}) && $_->{healthy} =~ /true|1/i) ? 'true' : 'false',
state => $_->{state},
transfer_state => defined($_->{transfer}->{state}) ? $_->{transfer}->{state} : 'n/a'
};
Expand All @@ -107,13 +107,13 @@ __END__
=head1 MODE
Check snapmirrors.
Check SnapMirrors.
=over 8
=item B<--filter-name>
Filter snapmirror name (can be a regexp).
Filter SnapMirror name (can be a regexp).
=item B<--unknown-status>
Expand Down
94 changes: 79 additions & 15 deletions src/storage/netapp/ontap/restapi/mode/volumes.pm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ sub custom_usage_output {
);
}

sub custom_logical_usage_output {
my ($self, %options) = @_;

my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_logical_space});
my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{logical_used_space});
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{logical_free_space});
return sprintf(
'logical space usage total: %s used: %s (%.2f%%) free: %s (%.2f%%)',
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{logical_prct_used_space},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{logical_prct_free_space}
);
}

sub prefix_volume_output {
my ($self, %options) = @_;

Expand Down Expand Up @@ -94,6 +108,33 @@ sub set_counters {
]
}
},
{ label => 'logical-usage', nlabel => 'volume.logicalspace.usage.bytes', set => {
key_values => [ { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_logical_space' }, { name => 'display' }, ],
closure_custom_output => $self->can('custom_logical_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total_logical_space',
unit => 'B', cast_int => 1, label_extra_instance => 1 }
]
}
},
{ label => 'logical-usage-free', nlabel => 'volume.logicalspace.free.bytes', display_ok => 0, set => {
key_values => [ { name => 'logical_free_space' }, { name => 'logical_used_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_logical_space' }, { name => 'display' }, ],
closure_custom_output => $self->can('custom_logical_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total_logical_space',
unit => 'B', cast_int => 1, label_extra_instance => 1 }
]
}
},
{ label => 'logical-usage-prct', nlabel => 'volume.logicalspace.usage.percentage', display_ok => 0, set => {
key_values => [ { name => 'logical_prct_used_space' }, { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_free_space' }, { name => 'total_logical_space' }, { name => 'display' }, ],
closure_custom_output => $self->can('custom_logical_usage_output'),
perfdatas => [
{ template => '%.2f', min => 0, max => 100,
unit => '%', label_extra_instance => 1 }
]
}
},
{ label => 'read', nlabel => 'volume.io.read.usage.bytespersecond', display_ok => 0, set => {
key_values => [ { name => 'read' } ],
output_template => 'read: %s %s/s',
Expand Down Expand Up @@ -203,6 +244,7 @@ sub new {
bless $self, $class;

$options{options}->add_options(arguments => {
'filter-volume-name:s' => { name => 'filter_volume_name' },
'filter-name:s' => { name => 'filter_name' },
'filter-vserver-name:s' => { name => 'filter_vserver_name' }
});
Expand All @@ -213,7 +255,13 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;

my $volumes = $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=*');
my $endpoint = '/api/storage/volumes?fields=svm,name,space,metric';

if (defined($self->{option_results}->{filter_volume_name}) && $self->{option_results}->{filter_volume_name} ne '' ) {
$endpoint .= '&name=' . $self->{option_results}->{filter_volume_name}
}

my $volumes = $options{custom}->request_api(endpoint => $endpoint);

$self->{volumes} = {};
foreach (@{$volumes->{records}}) {
Expand Down Expand Up @@ -249,11 +297,21 @@ sub manage_selection {
write_iops => $_->{metric}->{iops}->{write},
other_iops => $_->{metric}->{iops}->{other},
total_iops => $_->{metric}->{iops}->{total},
read_latency => $_->{metric}->{latency}->{read} / 1000,
write_latency => $_->{metric}->{latency}->{write} / 1000,
other_latency => $_->{metric}->{latency}->{other} / 1000,
total_latency => $_->{metric}->{latency}->{total} / 1000
read_latency => (defined($_->{metric}->{latency}->{read})) ? ($_->{metric}->{latency}->{read} / 1000) : undef,
write_latency => (defined($_->{metric}->{latency}->{write})) ? ($_->{metric}->{latency}->{write} / 1000) : undef,
other_latency => (defined($_->{metric}->{latency}->{other})) ? ($_->{metric}->{latency}->{other} / 1000) : undef,
total_latency => (defined($_->{metric}->{latency}->{total})) ? ($_->{metric}->{latency}->{total} / 1000) : undef,
};

if (defined($_->{space}->{logical_space})) {
$self->{volumes}->{$name}->{total_logical_space} = $_->{space}->{logical_space}->{used} + $_->{space}->{logical_space}->{available};
$self->{volumes}->{$name}->{logical_used_space} = $_->{space}->{logical_space}->{used};
$self->{volumes}->{$name}->{logical_free_space} = $_->{space}->{logical_space}->{available};
$self->{volumes}->{$name}->{logical_prct_used_space} = $_->{space}->{logical_space}->{used_percent};
$self->{volumes}->{$name}->{logical_prct_free_space} = 100 - $_->{space}->{logical_space}->{used_percent};
}


}

if (scalar(keys %{$self->{volumes}}) <= 0) {
Expand All @@ -275,15 +333,20 @@ Check volumes.
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='^usage$'
Example: C<--filter-counters='^usage$'>.
=item B<--filter-volume-name>
Filter the API request by volumes name (* can be used, volumes name are separated by |). Required if you wan to retrieve
logical space metrics.
=item B<--filter-name>
Filter volumes by volume name (can be a regexp).
Filter the API request result by volume name (can be a regexp).
=item B<--filter-vserver-name>
Filter volumes by vserver name (can be a regexp).
Filter volumes by Vserver name (can be a regexp).
=item B<--unknown-status>
Expand All @@ -293,21 +356,22 @@ You can use the following variables: %{state}, %{display}
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{state}, %{display}
You can use the following variables: %{state}, %{display}.
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: '%{state} !~ /online/i').
You can use the following variables: %{state}, %{display}
You can use the following variables: %{state}, %{display}.
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%),
'read' (B/s), 'read-iops', 'write' (B/s), 'write-iops',
'read-latency' (ms), 'write-latency' (ms), 'total-latency' (ms),
'other-latency' (ms), 'other' (B/s), 'total' (B/s),
'other-iops', 'total-iops'.
Can be: usage' (B), usage-free (B), usage-prct (%),
logical-usage (B), logical-usage-free (B), logical-usage-prct (%),
read (B/s), read-iops, write (B/s), write-iops,
read-latency (ms), write-latency (ms), total-latency (ms),
other-latency (ms), other (B/s), total (B/s),
other-iops, total-iops.
=back
Expand Down
13 changes: 7 additions & 6 deletions tests/resources/spellcheck/stopwords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ ldap
--legacy-api-beta
license-instances-usage-prct
Loggly
--lookback
--lookup-perfdatas-nagios
LUN
LUNs
machineaccount
--map-speed-dsl
MBean
Expand Down Expand Up @@ -204,11 +204,9 @@ proto
--proxyurl
psu
QoS
Qtree
queue-messages-inflighted
raidvolume
--redis-attribute
--redis-db
--redis-server
RestAPI
RFC1628
RRDCached
Expand All @@ -220,6 +218,8 @@ SFDC
sfp.temperature
--skip-ssl-check
SkyHigh
SnapMirror
SnapMirrors
SNMP
space-usage-prct
--sql-errors-exit
Expand Down Expand Up @@ -259,6 +259,7 @@ v2
VDSL2
Veeam
VeloCloud
Vserver
VM
VMware
VPN
Expand All @@ -279,4 +280,4 @@ WLAN
WLC
WSMAN
XPath
ZFS
ZFS
Loading

0 comments on commit 942c0b7

Please sign in to comment.