Enhance exchange (#2269)

This commit is contained in:
qgarnier 2020-10-20 17:14:08 +02:00 committed by GitHub
parent becca7e330
commit 3af2d6554a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 497 additions and 334 deletions

View File

@ -20,16 +20,239 @@
package apps::exchange::2010::local::mode::databases;
use base qw(centreon::plugins::mode);
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::misc;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::common::powershell::exchange::2010::databases;
use apps::exchange::2010::local::mode::resources::types qw($copystatus_contentindexstate);
use JSON::XS;
sub custom_mailflow_latency_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel},
unit => 's',
instances => [$self->{result_values}->{server}, $self->{result_values}->{database}],
value => sprintf('%.3f', $self->{result_values}->{mailflow_latency}),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel})
);
}
sub custom_space_size_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel},
unit => 'B',
instances => [$self->{result_values}->{server}, $self->{result_values}->{database}],
value => $self->{result_values}->{size},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel})
);
}
sub custom_space_available_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel},
unit => 'B',
instances => [$self->{result_values}->{server}, $self->{result_values}->{database}],
value => $self->{result_values}->{asize},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel})
);
}
sub custom_mapi_output {
my ($self, %options) = @_;
return 'mapi test connectivity is ' . $self->{result_values}->{mapi_result};
}
sub custom_mailflow_output {
my ($self, %options) = @_;
return 'mapi test result is ' . $self->{result_values}->{mailflow_result};
}
sub custom_copystatus_output {
my ($self, %options) = @_;
return sprintf(
"copystatus state is %s [error: %s]",
$self->{result_values}->{copystatus_indexstate},
$self->{result_values}->{copystatus_content_index_error_message}
);
}
sub custom_status_output {
my ($self, %options) = @_;
return sprintf(
'%s mounted',
$self->{result_values}->{mounted} == 0 ? 'not' : 'is'
);
}
sub database_long_output {
my ($self, %options) = @_;
return "checking database '" . $options{instance_value}->{database} . "' server '" . $options{instance_value}->{server} . "'";
}
sub prefix_database_output {
my ($self, %options) = @_;
return "Database '" . $options{instance_value}->{database} . "' server '" . $options{instance_value}->{server} . "'";
}
sub prefix_mailflow_output {
my ($self, %options) = @_;
return 'mailflow ';
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Databases ';
}
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 => 'databases', type => 3, cb_prefix_output => 'prefix_database_output', cb_long_output => 'database_long_output', indent_long_output => ' ', message_multiple => 'All databases are ok',
group => [
{ name => 'db_global', type => 0, skipped_code => { -10 => 1 } },
{ name => 'space', type => 0, skipped_code => { -10 => 1 } },
{ name => 'mapi', type => 0, skipped_code => { -10 => 1 } },
{ name => 'mailflow', type => 0, cb_prefix_output => 'prefix_mailflow_output', skipped_code => { -10 => 1 } },
{ name => 'copystatus', type => 0, skipped_code => { -10 => 1 } },
]
}
];
$self->{maps_counters}->{global} = [
{ label => 'databases-space-size', nlabel => 'databases.space.size.bytes', set => {
key_values => [ { name => 'size' } ],
output_template => 'space size: %s %s',
output_change_bytes => 1,
perfdatas => [
{ template => '%d', unit => 'B', min => 0 }
]
}
},
{ label => 'databases-space-available', nlabel => 'databases.space.available.bytes', set => {
key_values => [ { name => 'asize' } ],
output_template => 'space available: %s %s',
output_change_bytes => 1,
perfdatas => [
{ template => '%d', unit => 'B', min => 0 }
]
}
}
];
$self->{maps_counters}->{db_global} = [
{
label => 'status',
type => 2,
critical_default => '%{mounted} == 0',
set => {
key_values => [
{ name => 'mounted' }, { name => 'database' }, { name => 'server' }
],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
$self->{maps_counters}->{space} = [
{ label => 'database-space-size', nlabel => 'database.space.size.bytes', set => {
key_values => [ { name => 'size' }, { name => 'database' }, { name => 'server' } ],
output_template => 'space size: %s %s',
output_change_bytes => 1,
closure_custom_perfdata => $self->can('custom_space_size_perfdata')
}
},
{ label => 'database-space-available', nlabel => 'database.space.available.bytes', set => {
key_values => [ { name => 'asize' }, { name => 'database' }, { name => 'server' } ],
output_template => 'space available: %s %s',
output_change_bytes => 1,
closure_custom_perfdata => $self->can('custom_space_asize_perfdata')
}
}
];
$self->{maps_counters}->{mapi} = [
{
label => 'mapi',
type => 2,
critical_default => '%{mapi_result} !~ /Success/i',
set => {
key_values => [
{ name => 'mapi_result' }, { name => 'database' }, { name => 'server' }
],
closure_custom_output => $self->can('custom_mapi_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
$self->{maps_counters}->{mailflow} = [
{
label => 'mailflow',
type => 2,
critical_default => '%{mailflow_result} !~ /Success/i',
set => {
key_values => [
{ name => 'mailflow_result' }, { name => 'database' }, { name => 'server' }
],
closure_custom_output => $self->can('custom_mailflow_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'mailflow-latency', nlabel => 'database.mailflow.latency.seconds', display_ok => 0, set => {
key_values => [ { name => 'mailflow_latency' }, { name => 'database' }, { name => 'server' } ],
output_template => 'latency: %.3f %%',
closure_custom_perfdata => $self->can('custom_mailflow_latency_perfdata')
}
}
];
$self->{maps_counters}->{copystatus} = [
{
label => 'copystatus',
type => 2,
critical_default => '%{copystatus_indexstate} !~ /Healthy/i',
set => {
key_values => [
{ name => 'copystatus_indexstate' }, { name => 'copystatus_content_index_error_message' },
{ name => 'database' }, { name => 'server' }
],
closure_custom_output => $self->can('custom_copystatus_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
@ -47,36 +270,13 @@ sub new {
'ps-exec-only' => { name => 'ps_exec_only' },
'ps-display' => { name => 'ps_display' },
'ps-database-filter:s' => { name => 'ps_database_filter' },
'ps-database-test-filter:s' => { name => 'ps_database_test_filter' },
'warning-mapi:s' => { name => 'warning_mapi' },
'critical-mapi:s' => { name => 'critical_mapi', default => '%{mapi_result} !~ /Success/i' },
'warning-mailflow:s' => { name => 'warning_mailflow' },
'critical-mailflow:s' => { name => 'critical_mailflow', default => '%{mailflow_result} !~ /Success/i' },
'warning-copystatus:s' => { name => 'warning_copystatus' },
'critical-copystatus:s' => { name => 'critical_copystatus', default => '%{copystatus_indexstate} !~ /Healthy/i' },
'ps-database-test-filter:s' => { name => 'ps_database_test_filter' }
});
return $self;
}
sub change_macros {
my ($self, %options) = @_;
foreach (('warning_mapi', 'critical_mapi', 'warning_mailflow', 'critical_mailflow', 'warning_copystatus', 'critical_copystatus')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{data}->{$1}/g;
}
}
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
$self->change_macros();
}
sub run {
sub manage_selection {
my ($self, %options) = @_;
if (!defined($self->{option_results}->{no_ps})) {
@ -117,10 +317,35 @@ sub run {
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
centreon::common::powershell::exchange::2010::databases::check($self, stdout => $stdout);
$self->{output}->display();
$self->{output}->exit();
my $decoded;
eval {
$decoded = JSON::XS->new->decode($stdout);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
$self->{global} = { size => 0, asize => 0 };
$self->{databases} = {};
foreach my $db (@$decoded) {
$db->{mounted} = $db->{mounted} =~ /True|1/i ? 1 : 0;
$db->{copystatus_indexstate} = $copystatus_contentindexstate->{ $db->{copystatus_indexstate} }
if (defined($db->{copystatus_indexstate}));
$self->{databases}->{ $db->{database} . ':' . $db->{server} } = {
database => $db->{database},
server => $db->{server},
db_global => $db,
space => $db,
mapi => $db,
mailflow => $db,
copystatus => $db
};
$self->{global}->{size} += $db->{size};
$self->{global}->{asize} += $db->{asize};
}
}
1;
@ -194,6 +419,16 @@ Filter database (only wilcard '*' can be used. In Powershell).
Skip mapi/mailflow test (regexp can be used. In Powershell).
=item B<--warning-status>
Set warning threshold.
Can used special variables like: %{mounted}, %{database}, %{server}
=item B<--critical-status>
Set critical threshold (Default: '%{mounted} == 0').
Can used special variables like: %{mounted}, %{database}, %{server}
=item B<--warning-mapi>
Set warning threshold.

View File

@ -20,12 +20,58 @@
package apps::exchange::2010::local::mode::queues;
use base qw(centreon::plugins::mode);
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::misc;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::common::powershell::exchange::2010::queues;
use apps::exchange::2010::local::mode::resources::types qw($queue_status $queue_delivery_type);
use JSON::XS;
sub custom_status_output {
my ($self, %options) = @_;
return sprintf(
'status: %s [last error: %s] [delivery type: %s] [identity: %s] [message count: %s]',
$self->{result_values}->{status},
$self->{result_values}->{last_error},
$self->{result_values}->{delivery_type},
$self->{result_values}->{identity},
$self->{result_values}->{message_count}
);
}
sub prefix_queue_output {
my ($self, %options) = @_;
return "Queue '" . $options{instance_value}->{nexthopdomain} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'queues', type => 1, cb_prefix_output => 'prefix_queue_output', message_multiple => 'All queues are ok', skipped_code => { -11 => 1 } }
];
$self->{maps_counters}->{queues} = [
{ label => 'status', type => 2, critical_default => '%{status} !~ /Ready|Active/i', set => {
key_values => [
{ name => 'nexthopdomain' }, { name => 'identity' },
{ name => 'is_valid' }, { name => 'isvalid' },
{ name => 'delivery_type' }, { name => 'deliverytype' },
{ name => 'message_count' }, { name => 'messagecount' },
{ name => 'status' }, { name => 'last_error' }
],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
];
}
sub new {
my ($class, %options) = @_;
@ -42,32 +88,13 @@ sub new {
'command-path:s' => { name => 'command_path' },
'command-options:s' => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' },
'ps-exec-only' => { name => 'ps_exec_only' },
'ps-display' => { name => 'ps_display' },
'warning:s' => { name => 'warning' },
'critical:s' => { name => 'critical', default => '%{status} !~ /Ready|Active/i' },
'ps-display' => { name => 'ps_display' }
});
return $self;
}
sub change_macros {
my ($self, %options) = @_;
foreach (('warning', 'critical')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{data}->{$1}/g;
}
}
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
$self->change_macros();
}
sub run {
sub manage_selection {
my ($self, %options) = @_;
if (!defined($self->{option_results}->{no_ps})) {
@ -103,10 +130,52 @@ sub run {
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
centreon::common::powershell::exchange::2010::queues::check($self, stdout => $stdout);
$self->{output}->display();
$self->{output}->exit();
my $decoded;
eval {
$decoded = JSON::XS->new->decode($stdout);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
my $perfdatas_queues = {};
$self->{queues} = {};
foreach my $queue (@$decoded) {
$queue->{is_valid} = $queue->{is_valid} =~ /True|1/i ? 1 : 0;
$queue->{status} = $queue_status->{ $queue->{status} }
if (defined($queue->{status}));
$queue->{delivery_type} = $queue_delivery_type->{ $queue->{delivery_type} }
if (defined($queue->{delivery_type}));
$self->{queues}->{ $queue->{identity} } = {
%$queue,
deliverytype => $queue->{delivery_type},
isvalid => $queue->{is_valid},
messagecount => $queue->{message_count}
};
if ($queue->{message_count} =~ /^(\d+)/) {
my $num = $1;
my $identity = $queue->{identity};
$identity = $1 if ($queue->{identity} =~ /^(.*\/)[0-9]+$/);
$perfdatas_queues->{$identity} = 0 if (!defined($perfdatas_queues->{$identity}));
$perfdatas_queues->{$identity} += $num;
}
}
foreach (keys %$perfdatas_queues) {
$self->{output}->perfdata_add(
label => 'queue_length',
nlabel => 'queue.length.count',
instances => $_,
value => $perfdatas_queues->{$_},
min => 0
);
}
}
1;
@ -160,15 +229,15 @@ Display powershell script.
Print powershell output.
=item B<--warning>
=item B<--warning-status>
Set warning threshold.
Can used special variables like: %{status}, %{identity}, %{isvalid}, %{deliverytype}, %{messagecount}
Can used special variables like: %{status}, %{identity}, %{is_valid}, %{delivery_type}, %{message_count}
=item B<--critical>
=item B<--critical-status>
Set critical threshold (Default: '%{status} !~ /Ready|Active/i').
Can used special variables like: %{status}, %{identity}, %{isvalid}, %{deliverytype}, %{messagecount}
Can used special variables like: %{status}, %{identity}, %{is_valid}, %{delivery_type}, %{message_count}
=back

View File

@ -0,0 +1,90 @@
#
# 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 apps::exchange::2010::local::mode::resources::types;
use strict;
use warnings;
use Exporter;
our $queue_status;
our $queue_delivery_type;
our $copystatus_contentindexstate;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
$queue_status $queue_delivery_type
$copystatus_contentindexstate
);
$queue_status = {
0 => 'None',
1 => 'Active',
2 => 'Ready',
3 => 'Retry',
4 => 'Suspended',
5 => 'Connecting',
6 => 'Throttled'
};
$queue_delivery_type = {
0 => 'Undefined',
1 => 'DnsConnectorDelivery',
2 => 'MapiDelivery',
3 => 'NonSmtpGatewayDelivery',
4 => 'SmartHostConnectorDelivery',
5 => 'SmtpRelayToRemoteAdSite',
6 => 'SmtpRelayToTiRg',
7 => 'SmtpRelayWithinAdSite',
8 => 'SmtpRelayWithinAdSiteToEdge',
9 => 'Unreachable',
10 => 'ShadowRedundancy',
11 => 'Heartbeat',
12 => 'DeliveryAgent',
13 => 'SmtpDeliveryToMailbox',
14 => 'SmtpRelayToDag',
15 => 'SmtpRelayToMailboxDeliveryGroup',
16 => 'SmtpRelayToConnectorSourceServers',
17 => 'SmtpRelayToServers',
18 => 'SmtpRelayToRemoteForest',
19 => 'SmtpDeliveryToExo',
20 => 'HttpDeliveryToMailbox',
21 => 'HttpDeliveryToExo',
22 => 'Delay',
23 => 'SmtpSubmissionToEop',
24 => 'SmtpSubmissionToExo',
25 => 'HttpDeliveryToApp'
};
$copystatus_contentindexstate = {
0 => 'Unknown',
1 => 'Healthy',
2 => 'Crawling',
3 => 'Failed',
4 => 'Seeding',
5 => 'FailedAndSuspended',
6 => 'Suspended',
7 => 'Disabled',
8 => 'AutoSuspended',
9 => 'HealthyAndUpgrading',
10 => 'DiskUnavailable'
};
1;

View File

@ -30,7 +30,7 @@ sub new {
bless $self, $class;
$self->{version} = '0.1';
%{$self->{modes}} = (
$self->{modes} = {
'activesync-mailbox' => 'apps::exchange::2010::local::mode::activesyncmailbox',
'databases' => 'apps::exchange::2010::local::mode::databases',
'list-databases' => 'apps::exchange::2010::local::mode::listdatabases',
@ -40,8 +40,8 @@ sub new {
'owa-mailbox' => 'apps::exchange::2010::local::mode::owamailbox',
'queues' => 'apps::exchange::2010::local::mode::queues',
'replication-health' => 'apps::exchange::2010::local::mode::replicationhealth',
'services' => 'apps::exchange::2010::local::mode::services',
);
'services' => 'apps::exchange::2010::local::mode::services'
};
return $self;
}
@ -52,7 +52,6 @@ __END__
=head1 PLUGIN DESCRIPTION
Check Windows Exchange 2010 locally.
!!! Experimental system !!!
Check Windows Exchange 2010/2016 locally.
=cut

View File

@ -22,8 +22,8 @@ package centreon::common::powershell::exchange::2010::databases;
use strict;
use warnings;
use centreon::plugins::misc;
use centreon::common::powershell::exchange::2010::powershell;
use centreon::common::powershell::functions;
sub get_powershell {
my (%options) = @_;
@ -33,7 +33,9 @@ sub get_powershell {
my $no_copystatus = (defined($options{no_copystatus})) ? 1 : 0;
my $ps = centreon::common::powershell::exchange::2010::powershell::powershell_init(%options);
$ps .= centreon::common::powershell::functions::escape_jsonstring(%options);
$ps .= centreon::common::powershell::functions::convert_to_json(%options);
$ps .= '
# Check to make sure all databases are mounted
try {
@ -55,15 +57,21 @@ try {
Write-Host $Error[0].Exception
exit 1
}
$items = New-Object System.Collections.Generic.List[Hashtable];
Foreach ($DB in $MountedDB) {
Write-Host "[name=" $DB.Name "][server=" $DB.Server "][mounted=" $DB.Mounted "][size=" $DB.DatabaseSize "][asize=" $DB.AvailableNewMailboxSpace "]" -NoNewline
$item = @{}
$item.database = $DB.Name
$item.server = $DB.Server.Name
$item.mounted = $DB.Mounted
$item.size = $DB.DatabaseSize.ToBytes().ToString()
$item.asize = $DB.AvailableNewMailboxSpace.ToBytes().ToString()
';
if (defined($options{filter_database_test}) && $options{filter_database_test} ne '') {
$ps .= '
if (!($DB.Name -match "' . $options{filter_database_test} . '")) {
Write-Host "[Skip extra test]"
continue
}
';
@ -77,7 +85,7 @@ Foreach ($DB in $MountedDB) {
$ps .= '
# Test Mapi Connectivity
$MapiResult = test-mapiconnectivity -Database $DB.Name
Write-Host "[mapi=" $MapiResult.Result "]" -NoNewline
$item.mapi_result = $MapiResult.Result
';
}
@ -85,7 +93,8 @@ Foreach ($DB in $MountedDB) {
$ps .= '
# Test Mailflow
$MailflowResult = Test-mailflow -Targetdatabase $DB.Name
Write-Host "[mailflow=" $MailflowResult.testmailflowresult "][latency=" $MailflowResult.MessageLatencyTime.TotalMilliseconds "]" -NoNewline
$item.mailflow_result = $MailflowResult.testmailflowresult
$item.mailflow_latency = $MailflowResult.MessageLatencyTime.TotalMilliseconds
';
}
if ($no_copystatus == 0) {
@ -93,214 +102,25 @@ Foreach ($DB in $MountedDB) {
# Test CopyStatus
$tmp_name = $DB.Name + "\" + $DB.Server
$CopyStatusResult = Get-MailboxDatabaseCopyStatus -Identity $tmp_name
Write-Host "[contentindexstate=" $CopyStatusResult.ContentIndexState "][[contentindexerrormessage=" $CopyStatusResult.ContentIndexErrorMessage "]]" -NoNewline
$item.copystatus_indexstate = $CopyStatusResult.ContentIndexState.value__
$item.copystatus_content_index_error_message = $CopyStatusResult.ContentIndexErrorMessage
';
}
$ps .= '
}
Write-Host ""
$items.Add($item)
}
$jsonString = $items | ConvertTo-JSON-20 -forceArray $true
Write-Host $jsonString
exit 0
';
return $ps;
}
sub check_mapi {
my ($self, %options) = @_;
if (defined($self->{option_results}->{no_mapi})) {
$self->{output}->output_add(long_msg => ' Skip MAPI test connectivity');
return ;
}
if ($options{line} !~ /\[mapi=(.*?)\]/) {
$self->{output}->output_add(long_msg => ' Skip MAPI test connectivity (information not found)');
return ;
}
$self->{data}->{mapi_result} = centreon::plugins::misc::trim($1);
$self->{output}->output_add(long_msg => " MAPI Test connectivity: " . $self->{data}->{mapi_result});
my ($status, $message) = ('ok');
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($self->{option_results}->{critical_mapi}) && $self->{option_results}->{critical_mapi} ne '' &&
eval "$self->{option_results}->{critical_mapi}") {
$status = 'critical';
} elsif (defined($self->{option_results}->{warning_mapi}) && $self->{option_results}->{warning_mapi} ne '' &&
eval "$self->{option_results}->{warning_mapi}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $status,
short_msg => sprintf("Server '%s' Database '%s' MAPI connectivity is %s",
$self->{data}->{server}, $self->{data}->{database}, $self->{data}->{mapi_result}));
}
}
sub check_mailflow {
my ($self, %options) = @_;
if (defined($self->{option_results}->{no_mailflow})) {
$self->{output}->output_add(long_msg => ' Skip Mailflow test');
return ;
}
if ($options{line} !~ /\[mailflow=(.*?)\]\[latency=(.*?)\]/) {
$self->{output}->output_add(long_msg => ' Skip Mailflow test (information not found)');
return ;
}
$self->{data}->{mailflow_result} = centreon::plugins::misc::trim($1);
my $latency = centreon::plugins::misc::trim($2);
$self->{output}->output_add(long_msg => " Mailflow Test: " . $self->{data}->{mailflow_result});
my ($status, $message) = ('ok');
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($self->{option_results}->{critical_mailflow}) && $self->{option_results}->{critical_mailflow} ne '' &&
eval "$self->{option_results}->{critical_mailflow}") {
$status = 'critical';
} elsif (defined($self->{option_results}->{warning_mailflow}) && $self->{option_results}->{warning_mailflow} ne '' &&
eval "$self->{option_results}->{warning_mailflow}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $status,
short_msg => sprintf("Server '%s' Database '%s' Mailflow test is %s",
$self->{data}->{server}, $self->{data}->{database}, $self->{data}->{mailflow_result}));
}
if ($latency =~ /^(\d+)/) {
$self->{output}->perfdata_add(label => 'latency_' . $self->{data}->{server} . '_' . $self->{data}->{database}, unit => 's',
value => sprintf("%.3f", $1 / 1000),
min => 0);
}
}
sub check_copystatus {
my ($self, %options) = @_;
if (defined($self->{option_results}->{no_copystatus})) {
$self->{output}->output_add(long_msg => ' Skip copy status test');
return ;
}
if ($options{line} !~ /\[contentindexstate=(.*?)\]\[\[contentindexerrormessage=(.*?)\]\]/) {
$self->{output}->output_add(long_msg => ' Skip copystatus test (information not found)');
return ;
}
($self->{data}->{copystatus_indexstate}, $self->{data}->{copystatus_indexerror}) = (centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2));
$self->{output}->output_add(long_msg => " Copystatus state : " . $self->{data}->{copystatus_indexstate});
my ($status, $message) = ('ok');
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($self->{option_results}->{critical_copystatus}) && $self->{option_results}->{critical_copystatus} ne '' &&
eval "$self->{option_results}->{critical_copystatus}") {
$status = 'critical';
} elsif (defined($self->{option_results}->{warning_copystatus}) && $self->{option_results}->{warning_copystatus} ne '' &&
eval "$self->{option_results}->{warning_copystatus}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $status,
short_msg => sprintf("Server '%s' Database '%s' copystatus state is %s [error: %s]",
$self->{data}->{server}, $self->{data}->{database}, $self->{data}->{copystatus_indexstate}, $self->{data}->{copystatus_indexerror}));
}
}
sub check {
my ($self, %options) = @_;
# options: stdout
# Following output:
#[name= Mailbox Database 0975194476 ][server= SRVI-WIN-TEST ][mounted= True ][size= 136.1 MB (142,671,872 bytes) ][asize= 124.4 MB (130,482,176 bytes) ][mapi= Success ][mailflow= Success ][latency= 50,00 ]
#...
$self->{output}->output_add(severity => 'OK',
short_msg => 'Databases are mounted');
if (!defined($self->{option_results}->{no_mapi})) {
$self->{output}->output_add(severity => 'OK',
short_msg => 'MAPI Connectivities are ok');
}
if (!defined($self->{option_results}->{no_mailflow})) {
$self->{output}->output_add(severity => 'OK',
short_msg => 'Mailflow test are ok');
}
my $checked = 0;
foreach my $line (split /\n/, $options{stdout}) {
next if ($line !~ /^\[name=(.*?)\]\[server=(.*?)\]\[mounted=(.*?)\]\[size=(.*?)\]\[asize=(.*?)\]/);
$checked++;
$self->{data} = {};
($self->{data}->{database}, $self->{data}->{server}, $self->{data}->{mounted}, $self->{data}->{size}, $self->{data}->{asize}) = (centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2),
centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5));
$self->{output}->output_add(long_msg => sprintf("Test database '%s' server '%s':", $self->{data}->{database}, $self->{data}->{server}));
if ($self->{data}->{asize} =~ /\((.*?)\s*bytes/) {
my $free_bytes = $1;
$free_bytes =~ s/[.,]//g;
my $total_bytes;
if ($self->{data}->{size} =~ /\((.*?)\s*bytes/) {
$total_bytes = $1;
$total_bytes =~ s/[.,]//g;
my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_bytes);
$self->{output}->output_add(long_msg => sprintf(" Size %s", $total_value . ' ' . $total_unit));
}
my $used_bytes = $total_bytes - $free_bytes;
$self->{output}->perfdata_add(label => 'used_' . $self->{data}->{database}, unit => 'B',
value => $used_bytes,
min => 0, max => $total_bytes);
my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $used_bytes);
$self->{output}->output_add(long_msg => sprintf(" Used Size %s", $used_value . ' ' . $used_unit));
}
# Check mounted
if ($self->{data}->{mounted} =~ /False/i) {
$self->{output}->output_add(long_msg => sprintf(" not mounted\n Skip mapi/mailflow test"));
$self->{output}->output_add(severity => 'CRITICAL',
short_msg => sprintf("Database '%s' server '%s' is not mounted", $self->{data}->{database}, $self->{data}->{server}));
next;
}
$self->{output}->output_add(long_msg => sprintf(" mounted"));
check_mapi($self, line => $line);
check_mailflow($self, line => $line);
check_copystatus($self, line => $line);
}
if ($checked == 0) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => 'Cannot find informations');
}
}
1;
__END__

View File

@ -22,13 +22,15 @@ package centreon::common::powershell::exchange::2010::queues;
use strict;
use warnings;
use centreon::plugins::misc;
use centreon::common::powershell::exchange::2010::powershell;
use centreon::common::powershell::functions;
sub get_powershell {
my (%options) = @_;
my $ps = centreon::common::powershell::exchange::2010::powershell::powershell_init(%options);
$ps .= centreon::common::powershell::functions::escape_jsonstring(%options);
$ps .= centreon::common::powershell::functions::convert_to_json(%options);
$ps .= '
try {
@ -39,80 +41,28 @@ try {
exit 1
}
$items = New-Object System.Collections.Generic.List[Hashtable];
Foreach ($result in $results) {
Write-Host "[identity=" $result.Identity "][nexthopdomain=" $result.NextHopDomain "][deliverytype=" $result.DeliveryType "][status=" $result.Status "][isvalid=" $result.IsValid "][messagecount=" $result.MessageCount "][[error=" $result.LastError "]]"
$item = @{}
$item.identity = $result.Identity.ToString().Replace("\\", "/")
$item.nexthopdomain = $result.NextHopDomain
$item.delivery_type = $result.DeliveryType.value__
$item.status = $result.Status.value__
$item.is_valid = $result.IsValid
$item.message_count = $result.MessageCount
$item.last_error = $result.LastError
$items.Add($item)
}
$jsonString = $items | ConvertTo-JSON-20 -forceArray $true
Write-Host $jsonString
exit 0
';
return $ps;
}
sub check {
my ($self, %options) = @_;
# options: stdout
# Following output:
#[identity= ][nexthopdomain= xxxx][deliverytype= SmtpRelayWithinAdSite][status= Active ][isvalid= Yes][messagecount= 1 ][[error=...]]
$self->{output}->output_add(severity => 'OK',
short_msg => "All Queues are ok.");
my $checked = 0;
$self->{output}->output_add(long_msg => $options{stdout});
$self->{perfdatas_queues} = {};
while ($options{stdout} =~ /\[identity=(.*?)\]\[nexthopdomain=(.*?)\]\[deliverytype=(.*?)\]\[status=(.*?)\]\[isvalid=(.*?)\]\[messagecount=(.*?)\]\[\[error=(.*?)\]\]/msg) {
$self->{data} = {};
($self->{data}->{identity}, $self->{data}->{nexthopdomain}, $self->{data}->{deliverytype}, $self->{data}->{status}, $self->{data}->{isvalid}, $self->{data}->{messagecount}, $self->{data}->{error}) =
($self->{output}->to_utf8($1), centreon::plugins::misc::trim($2),
centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5), centreon::plugins::misc::trim($6), centreon::plugins::misc::trim($7));
$checked++;
my ($status, $message) = ('ok');
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($self->{option_results}->{critical}) && $self->{option_results}->{critical} ne '' &&
eval "$self->{option_results}->{critical}") {
$status = 'critical';
} elsif (defined($self->{option_results}->{warning}) && $self->{option_results}->{warning} ne '' &&
eval "$self->{option_results}->{warning}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $status,
short_msg => sprintf("Queue '%s' status is '%s' [last error: %s]",
$self->{data}->{nexthopdomain}, $self->{data}->{status}, $self->{data}->{error}));
}
if ($self->{data}->{messagecount} =~ /^(\d+)/) {
my $num = $1;
my $identity = $self->{data}->{identity};
$identity = $1 if ($self->{data}->{identity} =~ /^(.*\\)[0-9]+$/);
$self->{perfdatas_queues}->{$identity} = 0 if (!defined($self->{perfdatas_queues}->{$identity}));
$self->{perfdatas_queues}->{$identity} += $num;
}
}
foreach (keys %{$self->{perfdatas_queues}}) {
$self->{output}->perfdata_add(label => 'queue_length_' . $_,
value => $self->{perfdatas_queues}->{$_},
min => 0);
}
if ($checked == 0) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => 'Cannot find informations');
}
}
1;
__END__

View File

@ -67,7 +67,7 @@ function ConvertTo-JSON-20($maxDepth = 4,$forceArray = $false) {
return "`"{0}`"" -f (Escape-JSONString $value )
}
'(System\.)?DateTime' {return "`"{0:yyyy-MM-dd}T{0:HH:mm:ss}`"" -f $value}
'Int32|Double' {return "$value"}
'Int16|Int32|Double' {return "$value"}
'Boolean' {return "$value".ToLower()}
'(System\.)?Object\[\]' { # array