From e23d0dec2150dd342a3d64a149dc73b137c8d4bf Mon Sep 17 00:00:00 2001 From: Lotfi zaouche Date: Mon, 11 May 2020 15:50:37 +0000 Subject: [PATCH] Code to be completed --- .../blockchain/parity/ethpoller/mode/disk.pm | 135 +++++++++++ .../blockchain/parity/ethpoller/mode/stats.pm | 120 ++++++---- .../parity/ethpoller/mode/tracking.pm | 221 ++++++++++++++++++ .../blockchain/parity/ethpoller/plugin.pm | 8 +- .../blockchain/parity/restapi/mode/eth.pm | 48 +++- .../blockchain/parity/restapi/mode/infos.pm | 121 ++++++++++ .../blockchain/parity/restapi/mode/net.pm | 2 +- .../blockchain/parity/restapi/mode/parity.pm | 65 +++++- .../blockchain/parity/restapi/plugin.pm | 3 +- 9 files changed, 666 insertions(+), 57 deletions(-) create mode 100644 centreon-plugins/blockchain/parity/ethpoller/mode/disk.pm create mode 100644 centreon-plugins/blockchain/parity/ethpoller/mode/tracking.pm create mode 100644 centreon-plugins/blockchain/parity/restapi/mode/infos.pm diff --git a/centreon-plugins/blockchain/parity/ethpoller/mode/disk.pm b/centreon-plugins/blockchain/parity/ethpoller/mode/disk.pm new file mode 100644 index 000000000..bd5158c28 --- /dev/null +++ b/centreon-plugins/blockchain/parity/ethpoller/mode/disk.pm @@ -0,0 +1,135 @@ +# +# 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 blockchain::parity::ethpoller::mode::disk; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use bigint; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', cb_prefix_output => 'prefix_module_output', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'disk_free', nlabel => 'eth.poller.disk.free', set => { + key_values => [ { name => 'disk_free' } ], + output_template => "Disk free: %d ", + perfdatas => [ + { label => 'disk_free', value => 'disk_free_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'disk_available', nlabel => 'eth.poller.disk.free', set => { + key_values => [ { name => 'disk_available' } ], + output_template => "Disk available: %d ", + perfdatas => [ + { label => 'disk_available', value => 'disk_available_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'disk_size', nlabel => 'eth.poller.disk.size', set => { + key_values => [ { name => 'disk_size' } ], + output_template => "Disk size: %d ", + perfdatas => [ + { label => 'disk_size', value => 'disk_size_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'disk_used', nlabel => 'eth.poller.disk.used', set => { + key_values => [ { name => 'disk_used' } ], + output_template => "Disk used: %d ", + perfdatas => [ + { label => 'disk_used', value => 'disk_used_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'disk_usage', nlabel => 'eth.poller.disk.usage', set => { + key_values => [ { name => 'disk_usage' } ], + output_template => "Disk usage: %d %", + perfdatas => [ + { label => 'disk_usage', value => 'disk_usage_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'blockchain_dir', nlabel => 'eth.poller.blockchain.directory', set => { + key_values => [ { name => 'blockchain_dir' } ], + output_template => "Blockchain directory: %d", + perfdatas => [ + { label => 'blockchain_dir', value => 'blockchain_dir_absolute', template => '%d', min => 0 } + ], + } + } + ]; + +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Disk '"; +} + +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 => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(url_path => '/disk'); + + # use Data::Dumper; + # print Dumper($result); + + $self->{global} = { disk_free => $result->{free}, + disk_available => $result->{available}, + disk_size => $result->{size}, + disk_used => $result->{used}, + disk_usage => $result->{usage}, + blockchain_dir => $result->{dir} + }; + + $self->{output}->output_add(severity => 'OK', long_msg => 'Ledger: ' . $result->{dir} . ' (' . $result->{usage} . '%)'); +} + +1; + +__END__ + +=head1 MODE + +Check Parity eth-poller for disk monitoring + +=cut diff --git a/centreon-plugins/blockchain/parity/ethpoller/mode/stats.pm b/centreon-plugins/blockchain/parity/ethpoller/mode/stats.pm index e6cbe1451..10acb6bef 100644 --- a/centreon-plugins/blockchain/parity/ethpoller/mode/stats.pm +++ b/centreon-plugins/blockchain/parity/ethpoller/mode/stats.pm @@ -24,61 +24,61 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use bigint; use Digest::MD5 qw(md5_hex); sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', cb_prefix_output => 'prefix_module_output', type => 0 }, + { name => 'block', cb_prefix_output => 'prefix_output_block', type => 0 }, + { name => 'transaction', cb_prefix_output => 'prefix_output_transaction', type => 0 } ]; - $self->{maps_counters}->{global} = [ - { label => 'stats_blockInterval', nlabel => 'parity.stats.block.interval', set => { - key_values => [ { name => 'stats_blockInterval' } ], - output_template => "Block interval: %d ", + $self->{maps_counters}->{block} = [ + { label => 'block_freq', nlabel => 'parity.stats.block.frequency', set => { + key_values => [ { name => 'block_freq' } ], + output_template => "Block frequency: %d (block/min)", perfdatas => [ - { label => 'stats_blockInterval', value => 'stats_blockInterval_absolute', template => '%d', min => 0 } + { label => 'block_freq', value => 'block_freq_absolute', template => '%d', min => 0 } ], } - }, - { label => 'stats_contracts', nlabel => 'eth.poller.stats.contracts.number', set => { - key_values => [ { name => 'stats_contracts' } ], - output_template => "Cumulative contracts: %d ", - perfdatas => [ - { label => 'stats_contracts', value => 'stats_contracts_absolute', template => '%d', min => 0 } - ], - } - }, - { label => 'stats_blocks', nlabel => 'eth.poller.stats.blocks.number', set => { - key_values => [ { name => 'stats_blocks' } ], - output_template => "Cumulative blocks: %d ", - perfdatas => [ - { label => 'stats_blocks', value => 'stats_blocks_absolute', template => '%d', min => 0 } - ], - } - }, - { label => 'stats_transactions', nlabel => 'eth.poller.stats.transactions.number', set => { - key_values => [ { name => 'stats_transactions' } ], - output_template => "Cumulative transactions: %d ", - perfdatas => [ - { label => 'stats_transactions', value => 'stats_transactions_absolute', template => '%d', min => 0 } - ], - } - }, + } ]; + $self->{maps_counters}->{transaction} = [ + { label => 'transaction_freq', nlabel => 'parity.stats.transaction.frequency', set => { + key_values => [ { name => 'transaction_freq' } ], + output_template => "Transaction frequency: %d (tx/min)", + perfdatas => [ + { label => 'transaction_freq', value => 'transaction_freq_absolute', template => '%d', min => 0 } + ], + } + } + ]; } -sub prefix_output { +sub prefix_output_block { my ($self, %options) = @_; - return "Stats '"; + return "Block stats '"; +} + +sub prefix_output_fork { + my ($self, %options) = @_; + + return "Fork stats '"; +} + +sub prefix_output_transaction { + my ($self, %options) = @_; + + return "Transaction stats '"; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1); bless $self, $class; $options{options}->add_options(arguments => { @@ -91,16 +91,52 @@ sub new { sub manage_selection { my ($self, %options) = @_; + $self->{cache_name} = "parity_ethpoller_" . $self->{mode} . '_' . (defined($self->{option_results}->{hostname}) ? $self->{option_results}->{hostname} : 'me') . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + my $result = $options{custom}->request_api(url_path => '/stats'); - # use Data::Dumper; - # print Dumper($result); + my $old_block_timestamp = $self->{statefile_cache}->get(name => 'last_block_timestamp'); + my $old_block_count = $self->{statefile_cache}->get(name => 'last_block_count'); - $self->{global} = { stats_blockInterval => $result->{blockInterval}, - stats_contracts => $result->{cumulative}->{contracts}, - stats_blocks => $result->{cumulative}->{blocks}, - stats_transactions => $result->{cumulative}->{transactions} - }; + my $old_tx_timestamp = $self->{statefile_cache}->get(name => 'last_tx_timestamp'); + my $old_tx_count = $self->{statefile_cache}->get(name => 'last_tx_count'); + + my $datas = {}; + $datas->{last_block_timestamp} = time(); + $datas->{last_block_count} = $result->{block}->{count}; + + $datas->{last_tx_timestamp} = time(); + $datas->{last_tx_count} = $result->{block}->{count}; + + use Data::Dumper; + print Dumper($old_timestamp); + + my $res_timestamp = 0; + + if ($old_block_count && $old_block_timestamp) { + $res_timestamp = $result->{block}->{timestamp}) == 0 ? '' : $result->{block}->{timestamp})); + my $calculated_block_freq = ($result->{block}->{count} - $old_block_count) / (time() - $old_block_timestamp); + $self->{block} = { block_freq => $calculated_block_freq }; + $self->{output}->output_add(severity => 'OK', long_msg => 'Last block (#' . $result->{block}->{count} . ') was at ' . $res_timestamp); + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'Last block (#' . $result->{block}->{block} . ') was at ' . $res_timestamp . '. Block frequency is being calculated...'); + } + + if ($old_tx_count && $old_tx_timestamp) { + $res_timestamp = $result->{transaction}->{timestamp}) == 0 ? '' : $result->{transaction}->{timestamp})); + my $calculated_tx_freq = ($result->{transaction}->{count} - $old_tx_count) / (time() - $old_tx_timestamp); + $self->{transaction} = { transaction_freq => $calculated_tx_freq }; + $self->{output}->output_add(severity => 'OK', long_msg => 'Last transaction (#' . $result->{transaction}->{count} . ') was at ' . $res_timestamp); + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'Last transaction (#' . $result->{transaction}->{count} . ') was at ' . $res_timestamp . '. Transaction frequency is being calculated...'); + } + + if ($result->{fork}->{count} > 0) { + $self->{output}->output_add(severity => 'OK', long_msg => 'Last fork (#' . $result->{fork}->{count} . ') was at ' . $res_timestamp); + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'No fork occurence'); + } } 1; @@ -109,6 +145,6 @@ __END__ =head1 MODE -Check Parity eth-poller for accounts tracking +Check Parity eth-poller for stats =cut diff --git a/centreon-plugins/blockchain/parity/ethpoller/mode/tracking.pm b/centreon-plugins/blockchain/parity/ethpoller/mode/tracking.pm new file mode 100644 index 000000000..3fbb113dc --- /dev/null +++ b/centreon-plugins/blockchain/parity/ethpoller/mode/tracking.pm @@ -0,0 +1,221 @@ +# +# 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 blockchain::parity::ethpoller::mode::tracking; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use bigint; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'events', cb_prefix_output => 'prefix_module_events', type => 1, message_multiple => 'All event metrics are ok' }, + { name => 'miners', cb_prefix_output => 'prefix_module_miners', type => 1, message_multiple => 'All miner metrics are ok' }, + { name => 'balances', cb_prefix_output => 'prefix_module_balances', type => 1, message_multiple => 'All balance metrics are ok' }, + ]; + + $self->{maps_counters}->{events} = [ + { label => 'event_frequency', nlabel => 'parity.tracking.event.frequency', set => { + key_values => [ { name => 'event_frequency' } ], + output_template => "Event's frequency: %d (evt/min)", + perfdatas => [ + { label => 'event_frequency', value => 'event_frequency_absolute', template => '%d', min => 0 } + ], + } + } + ]; + + $self->{maps_counters}->{miners} = [ + { label => 'mining_frequency', nlabel => 'parity.tracking.mining.frequency', set => { + key_values => [ { name => 'mining_frequency' } ], + output_template => "Mining frequency: %d (block/min)", + perfdatas => [ + { label => 'mining_frequency', value => 'mining_frequency_absolute', template => '%d', min => 0 } + ], + } + } + ]; + + $self->{maps_counters}->{balances} = [ + { label => 'balance_fluctuation', nlabel => 'parity.tracking.balances.fluctuation', set => { + key_values => [ { name => 'balance_fluctuation' } ], + output_template => "Balance fluctuation: %d (diff/min)", + perfdatas => [ + { label => 'balance_fluctuation', value => 'balance_fluctuation_absolute', template => '%d', min => 0 } + ], + } + } + ]; + +} + +sub prefix_output_events { + my ($self, %options) = @_; + + return "Event stats '"; +} + +sub prefix_output_miners { + my ($self, %options) = @_; + + return "Miner stats '"; +} + +sub prefix_output_balances { + my ($self, %options) = @_; + + return "Balance stats '"; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "parity_ethpoller_" . $self->{mode} . '_' . (defined($self->{option_results}->{hostname}) ? $self->{option_results}->{hostname} : 'me') . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + my $results = $options{custom}->request_api(url_path => '/tracking'); + + # use Data::Dumper; + # print Dumper($results); + + my $res_timestamp = 0; + my $calculated_frequency = 0; + + $self->{events} = {}; + $self->{miners} = {}; + $self->{balances} = {}; + + my $datas = {}; + + foreach my $event (@{$results->{events}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $event->{id} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $event->{id} . "': no matching filter name.", debug => 1); + next; + } + + my $old_event_timestamp = $self->{statefile_cache}->get(name => 'last_event_timestamp'); #get the id last_event_timestamp + my $old_event_count = $self->{statefile_cache}->get(name => 'last_event_count'); #get the id last_event_count + + $datas->{$event->{id}}->{last_event_timestamp} = time(); + $datas->{$event->{id}}->{last_event_count} = $result->{block}->{count}; + + if ($old_event_count && $old_event_timestamp) { + $calculated_frequency = ($event->{count} - $old_event_count) / (time() - $old_event_timestamp); + + $self->{events}->{$event->{id}}->{display} = $event->{label}; + $self->{events}->{$event->{id}}->{event_frequency} = $calculated_frequency; + + $res_timestamp = $event->{timestamp} == 0 ? '': localtime($event->{timestamp}); + + if ($event->{count} > 0) { + $self->{output}->output_add(severity => 'OK', long_msg => 'Event ' . $event->{id} . ': Last Tx from "' . $event->{label} . '" (#' . $event->{count} . + ') was at ' . $res_timestamp . ' (block #' . $event->{block} . ')' ); + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'Event ' . $event->{id} . ': No Tx from "' . $event->{label} . '"'); + } + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'Event ' . $event->{id} . ': Building perfdata for "' . $event->{label} . '"...'); + } + } + + foreach my $miner (@{$results->{miners}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $miner->{id} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $miner->{id} . "': no matching filter name.", debug => 1); + next; + } + + my $old_miner_timestamp = $self->{statefile_cache}->get(name => 'last_miner_timestamp'); #get the id last_miner_timestamp + my $old_miner_count = $self->{statefile_cache}->get(name => 'last_miner_count'); #get the id last_miner_count + + $datas->{$miner->{id}}->{last_miner_timestamp} = time(); + $datas->{$miner->{id}}->{last_miner_count} = $result->{block}->{count}; + + if ($old_miner_timestamp && $old_miner_timestamp) { + $calculated_frequency = ($miner->{count} - $old_miner_count) / (time() - $old_miner_timestamp); + + $self->{miners}->{$miner->{id}}->{display} = $miner->{label}; + $self->{miners}->{$miner->{id}}->{mining_frequency} = $calculated_frequency; + + $res_timestamp = $miner->{timestamp} == 0 ? '': localtime($miner->{timestamp}); + if ($miner->{count} > 0) { + $self->{output}->output_add(severity => 'OK', long_msg => 'Miner ' . $miner->{id} . ': Last block from label "' . $miner->{label} . '" (#' . $miner->{count} . + ') was at ' . $res_timestamp . ' (block #' . $miner->{block} . ')' ); + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'Miner ' . $miner->{id} . ': No validation from "' . $miner->{label} . '"'); + } + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'Miner ' . $miner->{id} . ': Building perfdata for "' . $miner->{label} . '"...'); + } + } + + foreach my $balance (@{$results->{balances}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $balance->{id} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $balance->{id} . "': no matching filter name.", debug => 1); + next; + } + + my $old_balance = $self->{statefile_cache}->get(name => 'last_balance'); #get the id last_balance + + $datas->{$balance->{id}}->{last_balance} = $balance->{balance}; + + if ($old_balance) { + $calculated_diff = ($balance->{balance} - $old_balance) / ($old_balance); + + $self->{balances}->{$balance->{id}}->{display} = $balance->{label}; + $self->{balances}->{$balance->{id}}->{balance} = $calculated_diff; + + $self->{output}->output_add(severity => 'OK', long_msg => 'Balance ' . $balance->{id} . ': Balance of "' . $balance->{label} . '" is ' . $balance->{balance} . ' ether' ); + } else { + $self->{output}->output_add(severity => 'OK', long_msg => 'Balance ' . $balance->{id} . ': Balance fluctuation of "' . $balance->{label} . '" is being calculated...'); + } + } + + +} + +1; + +__END__ + +=head1 MODE + +Check Parity eth-poller for events, miners and balances tracking + +=cut diff --git a/centreon-plugins/blockchain/parity/ethpoller/plugin.pm b/centreon-plugins/blockchain/parity/ethpoller/plugin.pm index 77989acd3..48e08df5c 100644 --- a/centreon-plugins/blockchain/parity/ethpoller/plugin.pm +++ b/centreon-plugins/blockchain/parity/ethpoller/plugin.pm @@ -31,9 +31,11 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'watchlist' => 'blockchain::parity::ethpoller::mode::watchlist', - 'fork' => 'blockchain::parity::ethpoller::mode::fork', - 'stats' => 'blockchain::parity::ethpoller::mode::stats' + # 'watchlist' => 'blockchain::parity::ethpoller::mode::watchlist', + # 'fork' => 'blockchain::parity::ethpoller::mode::fork', + 'stats' => 'blockchain::parity::ethpoller::mode::stats', + 'disk' => 'blockchain::parity::ethpoller::mode::disk', + 'tracking' => 'blockchain::parity::ethpoller::mode::tracking' ); $self->{custom_modes}{api} = 'blockchain::parity::ethpoller::custom::api'; return $self; diff --git a/centreon-plugins/blockchain/parity/restapi/mode/eth.pm b/centreon-plugins/blockchain/parity/restapi/mode/eth.pm index ac872603e..08c7a8461 100644 --- a/centreon-plugins/blockchain/parity/restapi/mode/eth.pm +++ b/centreon-plugins/blockchain/parity/restapi/mode/eth.pm @@ -41,11 +41,23 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', cb_prefix_output => 'prefix_module_output', type => 0 }, + { name => 'gas', cb_prefix_output => 'prefix_module_output', type => 0 }, { name => 'block', cb_prefix_output => 'prefix_module_output', type => 0 }, + { name => 'sync', cb_prefix_output => 'prefix_module_output', type => 0 }, ]; - $self->{maps_counters}->{global} = [ + $self->{maps_counters}->{gas} = [ + { label => 'sync_status', nlabel => 'parity.eth.sync.status', set => { + key_values => [ { name => 'sync_status' } ], + output_template => "The gas price is: %d %% ", + perfdatas => [ + { label => 'sync_status', value => 'sync_status_absolute', template => '%d', min => 0 } + ], + } + } + ]; + + $self->{maps_counters}->{gas} = [ { label => 'gas_price', nlabel => 'parity.eth.gas.price', set => { key_values => [ { name => 'gas_price' } ], output_template => "The gas price is: %d wei ", @@ -53,6 +65,22 @@ sub set_counters { { label => 'gas_price', value => 'gas_price_absolute', template => '%d', min => 0 } ], } + }, + { label => 'gas_used', nlabel => 'parity.eth.gas.used', set => { + key_values => [ { name => 'gas_used' } ], + output_template => "The gas used is: %d", + perfdatas => [ + { label => 'gas_used', value => 'gas_used_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'gas_limit', nlabel => 'parity.eth.gas.limit', set => { + key_values => [ { name => 'gas_limit' } ], + output_template => "The gas limit is: %d", + perfdatas => [ + { label => 'gas_limit', value => 'gas_limit_absolute', template => '%d', min => 0 } + ], + } } ]; @@ -65,6 +93,14 @@ sub set_counters { ], } }, + { label => 'block_usage', nlabel => 'parity.eth.block.usage', set => { + key_values => [ { name => 'block_usage' } ], + output_template => "Block usage: %d %%", + perfdatas => [ + { label => 'block_usage', value => 'block_usage_absolute', template => '%d', min => 0 } + ], + } + }, { label => 'block_transactions', nlabel => 'parity.eth.block.transactions.number', set => { key_values => [ { name => 'block_transactions' } ], output_template => "Block transactions number: %d ", @@ -174,10 +210,16 @@ sub manage_selection { # $cache->set('gas_price', $gas_price); # } - $self->{global} = { gas_price => $gas_price }; + $self->{sync} = { sync_status => $res_sync }; + $self->{gas} = { gas_price => $gas_price, + gas_used => hex(@{$result}[5]->{result}->{gasLimit}), + gas_limit => hex(@{$result}[5]->{result}->{gasUsed}) }; + + my $calculated_block_usage = hex(@{$result}[5]->{result}->{gasUsed}) / hex(@{$result}[5]->{result}->{gasLimit}); $self->{block} = { block_size => hex(@{$result}[5]->{result}->{size}), block_gas => hex(@{$result}[5]->{result}->{gasUsed}), + block_usage => $calculated_block_usage, # block_difficulty => hex(@{$result}[5]->{result}->{totalDifficulty}), block_uncles => scalar(@{$$result[5]->{result}->{uncles}}), block_transactions => scalar(@{$$result[5]->{result}->{transactions}})}; diff --git a/centreon-plugins/blockchain/parity/restapi/mode/infos.pm b/centreon-plugins/blockchain/parity/restapi/mode/infos.pm new file mode 100644 index 000000000..c93eee5ab --- /dev/null +++ b/centreon-plugins/blockchain/parity/restapi/mode/infos.pm @@ -0,0 +1,121 @@ +# +# 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 blockchain::parity::restapi::mode::infos; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'unknown-status:s' => { name => 'unknown_status', default => '' }, + 'warning-status:s' => { name => 'warning_status', default => '' }, + 'critical-status:s' => { name => 'critical_status', default => '%{listening} !~ /true/' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); +} + +sub prefix_module_output { + my ($self, %options) = @_; + + return "Parity network module: "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "parity_restapi_" . $self->{mode} . '_' . (defined($self->{option_results}->{hostname}) ? $self->{option_results}->{hostname} : 'me') . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + my $query_form_post = [ { method => 'parity_versionInfo', params => [], id => "1", jsonrpc => "2.0" }, + { method => 'parity_chain', params => [], id => "2", jsonrpc => "2.0" }, + { method => 'eth_mining', params => [], id => "3", jsonrpc => "2.0" }, + { method => 'parity_nodeName', params => [], id => "4", jsonrpc => "2.0" }, ]; + + my $result = $options{custom}->request_api(method => 'POST', query_form_post => $query_form_post); + + # use Data::Dumper; + # print Dumper($result); + + # Parity version construction + my $res_parity_version = @{$result}[0]->{result}->{version}->{major} . '.' . @{$result}[0]->{result}->{version}->{minor} . '.' . @{$result}[0]->{result}->{version}->{patch}; + + + # Alerts management + # my $cache = Cache::File->new( cache_root => './parity-restapi-cache' ); + + # if (my $cached_count = $cache->get('peers_count')) { + # if ($peer_count < $cached_count) { + # #alert + # } elsif ($peer_count > $cached_count) { + # #alert + # } + # } else { + # $cache->set('peers_count', $peer_count); + # } + + $self->{output}->output_add(long_msg => "Parity version: '" . $res_parity_version . "'. Chain name: '" . @{$result}[1]->{result} . + "'. Node name: '" . @{$result}[3]->{result} . "'. is_validator: '" . @{$result}[2]->{result} . "'.", severity => 'OK'); +} + +1; + +__END__ + +=head1 MODE + +Check parity network cross module metrics (parity_versionInfo, parity_chain, eth_mining, parity_nodeName) + +=over 8 + +=item B<--unknown-status> + +Set unknown threshold for listening status (Default: ''). + +=item B<--warning-status> + +Set warning threshold for listening status (Default: ''). + +=item B<--critical-status> + +Set critical threshold for listening status (Default: '%{listening} !~ /true/'). + +=item B<--warning-peers> B<--critical-peers> + +Warning and Critical threhsold on the number of peer + +=back + +=cut diff --git a/centreon-plugins/blockchain/parity/restapi/mode/net.pm b/centreon-plugins/blockchain/parity/restapi/mode/net.pm index 2ad2ca153..7bc65d3a8 100644 --- a/centreon-plugins/blockchain/parity/restapi/mode/net.pm +++ b/centreon-plugins/blockchain/parity/restapi/mode/net.pm @@ -109,7 +109,7 @@ sub manage_selection { $self->{network} = { peers => hex(@{$result}[1]->{result}) }; - $self->{output}->output_add(long_msg => "Node status: [is_listening: " . $peer_count . ']', severity => 'OK'); + $self->{output}->output_add(long_msg => "Node status: [is_listening: " . @{$result}[0]->{result} . ']', severity => 'OK'); } 1; diff --git a/centreon-plugins/blockchain/parity/restapi/mode/parity.pm b/centreon-plugins/blockchain/parity/restapi/mode/parity.pm index 9da861cb1..7e62fda50 100644 --- a/centreon-plugins/blockchain/parity/restapi/mode/parity.pm +++ b/centreon-plugins/blockchain/parity/restapi/mode/parity.pm @@ -31,15 +31,59 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'mempool', cb_prefix_output => 'prefix_module_output', type => 0 } + { name => 'mempool', cb_prefix_output => 'prefix_module_output', type => 0 }, + { name => 'peers', cb_prefix_output => 'prefix_module_output', type => 0 } ]; $self->{maps_counters}->{mempool} = [ - { label => 'mempool', nlabel => 'parity.mempol.usage', set => { - key_values => [ { name => 'mempool' } ], - output_template => "Mempool: %d %% ", + { label => 'tx_pending', nlabel => 'parity.pending.transactions', set => { + key_values => [ { name => 'tx_pending' } ], + output_template => "Pending transactions: %d", perfdatas => [ - { label => 'mempool', value => 'mempool_absolute', template => '%d', min => 0 } + { label => 'tx_pending', value => 'tx_pending_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'mempool_size', nlabel => 'parity.mempol.size', set => { + key_values => [ { name => 'mempool_size' } ], + output_template => "Mempool size: %d", + perfdatas => [ + { label => 'mempool_size', value => 'mempool_size_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'mempool_usage', nlabel => 'parity.mempol.usage', set => { + key_values => [ { name => 'mempool_usage' } ], + output_template => "Mempool usage: %d %% ", + perfdatas => [ + { label => 'mempool_usage', value => 'mempool_usage_absolute', template => '%d', min => 0 } + ], + } + }, + ]; + + $self->{maps_counters}->{peers} = [ + { label => 'peers_connected', nlabel => 'parity.peers.connected', set => { + key_values => [ { name => 'peers_connected' } ], + output_template => "Peers connected: %d", + perfdatas => [ + { label => 'peers_connected', value => 'peers_connected_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'peers_max', nlabel => 'parity.peers.max', set => { + key_values => [ { name => 'peers_max' } ], + output_template => "Peers max: %d", + perfdatas => [ + { label => 'peers_max', value => 'peers_max_absolute', template => '%d', min => 0 } + ], + } + }, + { label => 'peers_usage', nlabel => 'parity.peers.usage', set => { + key_values => [ { name => 'peers_usage' } ], + output_template => "Mempool usage: %d %% ", + perfdatas => [ + { label => 'peers_usage', value => 'peers_usage_absolute', template => '%d', min => 0 } ], } }, @@ -85,7 +129,8 @@ sub manage_selection { { method => 'parity_netPeers', params => [], id => "4", jsonrpc => "2.0" }, { method => 'parity_enode', params => [], id => "5", jsonrpc => "2.0" }, { method => 'parity_nodeName', params => [], id => "6", jsonrpc => "2.0" }, - { method => 'parity_transactionsLimit', params => [], id => "7", jsonrpc => "2.0" } ]; #TO CHECK parity_transactionsLimit could be done once, at the beginning of the process + { method => 'parity_transactionsLimit', params => [], id => "7", jsonrpc => "2.0" }, #TO CHECK parity_transactionsLimit could be done once, at the beginning of the process + { method => 'net_peerCount', params => [], id => "8", jsonrpc => "2.0" } ]; my $result = $options{custom}->request_api(method => 'POST', query_form_post => $query_form_post); @@ -124,7 +169,13 @@ sub manage_selection { $self->{output}->output_add(long_msg => "Node: [node_name: " . @{$result}[5]->{result} . "] [enode: " . @{$result}[4]->{result} . "]", severity => 'OK'); $self->{output}->output_add(long_msg => "Mempool: [pending_transactions: " . scalar(@{$$result[2]->{result}}) . "] [transactions_limit: " . @{$result}[6]->{result} . "]", severity => 'OK'); - $self->{mempool} = { mempool => scalar(@{$$result[2]->{result}}) / @{$result}[6]->{result} * 100 }; #TO CHECK division entière + $self->{mempool} = { mempool_usage => scalar(@{$$result[2]->{result}}) / @{$result}[6]->{result} * 100, #TO CHECK division entière + mempool_size => @{$result}[6]->{result}, + tx_pending => scalar(@{$$result[2]->{result}}) }; + + $self->{peers} = { peers_usage => @{$result}[3]->{result}->{connected} / @{$result}[3]->{result}->{max} * 100, #TO CHECK division entière + peers_max => @{$result}[3]->{result}->{max}, + peers_connected => @{$result}[3]->{result}->{connected} }; } 1; diff --git a/centreon-plugins/blockchain/parity/restapi/plugin.pm b/centreon-plugins/blockchain/parity/restapi/plugin.pm index 7cffb8686..b470c1666 100644 --- a/centreon-plugins/blockchain/parity/restapi/plugin.pm +++ b/centreon-plugins/blockchain/parity/restapi/plugin.pm @@ -33,7 +33,8 @@ sub new { %{$self->{modes}} = ( 'net' => 'blockchain::parity::restapi::mode::net', 'eth' => 'blockchain::parity::restapi::mode::eth', - 'parity' => 'blockchain::parity::restapi::mode::parity' + 'parity' => 'blockchain::parity::restapi::mode::parity', + 'infos' => 'blockchain::parity::restapi::mode::infos' ); $self->{custom_modes}{api} = 'blockchain::parity::restapi::custom::api'; return $self;