diff --git a/src/database/mssql/mode/deadlocks.pm b/src/database/mssql/mode/deadlocks.pm index 91f08a3286..18be628e1e 100644 --- a/src/database/mssql/mode/deadlocks.pm +++ b/src/database/mssql/mode/deadlocks.pm @@ -20,9 +20,11 @@ package database::mssql::mode::deadlocks; +use base qw(centreon::plugins::templates::counter); + use strict; use warnings; -use base qw(centreon::plugins::templates::counter); +use Digest::MD5 qw(md5_hex); sub set_counters { my ($self, %options) = @_; @@ -32,25 +34,32 @@ sub set_counters { ]; $self->{maps_counters}->{deadlocks} = [ - { label => 'deadlocks', nlabel => 'mssql.deadlocks.count', set => { - key_values => [ { name => 'value' } ], - output_template => '%.2f dead locks/s', - perfdatas => [ - { template => '%.2f', min => 0 }, - ], - } + { label => 'deadlocks', nlabel => 'mssql.deadlocks.count.persecond', set => { + key_values => [ { name => 'value', per_second => 1 } ], + output_template => '%.2f dead locks/s', + perfdatas => [ + { template => '%.2f', min => 0 }, + ], + } + }, + { label => 'total', nlabel => 'mssql.deadlocks.count', set => { + key_values => [ { name => 'value' } ], + output_template => '%d dead locks', + perfdatas => [ + { template => '%d', min => 0 }, + ], + } }, ]; } - 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, statefile => 1, force_new_perfdata => 1); bless $self, $class; - - $options{options}->add_options(arguments => { - "filter-database:s" => { name => 'filter_database' }, + + $options{options}->add_options(arguments => { + "filter-instance:s" => { name => 'filter_instance', default => '_Total' }, }); return $self; @@ -67,18 +76,31 @@ sub manage_selection { sys.dm_os_performance_counters WHERE object_name = 'SQLServer:Locks' - AND - counter_name LIKE 'Number of Deadlocks/sec%' + AND counter_name LIKE 'Number of Deadlocks/sec%' }); my $query_result = $options{sql}->fetchall_arrayref(); $self->{deadlocks}->{value} = 0; foreach my $row (@{$query_result}) { - next if (defined($self->{option_results}->{filter_database}) && $self->{option_results}->{filter_database} ne '' - && $$row[0] !~ /$self->{option_results}->{filter_database}/); + my $instance = $$row[0]; + $instance =~ s/^\s+|\s+$//g; + if (defined($self->{option_results}->{filter_instance}) && $self->{option_results}->{filter_instance} ne '' + && $instance !~ /$self->{option_results}->{filter_instance}/) { + $self->{output}->output_add(long_msg => + "skipping instance '" . $instance . ' - ' . $$row[1] . "' : no matching filter instance", + debug => + 1); + next; + } + + $self->{output}->output_add(long_msg => "instance $instance: $$row[1]", debug => 1); $self->{deadlocks}->{value} += $$row[1]; } + + $self->{cache_name} = 'mssql_' . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_instance}) ? md5_hex($self->{option_results}->{filter_instance}) : md5_hex('all')); } 1; @@ -99,9 +121,10 @@ Warning threshold number of dead locks per second. Critical threshold number of dead locks per second. -=item B<--filter-database> +=item B<--filter-instance> -Filter the databases to monitor with a regular expression. +Filter the sub-category inside the performance object. The instance_name represents the lock type. For example: C<_Total>, C, C, C, C. (default: '_Total') +https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-locks-object?view=sql-server-ver17 =back diff --git a/src/database/mssql/mode/lockswaits.pm b/src/database/mssql/mode/lockswaits.pm index 2ad9b2d04b..06646f7c66 100644 --- a/src/database/mssql/mode/lockswaits.pm +++ b/src/database/mssql/mode/lockswaits.pm @@ -20,9 +20,11 @@ package database::mssql::mode::lockswaits; +use base qw(centreon::plugins::templates::counter); + use strict; use warnings; -use base qw(centreon::plugins::templates::counter); +use Digest::MD5 qw(md5_hex); sub set_counters { my ($self, %options) = @_; @@ -32,25 +34,32 @@ sub set_counters { ]; $self->{maps_counters}->{lockswaits} = [ - { label => 'lockswaits', nlabel => 'mssql.lockswaits.count', set => { - key_values => [ { name => 'value' } ], - output_template => '%.2f locks waits/s', - perfdatas => [ - { template => '%.2f', min => 0 } - ] - } + { label => 'lockswaits', nlabel => 'mssql.lockswaits.count.persecond', set => { + key_values => [ { name => 'value', per_second => 1 } ], + output_template => '%.2f locks waits/s', + perfdatas => [ + { template => '%.2f', min => 0 } + ] + } + }, + { label => 'total', nlabel => 'mssql.lockswaits.count', set => { + key_values => [ { name => 'value' } ], + output_template => '%d locks waits', + perfdatas => [ + { template => '%d', min => 0 }, + ], + } } ]; } - 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, statefile => 1, force_new_perfdata => 1); bless $self, $class; - - $options{options}->add_options(arguments => { - 'filter-database:s' => { name => 'filter_database' } + + $options{options}->add_options(arguments => { + 'filter-instance:s' => { name => 'filter_instance', default => '_Total' } }); return $self; @@ -67,18 +76,35 @@ sub manage_selection { sys.dm_os_performance_counters WHERE object_name = 'SQLServer:Locks' - AND - counter_name LIKE 'Lock Waits/sec%' + AND counter_name LIKE 'Lock Waits/sec%' }); my $query_result = $options{sql}->fetchall_arrayref(); $self->{lockswaits}->{value} = 0; foreach my $row (@{$query_result}) { - next if (defined($self->{option_results}->{filter_database}) && $self->{option_results}->{filter_database} ne '' - && $$row[0] !~ /$self->{option_results}->{filter_database}/); + my $instance = $$row[0]; + $instance =~ s/^\s+|\s+$//g; + if (defined($self->{option_results}->{filter_instance}) && $self->{option_results}->{filter_instance} ne '' + && $instance !~ /$self->{option_results}->{filter_instance}/) { + $self->{output}->output_add(long_msg => + "skipping instance '" . $instance . ' - ' . $$row[1] . "' : no matching filter instance", + debug => + 1); + next; + } + + $self->{output}->output_add(long_msg => "instance $instance: $$row[1]", debug => 1); $self->{lockswaits}->{value} += $$row[1]; } + + $self->{cache_name} = 'mssql_' . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? + md5_hex($self->{option_results}->{filter_counters}) : + md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_instance}) ? + md5_hex($self->{option_results}->{filter_instance}) : + md5_hex('all')); } 1; @@ -99,9 +125,10 @@ Warning threshold number of lock-waits per second. Critical threshold number of lock-waits per second. -=item B<--filter-database> +=item B<--filter-instance> -Filter the databases to monitor with a regular expression. +Filter the sub-category inside the performance object. The instance_name represents the lock type. For example: C<_Total>, C, C, C, C. (default: '_Total') +https://learn.microsoft.com/en-us/sql/relational-databases/performance-monitor/sql-server-locks-object?view=sql-server-ver17 =back