enhance cisco vcs

This commit is contained in:
garnier-quentin 2020-09-25 14:44:30 +02:00
parent c5ae64541d
commit 50ce0c5811
5 changed files with 338 additions and 388 deletions

View File

@ -23,7 +23,7 @@ package network::cisco::vcs::restapi::custom::xmlapi;
use strict;
use warnings;
use centreon::plugins::http;
use XML::Simple;
use XML::LibXML::Simple;
sub new {
my ($class, %options) = @_;
@ -41,13 +41,15 @@ sub new {
if (!defined($options{noptions})) {
$options{options}->add_options(arguments => {
'hostname:s' => { name => 'hostname' },
'url-path:s' => { name => 'url_path' },
'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' },
'username:s' => { name => 'username' },
'password:s' => { name => 'password' },
'timeout:s' => { name => 'timeout' }
'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port' },
'proto:s' => { name => 'proto' },
'api-username:s' => { name => 'api_username' },
'api-password:s' => { name => 'api_password' },
'timeout:s' => { name => 'timeout' },
'unknown-http-status:s' => { name => 'unknown_http_status' },
'warning-http-status:s' => { name => 'warning_http_status' },
'critical-http-status:s' => { name => 'critical_http_status' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'XMLAPI OPTIONS', once => 1);
@ -69,24 +71,26 @@ sub set_defaults {}
sub check_options {
my ($self, %options) = @_;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : '';
$self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443;
$self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https';
$self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef;
$self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef;
$self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/getxml?location=';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10;
$self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : '';
$self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : '';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 20;
$self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300';
$self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : '';
$self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : '';
if (!defined($self->{option_results}->{hostname}) || $self->{option_results}->{hostname} eq '') {
if ($self->{hostname} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --hostname option.");
$self->{output}->option_exit();
}
if (!defined($self->{option_results}->{username}) || $self->{option_results}->{username} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --username option.");
if ($self->{api_username} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --api-username option.");
$self->{output}->option_exit();
}
if (!defined($self->{option_results}->{password}) || $self->{option_results}->{password} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --password option.");
if ($self->{api_password} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --api-password option.");
$self->{output}->option_exit();
}
@ -100,28 +104,19 @@ sub build_options_for_httplib {
$self->{option_results}->{timeout} = $self->{timeout};
$self->{option_results}->{port} = $self->{port};
$self->{option_results}->{proto} = $self->{proto};
$self->{option_results}->{username} = $self->{username};
$self->{option_results}->{password} = $self->{password};
$self->{option_results}->{username} = $self->{api_username};
$self->{option_results}->{password} = $self->{api_password};
$self->{option_results}->{credentials} = 1;
$self->{option_results}->{basic} = 1;
$self->{option_results}->{warning_status} = '';
$self->{option_results}->{critical_status} = '';
}
sub settings {
my ($self, %options) = @_;
$self->build_options_for_httplib();
$self->{http}->set_options(%{$self->{option_results}});
}
sub get_connection_info {
my ($self, %options) = @_;
return $self->{hostname} . ":" . $self->{port};
}
sub get_hostname {
my ($self, %options) = @_;
@ -137,21 +132,23 @@ sub get_port {
sub get_endpoint {
my ($self, %options) = @_;
$self->settings;
my $content = $self->{http}->request(url_path => $self->{url_path} . $options{method});
$self->settings();
my $content = $self->{http}->request(
url_path => $options{endpoint},
unknown_status => $self->{unknown_http_status},
warning_status => $self->{warning_http_status},
critical_status => $self->{critical_http_status}
);
my $xml_result;
eval {
$xml_result = XMLin($content, ForceArray => ['Call', 'Zone'], KeyAttr => []);
$xml_result = XMLin($content, ForceArray => $options{force_array}, KeyAttr => []);
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@");
$self->{output}->option_exit();
}
if (defined($xml_result->{XPathError})) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Api return error: " . $xml_result->{XPathError}->{Reason});
$self->{output}->option_exit();
}
@ -179,10 +176,6 @@ Cisco VCS XML API
API hostname.
=item B<--url-path>
API url path (Default: '/getxml?location=')
=item B<--port>
API port (Default: 443)
@ -191,11 +184,11 @@ API port (Default: 443)
Specify https if needed (Default: 'https')
=item B<--username>
=item B<--api-username>
Set API username
=item B<--password>
=item B<--api-password>
Set API password

View File

@ -24,158 +24,140 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
use Date::Parse;
use Digest::MD5 qw(md5_hex);
sub custom_status_output {
sub prefix_global_output {
my ($self, %options) = @_;
my $msg = sprintf("state is '%s' [Duration: %s s]",
$self->{result_values}->{state}, $self->{result_values}->{duration});
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{serial_number} = $options{new_datas}->{$self->{instance} . '_SerialNumber'};
$self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_State'};
$self->{result_values}->{duration} = $options{new_datas}->{$self->{instance} . '_Duration'};
return 0;
return 'Calls ';
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } },
{ name => 'calls', type => 1, cb_prefix_output => 'prefix_call_output', message_multiple => 'All calls are ok' },
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } }
];
$self->{maps_counters}->{global} = [
{ label => 'traversal', set => {
key_values => [ { name => 'Traversal' } ],
output_template => 'Traversal: %d',
perfdatas => [
{ label => 'traversal', value => 'Traversal', template => '%d',
min => 0, unit => 'calls' },
],
{ label => 'dummy', threshold => 0, display_ok => 0, set => {
key_values => [ { name => 'last_cdr_start_time' } ],
output_template => 'none',
perfdatas => []
}
},
{ label => 'non-traversal', set => {
key_values => [ { name => 'NonTraversal' } ],
output_template => 'Non Traversal: %d',
perfdatas => [
{ label => 'non_traversal', value => 'NonTraversal', template => '%d',
min => 0, unit => 'calls' },
],
}
},
{ label => 'collaboration-edge', set => {
key_values => [ { name => 'CollaborationEdge' } ],
output_template => 'Collaboration Edge: %d',
perfdatas => [
{ label => 'collaboration_edge', value => 'CollaborationEdge', template => '%d',
min => 0, unit => 'calls' },
],
}
},
{ label => 'cloud', set => {
key_values => [ { name => 'Cloud' } ],
output_template => 'Cloud: %d',
perfdatas => [
{ label => 'cloud', value => 'Cloud', template => '%d',
min => 0, unit => 'calls' },
],
}
},
{ label => 'microsoft-content', set => {
key_values => [ { name => 'MicrosoftContent' } ],
output_template => 'Microsoft Content: %d',
perfdatas => [
{ label => 'microsoft_content', value => 'MicrosoftContent', template => '%d',
min => 0, unit => 'calls' },
],
}
},
{ label => 'microsoft-imp', set => {
key_values => [ { name => 'MicrosoftIMP' } ],
output_template => 'Microsoft IMP: %d',
perfdatas => [
{ label => 'microsoft_imp', value => 'MicrosoftIMP', template => '%d',
min => 0, unit => 'calls' },
],
}
},
}
];
$self->{maps_counters}->{calls} = [
{ label => 'status', set => {
key_values => [ { name => 'State' }, { name => 'Duration' }, { name => 'SerialNumber' } ],
closure_custom_calc => $self->can('custom_status_calc'),
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold,
}
},
];
}
sub prefix_global_output {
my ($self, %options) = @_;
foreach ((
['traversal', 1, 'traversal'], ['nontraversal', 1, 'non traversal'],
['cloud', 1, 'cloud'], ['collaborationedge', 0, 'collaboration edge'],
['microsoftcontent', 0, 'microsoft content'], ['microsoftimp', 0, 'microsoft imp']
)) {
push @{$self->{maps_counters}->{global}},
{
label => $_->[0] . '-current', nlabel => 'calls.' . $_->[0] . '.current.count', display_ok => $_->[1], set => {
key_values => [ { name => $_->[0] . '_current' } ],
output_template => $_->[2] . ' current: %d',
perfdatas => [
{ template => '%d', min => 0 }
]
}
},
{
label => $_->[0] . '-total', nlabel => 'calls.' . $_->[0] . '.total.count', display_ok => 0, set => {
key_values => [ { name => $_->[0] . '_total', diff => 1 } ],
output_template => $_->[2] . ' total: %d',
perfdatas => [
{ template => '%d', min => 0 }
]
}
};
}
return "Number of Calls ";
}
sub prefix_call_output {
my ($self, %options) = @_;
return "Call '" . $options{instance_value}->{SerialNumber} . "' ";
foreach ((
['connectionfailed', 1, 'connection failed'], ['disconnected', 1, 'disconnected']
)) {
push @{$self->{maps_counters}->{global}}, {
label => $_->[0] . '-total', nlabel => 'calls.' . $_->[0] . '.total.count', display_ok => $_->[1], set => {
key_values => [ { name => $_->[0] } ],
output_template => $_->[2] . ': %d',
perfdatas => [
{ template => '%d', min => 0 }
]
}
};
}
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments =>
{
"warning-status:s" => { name => 'warning_status' },
"critical-status:s" => { name => 'critical_status', default => '%{state} ne "Connected"' },
});
$options{options}->add_options(arguments => {
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->change_macros(macros => ['warning_status', 'critical_status']);
}
sub manage_selection {
my ($self, %options) = @_;
my $usages = $options{custom}->get_endpoint(method => '/Status/ResourceUsage/Calls');
$self->{cache_name} = 'cisco_vcs_' . $options{custom}->get_hostname() . '_' . $options{custom}->get_port() . '_' . $self->{mode} . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
$self->{global}->{Traversal} = $usages->{ResourceUsage}->{Calls}->{Traversal}->{Current}->{content};
$self->{global}->{NonTraversal} = $usages->{ResourceUsage}->{Calls}->{NonTraversal}->{Current}->{content};
$self->{global}->{CollaborationEdge} = $usages->{ResourceUsage}->{Calls}->{CollaborationEdge}->{Current}->{content};
$self->{global}->{Cloud} = $usages->{ResourceUsage}->{Calls}->{Cloud}->{Current}->{content};
$self->{global}->{MicrosoftContent} = $usages->{ResourceUsage}->{Calls}->{MicrosoftContent}->{Current}->{content};
$self->{global}->{MicrosoftIMP} = $usages->{ResourceUsage}->{Calls}->{MicrosoftIMP}->{Current}->{content};
my $calls = $options{custom}->get_endpoint(
endpoint => '/getxml?location=/Status/ResourceUsage/Calls'
);
my $results = $options{custom}->get_endpoint(method => '/Status/Calls');
$self->{global} = {
traversal_current => $calls->{ResourceUsage}->{Calls}->{Traversal}->{Current}->{content},
traversal_total => $calls->{ResourceUsage}->{Calls}->{Traversal}->{Total}->{content},
nontraversal_current => $calls->{ResourceUsage}->{Calls}->{NonTraversal}->{Current}->{content},
nontraversal_total => $calls->{ResourceUsage}->{Calls}->{NonTraversal}->{Total}->{content},
cloud_current => $calls->{ResourceUsage}->{Calls}->{Cloud}->{Current}->{content},
cloud_total => $calls->{ResourceUsage}->{Calls}->{Cloud}->{Total}->{content},
collaborationedge_current => $calls->{ResourceUsage}->{Calls}->{CollaborationEdge}->{Current}->{content},
collaborationedge_total => $calls->{ResourceUsage}->{Calls}->{CollaborationEdge}->{Total}->{content},
microsoftcontent_current => $calls->{ResourceUsage}->{Calls}->{MicrosoftContent}->{Current}->{content},
microsoftcontent_total => $calls->{ResourceUsage}->{Calls}->{MicrosoftContent}->{Total}->{content},
microsoftimp_current => $calls->{ResourceUsage}->{Calls}->{MicrosoftIMP}->{Current}->{content},
microsoftimp_total => $calls->{ResourceUsage}->{Calls}->{MicrosoftIMP}->{Total}->{content},
connectionfailed => 0,
disconnected => 0
};
$self->{calls} = {};
my $last_cdr_start_time = $self->read_statefile_key(key => 'global_last_cdr_start_time');
$last_cdr_start_time = 0 if (!defined($last_cdr_start_time));
my $results = $options{custom}->get_endpoint(
endpoint => '/history.xml?location=/Calls',
force_array => ['Call']
);
#<StartTime item="1">2020-09-24 12:28:52.267179</StartTime>
my $max_start_time = $last_cdr_start_time;
foreach my $call (@{$results->{Calls}->{Call}}) {
next if (!defined($call->{SerialNumber}));
$self->{calls}->{$call->{SerialNumber}->{content}} = {
SerialNumber => $call->{SerialNumber}->{content},
Duration => $call->{Duration}->{content},
State => $call->{State}->{content},
};
my $tmp_time = Date::Parse::str2time($call->{StartTime}->{content});
if (!defined($tmp_time)) {
$self->{output}->output_add(
severity => 'UNKNOWN',
short_msg => "can't parse date '" . $call->{StartTime}->{content} . "'"
);
next;
}
$tmp_time = int($tmp_time * 10000);
$max_start_time = $tmp_time if ($max_start_time < $tmp_time);
if ($tmp_time > $last_cdr_start_time) {
$call->{State}->{content} =~ s/\s+//g;
$self->{global}->{ lc($call->{State}->{content}) }++
if (defined($self->{global}->{ lc($call->{State}->{content}) }));
}
}
$self->{global}->{last_cdr_start_time} = $max_start_time;
}
1;
@ -184,31 +166,20 @@ __END__
=head1 MODE
Check calls count and state.
Check current calls and history.
=over 8
=item B<--warning-*>
=item B<--warning-*> B<--critical-*>
Threshold warning.
Can be: 'traversal', 'non-traversal', 'collaboration-edge',
'cloud', 'microsoft-content', 'microsoft-imp'.
=item B<--critical-*>
Threshold critical.
Can be: 'traversal', 'non-traversal', 'collaboration-edge',
'cloud', 'microsoft-content', 'microsoft-imp'.
=item B<--warning-status>
Set warning threshold for status. (Default: '').
Can use special variables like: %{state}, %{serial_number}, %{duration}.
=item B<--critical-status>
Set critical threshold for status. (Default: '%{state} ne "Connected"').
Can use special variables like: %{state}, %{serial_number}, %{duration}.
Thresholds.
Can be: 'traversal-current', 'traversal-total',
'nontraversal-current', 'nontraversal-total',
'cloud-current', 'cloud-total', '
'collaborationedge-current', 'collaborationedge-total',
'microsoftcontent-current', 'microsoftcontent-total',
'microsoftimp-current', 'microsoftimp-total',
'connectionfailed-total', 'disconnected-total'.
=back

View File

@ -25,20 +25,33 @@ 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);
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_status_output {
my ($self, %options) = @_;
my $msg = sprintf("Status is '%s'", $self->{result_values}->{status});
return $msg;
return sprintf(
"http proxy status is '%s'",
$self->{result_values}->{status}
);
}
sub custom_status_calc {
sub prefix_connections_output {
my ($self, %options) = @_;
$self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_Status'};
return 0;
return 'Connections ';
}
sub prefix_requests_output {
my ($self, %options) = @_;
return 'Resquests ';
}
sub prefix_responses_output {
my ($self, %options) = @_;
return 'Responses ';
}
sub set_counters {
@ -48,170 +61,150 @@ sub set_counters {
{ name => 'global', type => 0 },
{ name => 'connections', type => 0, cb_prefix_output => 'prefix_connections_output' },
{ name => 'requests', type => 0, cb_prefix_output => 'prefix_requests_output' },
{ name => 'responses', type => 0, cb_prefix_output => 'prefix_responses_output' },
{ name => 'responses', type => 0, cb_prefix_output => 'prefix_responses_output' }
];
$self->{maps_counters}->{global} = [
{ label => 'status', set => {
key_values => [ { name => 'Status' } ],
closure_custom_calc => $self->can('custom_status_calc'),
{ label => 'status', type => 2, critical_default => '%{status} ne "Active"',set => {
key_values => [ { name => 'status' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold,
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
}
];
$self->{maps_counters}->{connections} = [
{ label => 'client-connections', set => {
key_values => [ { name => 'TotalClientConnection', per_second => 1 } ],
output_template => 'Client: %.2f/s',
{ label => 'connections-client', nlabel => 'httproxy.connections.client.persecond', set => {
key_values => [ { name => 'total_client_connection', per_second => 1 } ],
output_template => 'client: %.2f/s',
perfdatas => [
{ label => 'client_connections', template => '%.2f', min => 0, unit => 'connections/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'server-connections', set => {
key_values => [ { name => 'TotalServerConnection', per_second => 1 } ],
output_template => 'Server: %.2f/s',
{ label => 'connections-server', nlabel => 'httproxy.connections.server.persecond', set => {
key_values => [ { name => 'total_server_connection', per_second => 1 } ],
output_template => 'server: %.2f/s',
perfdatas => [
{ label => 'server_connections', template => '%.2f', min => 0, unit => 'connections/s' },
],
{ template => '%.2f', min => 0 }
]
}
}
];
$self->{maps_counters}->{requests} = [
{ label => 'completed-requests', set => {
key_values => [ { name => 'CompletedRequests', per_second => 1 } ],
output_template => 'Completed: %.2f/s',
{ label => 'requests-completed', nlabel => 'httproxy.requests.completed.persecond', set => {
key_values => [ { name => 'completed', per_second => 1 } ],
output_template => 'completed: %.2f/s',
perfdatas => [
{ label => 'completed_requests', template => '%.2f', min => 0, unit => 'requests/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'get-requests', set => {
key_values => [ { name => 'GetRequests', per_second => 1 } ],
output_template => 'Get: %.2f/s',
{ label => 'requests-get', nlabel => 'httproxy.requests.get.persecond', set => {
key_values => [ { name => 'get', per_second => 1 } ],
output_template => 'get: %.2f/s',
perfdatas => [
{ label => 'get_requests', template => '%.2f', min => 0, unit => 'requests/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'post-requests', set => {
key_values => [ { name => 'PostRequests', per_second => 1 } ],
output_template => 'Post: %.2f/s',
{ label => 'requests-post', nlabel => 'httproxy.requests.post.persecond', set => {
key_values => [ { name => 'post', per_second => 1 } ],
output_template => 'post: %.2f/s',
perfdatas => [
{ label => 'post_requests', template => '%.2f', min => 0, unit => 'requests/s' },
],
{ template => '%.2f', min => 0 }
]
}
}
];
$self->{maps_counters}->{responses} = [
{ label => 'responses-1xx', set => {
key_values => [ { name => 'Response1XXCount', per_second => 1 } ],
output_template => '1XX: %.2f/s',
{ label => 'responses-1xx', nlabel => 'httproxy.responses.1xx.persecond', set => {
key_values => [ { name => 'response1xxx', per_second => 1 } ],
output_template => '1xx: %.2f/s',
perfdatas => [
{ label => 'responses_1xx', template => '%.2f', min => 0, unit => 'responses/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'responses-2xx', set => {
key_values => [ { name => 'Response2XXCount', per_second => 1 } ],
output_template => '2XX: %.2f/s',
{ label => 'responses-2xx', nlabel => 'httproxy.responses.2xx.persecond', set => {
key_values => [ { name => 'response2xxx', per_second => 1 } ],
output_template => '2xx: %.2f/s',
perfdatas => [
{ label => 'responses_2xx', template => '%.2f', min => 0, unit => 'responses/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'responses-3xx', set => {
key_values => [ { name => 'Response3XXCount', per_second => 1 } ],
output_template => '3XX: %.2f/s',
{ label => 'responses-3xx', nlabel => 'httproxy.responses.3xx.persecond', set => {
key_values => [ { name => 'response3xxx', per_second => 1 } ],
output_template => '3xx: %.2f/s',
perfdatas => [
{ label => 'responses_3xx', template => '%.2f', min => 0, unit => 'responses/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'responses-4xx', set => {
key_values => [ { name => 'Response4XXCount', per_second => 1 } ],
output_template => '4XX: %.2f/s',
{ label => 'responses-4xx', nlabel => 'httproxy.responses.4xx.persecond', set => {
key_values => [ { name => 'response4xxx', per_second => 1 } ],
output_template => '4xx: %.2f/s',
perfdatas => [
{ label => 'responses_4xx', template => '%.2f', min => 0, unit => 'responses/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'responses-5xx', set => {
key_values => [ { name => 'Response5XXCount', per_second => 1 } ],
output_template => '5XX: %.2f/s',
{ label => 'responses-5xx', nlabel => 'httproxy.responses.5xx.persecond', set => {
key_values => [ { name => 'response5xxx', per_second => 1 } ],
output_template => '5xx: %.2f/s',
perfdatas => [
{ label => 'responses_5xx', template => '%.2f', min => 0, unit => 'responses/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
}
];
}
sub prefix_connections_output {
my ($self, %options) = @_;
return "Connections ";
}
sub prefix_requests_output {
my ($self, %options) = @_;
return "Resquests ";
}
sub prefix_responses_output {
my ($self, %options) = @_;
return "Responses ";
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'warning-status:s' => { name => 'warning_status' },
'critical-status:s' => { name => 'critical_status', default => '%{status} ne "Active"' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->change_macros(macros => ['warning_status', 'critical_status']);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->get_endpoint(method => '/Status/HTTPProxy');
my $results = $options{custom}->get_endpoint(
endpoint => '/getxml?location=/Status/HTTPProxy'
);
$self->{global} = {};
$self->{connections} = {};
$self->{requests} = {};
$self->{responses} = {};
$self->{global} = {
status => $results->{HTTPProxy}->{Status}->{content}
};
if (defined($results->{HTTPProxy}->{Stats})) {
$self->{connections} = {
total_client_connection => $results->{HTTPProxy}->{Stats}->{TotalClientConnection}->{content},
total_server_connection => $results->{HTTPProxy}->{Stats}->{TotalServerConnection}->{content}
};
$self->{requests} = {
completed => $results->{HTTPProxy}->{Stats}->{CompletedRequests}->{content},
get => $results->{HTTPProxy}->{Stats}->{GetRequests}->{content},
post => $results->{HTTPProxy}->{Stats}->{PostRequests}->{content}
};
$self->{responses} = {
response1xxx => $results->{HTTPProxy}->{Stats}->{Response1XXCount}->{content},
response2xxx => $results->{HTTPProxy}->{Stats}->{Response2XXCount}->{content},
response3xxx => $results->{HTTPProxy}->{Stats}->{Response3XXCount}->{content},
response4xxx => $results->{HTTPProxy}->{Stats}->{Response4XXCount}->{content},
response5xxx => $results->{HTTPProxy}->{Stats}->{Response5XXCount}->{content}
};
}
$self->{global}->{Status} = $results->{HTTPProxy}->{Status}->{content};
$self->{connections}->{TotalClientConnection} = $results->{HTTPProxy}->{Stats}->{TotalClientConnection}->{content};
$self->{connections}->{TotalServerConnection} = $results->{HTTPProxy}->{Stats}->{TotalServerConnection}->{content};
$self->{requests}->{CompletedRequests} = $results->{HTTPProxy}->{Stats}->{CompletedRequests}->{content};
$self->{requests}->{GetRequests} = $results->{HTTPProxy}->{Stats}->{GetRequests}->{content};
$self->{requests}->{PostRequests} = $results->{HTTPProxy}->{Stats}->{PostRequests}->{content};
$self->{responses}->{Response1XXCount} = $results->{HTTPProxy}->{Stats}->{Response1XXCount}->{content};
$self->{responses}->{Response2XXCount} = $results->{HTTPProxy}->{Stats}->{Response2XXCount}->{content};
$self->{responses}->{Response3XXCount} = $results->{HTTPProxy}->{Stats}->{Response3XXCount}->{content};
$self->{responses}->{Response4XXCount} = $results->{HTTPProxy}->{Stats}->{Response4XXCount}->{content};
$self->{responses}->{Response5XXCount} = $results->{HTTPProxy}->{Stats}->{Response5XXCount}->{content};
$self->{cache_name} = "cisco_vcs_" . $options{custom}->get_hostname() . '_' . $options{custom}->get_port() . '_' . $self->{mode} . '_' .
$self->{cache_name} = 'cisco_vcs_' . $options{custom}->get_hostname() . '_' . $options{custom}->get_port() . '_' . $self->{mode} . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
}
@ -230,28 +223,21 @@ Check HTTP proxy status and statistics.
Only display some counters (regexp can be used).
(Example: --filter-counters='responses')
=item B<--warning-*>
=item B<--warning-*> B<--critical-*>
Threshold warning (/s).
Can be: 'client-connections', 'server-connections', 'completed-requests',
'get-requests', 'post-requests', 'responses-1xx', 'responses-2xx',
'responses-3xx', 'responses-4xx', 'responses-5xx'.
=item B<--critical-*>
Threshold critical (/s).
Can be: 'client-connections', 'server-connections', 'completed-requests',
'get-requests', 'post-requests', 'responses-1xx', 'responses-2xx',
'responses-3xx', 'responses-4xx', 'responses-5xx'.
Threshold.
Can be: 'connections-client', 'connections-server',
'requests-completed', 'requests-get', 'requests-post',
'responses-1xx', 'responses-2xx', 'responses-3xx', 'responses-4xx', 'responses-5xx'.
=item B<--warning-status>
Set warning threshold for status. (Default: '').
Set warning threshold for status.
Can use special variables like: %{status}.
=item B<--critical-status>
Set critical threshold for status. (Default: '%{status} ne "Active"').
Set critical threshold for status (Default: '%{status} ne "Active"').
Can use special variables like: %{status}.
=back

View File

@ -25,14 +25,15 @@ 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);
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_status_output {
my ($self, %options) = @_;
my $msg = sprintf("Status is '%s' [Type: %s]",
$self->{result_values}->{status}, $self->{result_values}->{type});
return $msg;
return sprintf(
"status is '%s' [type: %s]",
$self->{result_values}->{status}, $self->{result_values}->{type}
);
}
sub custom_status_calc {
@ -44,142 +45,143 @@ sub custom_status_calc {
return 0;
}
sub prefix_searches_output {
my ($self, %options) = @_;
return 'Searches ';
}
sub prefix_zones_output {
my ($self, %options) = @_;
return "Zone '" . $options{instance_value}->{name} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0},
{ name => 'searches', type => 0, cb_prefix_output => 'prefix_searches_output' },
{ name => 'zones', type => 1, cb_prefix_output => 'prefix_zones_output', message_multiple => 'All zones are ok' },
{ name => 'zones', type => 1, cb_prefix_output => 'prefix_zones_output', message_multiple => 'All zones are ok' }
];
$self->{maps_counters}->{global} = [
{ label => 'zones-count', set => {
{ label => 'zones-count', nlabel => 'zones.total.count', set => {
key_values => [ { name => 'count' } ],
output_template => 'Number of zones: %d',
perfdatas => [
{ label => 'zones_count', template => '%d', min => 0 }
{ template => '%d', min => 0 }
]
}
}
];
$self->{maps_counters}->{searches} = [
{ label => 'searches-total', set => {
key_values => [ { name => 'Total', per_second => 1 } ],
output_template => 'Total: %.2f/s',
{ label => 'searches-total', nlabel => 'zones.searches.total.persecond', set => {
key_values => [ { name => 'total', per_second => 1 } ],
output_template => 'total: %.2f/s',
perfdatas => [
{ label => 'searches_total', template => '%.2f', min => 0, unit => 'searches/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'searches-dropped', set => {
key_values => [ { name => 'Dropped', per_second => 1 } ],
output_template => 'Dropped: %.2f/s',
{ label => 'searches-dropped', nlabel => 'zones.searches.dropped.persecond', set => {
key_values => [ { name => 'dropped', per_second => 1 } ],
output_template => 'dropped: %.2f/s',
perfdatas => [
{ label => 'searches_dropped', template => '%.2f', min => 0, unit => 'searches/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'searches-max-sub-search-exceeded', set => {
key_values => [ { name => 'MaxSubSearchExceeded', per_second => 1 } ],
output_template => 'Max Sub Search Exceeded: %.2f/s',
{ label => 'searches-maxsub-exceeded', nlabel => 'zones.searches.maxsub.exceeded.count', set => {
key_values => [ { name => 'max_sub_search_exceeded', diff => 1 } ],
output_template => 'max sub exceeded: %s',
perfdatas => [
{ label => 'searches_max_sub_search_exceeded', template => '%.2f',
min => 0, unit => 'searches/s' },
],
{ template => '%.2f', min => 0 }
]
}
},
{ label => 'searches-max-targets-exceeded', set => {
key_values => [ { name => 'MaxTargetsExceeded', per_second => 1 } ],
output_template => 'Max Targets Exceeded: %.2f/s',
{ label => 'searches-maxtargets-exceeded', nlabel => 'zones.searches.maxtargets.exceeded.count', set => {
key_values => [ { name => 'max_targets_exceeded', diff => 1 } ],
output_template => 'max targets exceeded: %s',
perfdatas => [
{ label => 'searches_max_targets_exceeded', template => '%.2f', min => 0, unit => 'searches/s' },
],
{ template => '%s', min => 0 }
]
}
}
];
$self->{maps_counters}->{zones} = [
{ label => 'status', set => {
key_values => [ { name => 'Status' }, { name => 'Type' }, { name => 'Name' } ],
closure_custom_calc => $self->can('custom_status_calc'),
{ label => 'status', type => 2, critical_default => '%{status} ne "Active"', set => {
key_values => [ { name => 'status' }, { name => 'type' }, { name => 'name' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'calls-count', set => {
key_values => [ { name => 'Calls' }, { name => 'Name' } ],
output_template => 'Number of Calls: %d',
{ label => 'zone-calls-current', nlabel => 'zone.calls.current.count', set => {
key_values => [ { name => 'calls' } ],
output_template => 'current calls: %d',
perfdatas => [
{ label => 'calls_count', template => '%d', min => 0, label_extra_instance => 1, instance_use => 'Name' }
{ template => '%d', min => 0, label_extra_instance => 1 }
]
}
}
];
}
sub prefix_searches_output {
my ($self, %options) = @_;
return "Searches ";
}
sub prefix_zones_output {
my ($self, %options) = @_;
return "Zone '" . $options{instance_value}->{Name} . "' ";
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'warning-status:s' => { name => 'warning_status' },
'critical-status:s' => { name => 'critical_status', default => '%{status} ne "Active"' }
'filter-zone-name:s' => { name => 'filter_zone_name' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->change_macros(macros => ['warning_status', 'critical_status']);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->get_endpoint(method => '/Status/Zones');
my $results = $options{custom}->get_endpoint(
endpoint => '/getxml?location=/Status/Zones',
force_array => ['Zone', 'Call']
);
$self->{global}->{count} = 0;
$self->{searches} = {};
$self->{zones} = {};
$self->{searches}->{Total} = $results->{Zones}->{Searches}->{Total}->{content};
$self->{searches}->{Dropped} = $results->{Zones}->{Searches}->{Dropped}->{content};
$self->{searches}->{MaxSubSearchExceeded} = $results->{Zones}->{Searches}->{MaxSubSearchExceeded}->{content};
$self->{searches}->{MaxTargetsExceeded} = $results->{Zones}->{Searches}->{MaxTargetsExceeded}->{content};
$self->{searches} = {
total => $results->{Zones}->{Searches}->{Total}->{content},
dropped => $results->{Zones}->{Searches}->{Dropped}->{content},
max_sub_search_exceeded => $results->{Zones}->{Searches}->{MaxSubSearchExceeded}->{content},
max_targets_exceeded => $results->{Zones}->{Searches}->{MaxTargetsExceeded}->{content}
};
$self->{zones} = {};
foreach my $zone (@{$results->{Zones}->{Zone}}) {
next if (!defined($zone->{Name}));
$self->{zones}->{$zone->{Name}->{content}} = {
Type => $zone->{Type}->{content},
Name => $zone->{Name}->{content},
Calls => (defined($zone->{Calls})) ? scalar(@{$zone->{Calls}->{Call}}) : 0,
Status => $zone->{Status}->{content},
if (defined($self->{option_results}->{filter_zone_name}) && $self->{option_results}->{filter_zone_name} ne '' &&
$zone->{Name}->{content} !~ /$self->{option_results}->{filter_zone_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $zone->{Name}->{content} . "': no matching filter vserver.", debug => 1);
next;
}
$self->{zones}->{ $zone->{Name}->{content} } = {
type => $zone->{Type}->{content},
name => $zone->{Name}->{content},
calls => (defined($zone->{Calls})) ? scalar(@{$zone->{Calls}->{Call}}) : 0,
status => $zone->{Status}->{content}
};
$self->{global}->{count}++;
}
$self->{cache_name} = "cisco_vcs_" . $options{custom}->get_hostname() . '_' . $options{custom}->get_port() . '_' . $self->{mode} . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
$self->{cache_name} = 'cisco_vcs_' . $options{custom}->get_hostname() . '_' . $options{custom}->get_port() . '_' . $self->{mode} . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' .
(defined($self->{option_results}->{filter_zone_name}) ? md5_hex($self->{option_results}->{filter_zone_name}) : md5_hex('all'))
}
1;
@ -188,21 +190,19 @@ __END__
=head1 MODE
Check zones count and state.
Check zones.
=over 8
=item B<--warning-*>
=item B<--filter-zone-name>
Threshold warning.
Can be: 'zones-count', 'calls-count', 'searches-total' (/s), 'searches-dropped' (/s),
'searches-max-sub-search-exceeded' (/s), 'searches-max-targets-exceeded' (/s).
Filter zones by name (can be a regexp).
=item B<--critical-*>
=item B<--warning-*> B<--critical-*>
Threshold critical.
Can be: 'zones-count', 'calls-count', 'searches-total' (/s), 'searches-dropped' (/s),
'searches-max-sub-search-exceeded' (/s), 'searches-max-targets-exceeded' (/s).
Thresholds.
Can be: 'zones-count', 'zone-calls-current', 'searches-total',
'searches-dropped', 'searches-maxsub-exceeded', 'searches-maxtargets-exceeded'.
=item B<--warning-status>

View File

@ -30,13 +30,13 @@ sub new {
bless $self, $class;
$self->{version} = '1.0';
%{$self->{modes}} = (
$self->{modes} = {
'calls' => 'network::cisco::vcs::restapi::mode::calls',
'http-proxy-stats' => 'network::cisco::vcs::restapi::mode::httpproxystats',
'zones' => 'network::cisco::vcs::restapi::mode::zones',
);
'zones' => 'network::cisco::vcs::restapi::mode::zones'
};
$self->{custom_modes}{xmlapi} = 'network::cisco::vcs::restapi::custom::xmlapi';
$self->{custom_modes}->{xmlapi} = 'network::cisco::vcs::restapi::custom::xmlapi';
return $self;
}