Skip to content

Commit 7edda46

Browse files
committed
feat(os/aix/snmp): add memory monitoring mode via hrStorageTable
- Extends centreon::plugins::templates::counter following swap.pm conventions - Walks hrStorageTable dynamically to identify RAM entry by hrStorageType OID - AIX exposes RAM as hrStorageRam (.1.3.6.1.2.1.25.2.1.2) with dynamic index - No fixed index assumption -- works across all AIX versions and configurations - Tested on AIX 7.x production infrastructure
1 parent 562f357 commit 7edda46

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

src/os/aix/snmp/mode/memory.pm

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#
2+
# Copyright 2024 Centreon (http://www.centreon.com/)
3+
#
4+
# Centreon is a full-fledged industry-strength solution that meets
5+
# the needs in IT infrastructure and application monitoring for
6+
# service performance.
7+
#
8+
# Licensed under the Apache License, Version 2.0 (the "License");
9+
# you may not use this file except in compliance with the License.
10+
# You may obtain a copy of the License at
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing, software
15+
# distributed under the License is distributed on an "AS IS" BASIS,
16+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
# See the License for the specific language governing permissions and
18+
# limitations under the License.
19+
#
20+
21+
package os::aix::snmp::mode::memory;
22+
23+
use base qw(centreon::plugins::templates::counter);
24+
25+
use strict;
26+
use warnings;
27+
28+
my $oid_hrStorageType = '.1.3.6.1.2.1.25.2.3.1.2';
29+
my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4';
30+
my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5';
31+
my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6';
32+
my $oid_hrStorageRam = '.1.3.6.1.2.1.25.2.1.2';
33+
34+
sub custom_usage_calc {
35+
my ($self, %options) = @_;
36+
37+
return -10 if ($options{new_datas}->{$self->{instance} . '_total'} <= 0);
38+
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'};
39+
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'};
40+
$self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used};
41+
$self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total};
42+
$self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used};
43+
44+
return 0;
45+
}
46+
47+
sub custom_usage_output {
48+
my ($self, %options) = @_;
49+
50+
my ($total_h, $total_u) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
51+
my ($used_h, $used_u) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
52+
my ($free_h, $free_u) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
53+
54+
return sprintf(
55+
'Ram Total: %s %s Used: %s %s (%.2f%%) Free: %s %s (%.2f%%)',
56+
$total_h, $total_u,
57+
$used_h, $used_u, $self->{result_values}->{prct_used},
58+
$free_h, $free_u, $self->{result_values}->{prct_free}
59+
);
60+
}
61+
62+
sub set_counters {
63+
my ($self, %options) = @_;
64+
65+
$self->{maps_counters_type} = [
66+
{ name => 'memory', type => 0, skipped_code => { -10 => 1 } }
67+
];
68+
69+
$self->{maps_counters}->{memory} = [
70+
{ label => 'usage', nlabel => 'memory.usage.bytes', set => {
71+
key_values => [ { name => 'used' }, { name => 'total' } ],
72+
closure_custom_calc => $self->can('custom_usage_calc'),
73+
closure_custom_output => $self->can('custom_usage_output'),
74+
threshold_use => 'prct_used',
75+
perfdatas => [
76+
{ label => 'memory_used', value => 'used', template => '%d', cast_int => 1,
77+
unit => 'B', min => 0, max => 'total', threshold_total => 'total' },
78+
{ label => 'memory_free', value => 'free', template => '%d', cast_int => 1,
79+
unit => 'B', min => 0, max => 'total' },
80+
{ label => 'memory_usage', value => 'prct_used', template => '%.2f',
81+
unit => '%', min => 0, max => 100 }
82+
]
83+
}}
84+
];
85+
}
86+
87+
sub new {
88+
my ($class, %options) = @_;
89+
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
90+
bless $self, $class;
91+
92+
return $self;
93+
}
94+
95+
sub manage_selection {
96+
my ($self, %options) = @_;
97+
98+
my $snmp_result = $options{snmp}->get_table(
99+
oid => '.1.3.6.1.2.1.25.2.3',
100+
nothing_quit => 1
101+
);
102+
103+
$self->{memory} = {};
104+
105+
foreach my $oid (keys %{$snmp_result}) {
106+
next if ($oid !~ /^$oid_hrStorageType\.(\d+)$/);
107+
my $index = $1;
108+
my $type = $snmp_result->{$oid};
109+
110+
next if ($type ne $oid_hrStorageRam);
111+
112+
my $alloc = $snmp_result->{ $oid_hrStorageAllocationUnits . '.' . $index };
113+
my $size = $snmp_result->{ $oid_hrStorageSize . '.' . $index };
114+
my $used = $snmp_result->{ $oid_hrStorageUsed . '.' . $index };
115+
116+
next if (!defined($size) || !defined($used) || !defined($alloc) || $size == 0);
117+
118+
$self->{memory} = {
119+
total => $size * $alloc,
120+
used => $used * $alloc
121+
};
122+
123+
last; # RAM entry found, no need to continue
124+
}
125+
126+
if (!defined($self->{memory}->{total})) {
127+
$self->{output}->add_option_msg(
128+
short_msg => 'Cannot find RAM entry in hrStorageTable. ' .
129+
'Check that hrStorageRam OID (.1.3.6.1.2.1.25.2.1.2) is exposed by the SNMP agent.'
130+
);
131+
$self->{output}->option_exit();
132+
}
133+
}
134+
135+
1;
136+
137+
__END__
138+
139+
=head1 MODE
140+
141+
Check physical memory (RAM) usage on AIX servers via SNMP HOST-RESOURCES-MIB.
142+
143+
AIX SNMP agents expose RAM under hrStorageType = hrStorageRam (.1.3.6.1.2.1.25.2.1.2).
144+
Unlike Linux, the storage index for RAM is dynamic and discovered by scanning hrStorageTable.
145+
146+
For swap monitoring on AIX, use the dedicated 'swap' mode which leverages
147+
AIX-specific IBM MIB OIDs for more detailed paging space information.
148+
149+
=over 8
150+
151+
=item B<--warning-usage>
152+
153+
Warning threshold on RAM usage (%).
154+
155+
=item B<--critical-usage>
156+
157+
Critical threshold on RAM usage (%).
158+
159+
=back
160+
161+
=cut

src/os/aix/snmp/plugin.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ sub new {
3939
'processcount' => 'snmp_standard::mode::processcount',
4040
'storage' => 'snmp_standard::mode::storage',
4141
'swap' => 'os::aix::snmp::mode::swap',
42+
'memory' => 'os::aix::snmp::mode::memory',
4243
'time' => 'snmp_standard::mode::ntp',
4344
'uptime' => 'snmp_standard::mode::uptime',
4445
);

0 commit comments

Comments
 (0)