enh(protocol/snmp): collection mode - add sampling system (#2772)
This commit is contained in:
parent
a03662289f
commit
b5ae2ff417
|
@ -27,6 +27,7 @@ use warnings;
|
||||||
use JSON::XS;
|
use JSON::XS;
|
||||||
use Safe;
|
use Safe;
|
||||||
use centreon::plugins::statefile;
|
use centreon::plugins::statefile;
|
||||||
|
use Digest::MD5 qw(md5_hex);
|
||||||
|
|
||||||
sub custom_select_threshold {
|
sub custom_select_threshold {
|
||||||
my ($self, %options) = @_;
|
my ($self, %options) = @_;
|
||||||
|
@ -215,6 +216,7 @@ sub collect_snmp_tables {
|
||||||
}
|
}
|
||||||
|
|
||||||
my $mapping = {};
|
my $mapping = {};
|
||||||
|
my $sampling = {};
|
||||||
foreach (@{$table->{entries}}) {
|
foreach (@{$table->{entries}}) {
|
||||||
$self->validate_name(name => $_->{name}, section => "[snmp > tables > $table->{name}]");
|
$self->validate_name(name => $_->{name}, section => "[snmp > tables > $table->{name}]");
|
||||||
if (!defined($_->{oid}) || $_->{oid} eq '') {
|
if (!defined($_->{oid}) || $_->{oid} eq '') {
|
||||||
|
@ -222,6 +224,7 @@ sub collect_snmp_tables {
|
||||||
$self->{output}->option_exit();
|
$self->{output}->option_exit();
|
||||||
}
|
}
|
||||||
$mapping->{ $_->{name} } = { oid => $_->{oid} };
|
$mapping->{ $_->{name} } = { oid => $_->{oid} };
|
||||||
|
$sampling->{ $_->{name} } = 1 if (defined($_->{sampling}) && $_->{sampling} == 1);
|
||||||
if (defined($_->{map}) && $_->{map} ne '') {
|
if (defined($_->{map}) && $_->{map} ne '') {
|
||||||
if (!defined($self->{config}->{mapping}) || !defined($self->{config}->{mapping}->{ $_->{map} })) {
|
if (!defined($self->{config}->{mapping}) || !defined($self->{config}->{mapping}->{ $_->{map} })) {
|
||||||
$self->{output}->add_option_msg(short_msg => "unknown map attribute [snmp > tables > $table->{name} > $_->{name}]: $_->{map}");
|
$self->{output}->add_option_msg(short_msg => "unknown map attribute [snmp > tables > $table->{name} > $_->{name}]: $_->{map}");
|
||||||
|
@ -243,6 +246,12 @@ sub collect_snmp_tables {
|
||||||
/$used_instance/;
|
/$used_instance/;
|
||||||
next if (defined($self->{snmp_collected}->{tables}->{ $table->{name} }->{$1}));
|
next if (defined($self->{snmp_collected}->{tables}->{ $table->{name} }->{$1}));
|
||||||
$self->{snmp_collected}->{tables}->{ $table->{name} }->{$1} = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $1);
|
$self->{snmp_collected}->{tables}->{ $table->{name} }->{$1} = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $1);
|
||||||
|
foreach my $sample_name (keys %$sampling) {
|
||||||
|
$self->{snmp_collected_sampling}->{tables}->{ $table->{name} } = {}
|
||||||
|
if (!defined($self->{snmp_collected_sampling}->{tables}->{ $table->{name} }));
|
||||||
|
$self->{snmp_collected_sampling}->{tables}->{ $table->{name} }->{$1}->{$sample_name} =
|
||||||
|
$self->{snmp_collected}->{tables}->{ $table->{name} }->{$1}->{$sample_name};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,6 +269,10 @@ sub collect_snmp_leefs {
|
||||||
$self->{snmp_collected}->{leefs}->{ $_->{name} } = defined($_->{default}) ? $_->{default} : '';
|
$self->{snmp_collected}->{leefs}->{ $_->{name} } = defined($_->{default}) ? $_->{default} : '';
|
||||||
next if (!defined($_->{oid}) || !defined($snmp_result->{ $_->{oid } }));
|
next if (!defined($_->{oid}) || !defined($snmp_result->{ $_->{oid } }));
|
||||||
$self->{snmp_collected}->{leefs}->{ $_->{name} } = $snmp_result->{ $_->{oid } };
|
$self->{snmp_collected}->{leefs}->{ $_->{name} } = $snmp_result->{ $_->{oid } };
|
||||||
|
if (defined($_->{sampling}) && $_->{sampling} == 1) {
|
||||||
|
$self->{snmp_collected_sampling}->{leefs}->{ $_->{name} } = $snmp_result->{ $_->{oid } };
|
||||||
|
}
|
||||||
|
|
||||||
if (defined($_->{map}) && $_->{map} ne '') {
|
if (defined($_->{map}) && $_->{map} ne '') {
|
||||||
my $value = $self->get_map_value(value => $snmp_result->{ $_->{oid } }, map => $_->{map});
|
my $value = $self->get_map_value(value => $snmp_result->{ $_->{oid } }, map => $_->{map});
|
||||||
if (!defined($value)) {
|
if (!defined($value)) {
|
||||||
|
@ -289,7 +302,8 @@ sub use_snmp_cache {
|
||||||
return 0 if ($self->is_snmp_cache_enabled() == 0);
|
return 0 if ($self->is_snmp_cache_enabled() == 0);
|
||||||
|
|
||||||
my $has_cache_file = $self->{snmp_cache}->read(
|
my $has_cache_file = $self->{snmp_cache}->read(
|
||||||
statefile => 'cache_snmp_collection_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port()
|
statefile => 'cache_snmp_collection_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' .
|
||||||
|
md5_hex($self->{option_results}->{config})
|
||||||
);
|
);
|
||||||
$self->{snmp_collected} = $self->{snmp_cache}->get(name => 'snmp_collected');
|
$self->{snmp_collected} = $self->{snmp_cache}->get(name => 'snmp_collected');
|
||||||
my $reload = defined($self->{config}->{snmp}->{cache}->{reload}) && $self->{config}->{snmp}->{cache}->{reload} =~ /(\d+)/ ?
|
my $reload = defined($self->{config}->{snmp}->{cache}->{reload}) && $self->{config}->{snmp}->{cache}->{reload} =~ /(\d+)/ ?
|
||||||
|
@ -310,6 +324,70 @@ sub save_snmp_cache {
|
||||||
$self->{snmp_cache}->write(data => { snmp_collected => $self->{snmp_collected} });
|
$self->{snmp_cache}->write(data => { snmp_collected => $self->{snmp_collected} });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub collect_snmp_sampling {
|
||||||
|
my ($self, %options) = @_;
|
||||||
|
|
||||||
|
return if ($self->{snmp_collected}->{sampling} == 0);
|
||||||
|
|
||||||
|
my $has_cache_file = $self->{snmp_cache}->read(
|
||||||
|
statefile => 'cache_snmp_collection_sampling_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' .
|
||||||
|
md5_hex($self->{option_results}->{config})
|
||||||
|
);
|
||||||
|
my $snmp_collected_sampling_old = $self->{snmp_cache}->get(name => 'snmp_collected_sampling');
|
||||||
|
# with cache, we need to load the sampling cache maybe. please a statefile-suffix to get uniq files.
|
||||||
|
# sampling with a global cache can be a nonsense
|
||||||
|
if (!defined($self->{snmp_collected_sampling})) {
|
||||||
|
$self->{snmp_collected_sampling} = $snmp_collected_sampling_old;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $delta_time;
|
||||||
|
if (defined($snmp_collected_sampling_old->{epoch})) {
|
||||||
|
$delta_time = $self->{snmp_collected_sampling}->{epoch} - $snmp_collected_sampling_old->{epoch};
|
||||||
|
$delta_time = 1 if ($delta_time <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (keys %{$self->{snmp_collected_sampling}->{leefs}}) {
|
||||||
|
next if (!defined($snmp_collected_sampling_old->{leefs}->{$_}) || $snmp_collected_sampling_old->{leefs}->{$_} !~ /\d/);
|
||||||
|
my $old = $snmp_collected_sampling_old->{leefs}->{$_};
|
||||||
|
my $diff = $self->{snmp_collected_sampling}->{leefs}->{$_} - $old;
|
||||||
|
my $diff_counter = $diff;
|
||||||
|
$diff_counter = $self->{snmp_collected_sampling}->{leefs}->{$_} if ($diff_counter < 0);
|
||||||
|
|
||||||
|
$self->{snmp_collected}->{leefs}->{ $_ . 'Diff' } = $diff;
|
||||||
|
$self->{snmp_collected}->{leefs}->{ $_ . 'DiffCounter' } = $diff_counter;
|
||||||
|
if (defined($delta_time)) {
|
||||||
|
$self->{snmp_collected}->{leefs}->{ $_ . 'PerSeconds' } = $diff_counter / $delta_time;
|
||||||
|
$self->{snmp_collected}->{leefs}->{ $_ . 'PerMinutes' } = $diff_counter / $delta_time / 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $tbl_name (keys %{$self->{snmp_collected_sampling}->{tables}}) {
|
||||||
|
foreach my $instance (keys %{$self->{snmp_collected_sampling}->{tables}->{$tbl_name}}) {
|
||||||
|
foreach my $attr (keys %{$self->{snmp_collected_sampling}->{tables}->{$tbl_name}->{$instance}}) {
|
||||||
|
next if (
|
||||||
|
!defined($snmp_collected_sampling_old->{tables}->{$tbl_name}) ||
|
||||||
|
!defined($snmp_collected_sampling_old->{tables}->{$tbl_name}->{$instance}) ||
|
||||||
|
!defined($snmp_collected_sampling_old->{tables}->{$tbl_name}->{$instance}->{$attr}) ||
|
||||||
|
$snmp_collected_sampling_old->{tables}->{$tbl_name}->{$instance}->{$attr} !~ /\d/
|
||||||
|
);
|
||||||
|
my $old = $snmp_collected_sampling_old->{tables}->{$tbl_name}->{$instance}->{$attr};
|
||||||
|
my $diff = $self->{snmp_collected_sampling}->{tables}->{$tbl_name}->{$instance}->{$attr} - $old;
|
||||||
|
my $diff_counter = $diff;
|
||||||
|
$diff_counter = $self->{snmp_collected_sampling}->{tables}->{$tbl_name}->{$instance}->{$attr} if ($diff_counter < 0);
|
||||||
|
|
||||||
|
$self->{snmp_collected}->{tables}->{$tbl_name}->{$instance}->{ $attr . 'Diff' } = $diff;
|
||||||
|
$self->{snmp_collected}->{tables}->{$tbl_name}->{$instance}->{ $attr . 'DiffCounter' } = $diff_counter;
|
||||||
|
if (defined($delta_time)) {
|
||||||
|
$self->{snmp_collected}->{tables}->{$tbl_name}->{$instance}->{ $attr . 'PerSeconds' } = $diff_counter / $delta_time;
|
||||||
|
$self->{snmp_collected}->{tables}->{$tbl_name}->{$instance}->{ $attr . 'PerMinutes' } = $diff_counter / $delta_time / 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->{snmp_cache}->write(data => { snmp_collected_sampling => $self->{snmp_collected_sampling} });
|
||||||
|
}
|
||||||
|
|
||||||
sub collect_snmp {
|
sub collect_snmp {
|
||||||
my ($self, %options) = @_;
|
my ($self, %options) = @_;
|
||||||
|
|
||||||
|
@ -318,14 +396,21 @@ sub collect_snmp {
|
||||||
$self->{output}->option_exit();
|
$self->{output}->option_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
return if ($self->use_snmp_cache(snmp => $options{snmp}));
|
if ($self->use_snmp_cache(snmp => $options{snmp}) == 0) {
|
||||||
|
$self->{snmp_collected_sampling} = { tables => {}, leefs => {}, epoch => time() };
|
||||||
|
$self->{snmp_collected} = { tables => {}, leefs => {}, epoch => time(), sampling => 0 };
|
||||||
|
|
||||||
$self->{snmp_collected} = { tables => {}, leefs => {}, epoch => time() };
|
$self->collect_snmp_tables(snmp => $options{snmp});
|
||||||
|
$self->collect_snmp_leefs(snmp => $options{snmp});
|
||||||
|
|
||||||
$self->collect_snmp_tables(snmp => $options{snmp});
|
$self->{snmp_collected}->{sampling} = 1 if (
|
||||||
$self->collect_snmp_leefs(snmp => $options{snmp});
|
scalar(keys(%{$self->{snmp_collected_sampling}->{tables}})) > 0 ||
|
||||||
|
scalar(keys(%{$self->{snmp_collected_sampling}->{leefs}})) > 0
|
||||||
|
);
|
||||||
|
$self->save_snmp_cache();
|
||||||
|
}
|
||||||
|
|
||||||
$self->save_snmp_cache();
|
$self->collect_snmp_sampling(snmp => $options{snmp});
|
||||||
}
|
}
|
||||||
|
|
||||||
sub exist_table_name {
|
sub exist_table_name {
|
||||||
|
@ -1049,8 +1134,9 @@ sub manage_selection {
|
||||||
# add some functions types:
|
# add some functions types:
|
||||||
# eval_equal (concatenate, math operation)
|
# eval_equal (concatenate, math operation)
|
||||||
# regexp (regexp substitution, extract a pattern)
|
# regexp (regexp substitution, extract a pattern)
|
||||||
# can add: Diff, PerSecond, PerMinute for snmp values (use statefile)
|
# decode snmp type: ipAddress, DateTime (seconds, strftime)
|
||||||
# can cache only some parts of snmp requests
|
# can cache only some parts of snmp requests:
|
||||||
|
# use an array for "snmp" ?
|
||||||
$self->read_config();
|
$self->read_config();
|
||||||
$self->collect_snmp(snmp => $options{snmp});
|
$self->collect_snmp(snmp => $options{snmp});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue