# you will find instructions how to write extensions here

Self-written code is addressed by using a mode which starts with my-
--mode=my-thing-does ?

check_mysql_health will then look for a package named MyThing.

So you first have to write a Module which describes MyThing. Such a thing iinherits from DBD::MySQL::Server and needs two methods: init and nagios.

Start with a file called CheckMySQLHealthExt1.pm and skeleton code:

###################################################
package MyThing;

our @ISA = qw(DBD::MySQL::Server);

sub init {
  my $self = shift;
  my %params = @_;
}

sub nagios {
  my $self = shift;
  my %params = @_;
}
###################################################

When you call check_mysql_health with --mode=my-thing-does, it will
- create a DBD::MySQL::Server object
  $obj = DBD::MySQL::Server->new()
- connect to the database
  $obj->connect()
- re-bless the object
  bless $obj, "MyThing"
- call $obj->init()
- if that was ok, call $obj->nagios()


So you need to write code which 
- initializes the parameters you want to check
- calculates the nagios result from these parameters

For your convenience there are some predefined methods and variables:

Variable $self
 $self is a hash-based object of type My::Thing
 You can pass metrics from the init() method to the nagios() method by
 adding attributes to the hash.
 One important predefined attribute is $self->{handle} which points to
 a database Connection object. You surely will use this.

Variable %params
 $params{mode} contains the string you passed to the 
 --mode command line parameter, only with the "-" replaced by "::".
 In the above example it will be "my::thing::does". 
 Because you can have only one init() method for your MyThing object but 
 more than one related modes (my-thing-does, my-thing-length, my-thing-rate)
 you use $params{mode} for branching in your code. (see the example file)

Method add_nagios
 $self->add_nagios(1, "i warn you");
 This method can be called several times. The messages will be concatenated.
 The first parameter is one of 0..3 and sets the nagios level. The worst level
 among several calls to add_nagios will determine the plugin's exit code.

Method add_nagios_[ok|warning|critical|unknown] 
 $self->add_nagios_critical("i warned you!!! now it's too late");
 $self->add_nagios_ok("everything is ok. i am the exit message");
 These methods are wrappers for add_nagios which make your code more readable.

Method add_perfdata
 $self->add_perfdata("metric1=0 metric2=100");
 $self->add_perfdata("metric3=0);
 $self->add_perfdata(sprintf "metric_xy=%d", $self->{xy});
 You can call add_perfdata as often as you like. 
 The strings will be concatenated.

Method valdiff
 $self->valdiff(\%params, qw(metric1 metric2));
 Use this if you want to know how a metric has changed since the last run
 of check_mysql_health.
 Provided you have attributes metric1 and metric2 this method will create
 new attributes for your $self object.
 $self->{delta_metric1} which is the difference between the value of
 $self->{metric1} during the current run and $self->{metric1} during the
 last run.
 $self->{delta_timestamp} which is the number of seconds which passed
 since the last run of check_mysql_health.
 If you have ever-growing values, you can simply calculate the rate:
 $self->{metric1_per_second} = $self->{delta_metric1} / $self->{delta_timestamp}
 The valdiff method will automatically save the current value to a state file
 and read the past value from this file.
 If you used the --name parameter which appears as $params{name} in your code
 then you probably need to separate the saved values from each other. Otherwise
 name1 would read the same saved value as name2. They would overwrite the 
 saved values. Use $params{differentiator} to use different state files.
 $params{differenciator} = lc $self->{name};
 $self->valdiff(\%params, qw(gets misses));

Method fetchrow_array
 my($column1, $column2) = $self->{handle}->fetchrow_array(q{
     SELECT col1, col2 FROM table1 where col1 = 'val1'
 });
 $self->{connected_users} = $self->{handle}->fetchrow_array(q{
     SELECT COUNT(*) FROM v$session WHERE type = 'USER'
 });
 This method is used like the Perl DBI method fetchrow_array.


Method fetchall_array
 my @results = $self->{handle}->fetchall_array(q{
   SELECT col1, col2, col3 FROM table1
 });
 foreach (@results) {
   my($column1, $column2, $column3) = @{$_};
   ...
 }
 This method is used like the Perl DBI method fetchall_array.




Now you have written your first extension to check_mysql_health. Maybe you
just modified the example file contrib/CheckMySQLHealthExt1.pm
There are two methods how to import your own code into check_mysql_health:

- the static method
with ./configure --with-mymodules-dir=<dir> parameter you build a plugin which
contains both my code and your code in a single file. When you call "make"
every file in <dir> which matches CheckMySQLHealthExt*.pm is appended
to the final plugin check_mysql_health.

- the dynamic method
with ./configure --with-mymodules-dyn-dir=<dir> you build a plugin which will
search at runtime the <dir> for files matching CheckMySQLHealthExt*.pm and
import them. This way you can have different extensions on different hosts.
You also can modify your extension without having to rebuild the plugin.
On the other hand you have to distribute your extensions along with the plugin.

