1. Install xinetd and check_mk_agent
Install xinetd first. The check_mk_agent package drops a configuration snippet into /etc/xinetd.d/, which makes xinetd listen on port 6556 for the agent.
2. Write the custom check (Service to check)
The server-side check can be written in any language, as long as it can print to STDOUT. The output format is quite simple:
<<<check_name>>>
data1 data2 ... dataN
data1 data2 ... dataN
...
check_name is the identifier. It can be anything, but it has to be enclosed in <<<>>>. Data[1-] are the things you want to check, including performance counters, anything you like. Server-side the data will be split at white-spaces.
Simple example: check if bacula-director and bacula-storage-daemon is running (in perl):
#!/usr/bin/perl -w
use strict;
my @instances = `ps o cmd ax`;
my %count;
foreach my $i (@instances){
if($i =~ m#bacula-sd#){
$count{"storage_daemon"}++;
}
if($i =~ m#bacula-dir#){
$count{"director"}++;
}
}
print "<<<bacula_system>>>\n";
foreach my $k (keys %count){
print "$k $count{$k}\n";
}
Output:
<<<bacula_system>>>
storage_daemon 1
director 1
One storage daemon process and one director process running. Perfect! Drop this script in /usr/lib/check_mk/plugins and make it executable.
3. The check_mk-Server-Part
Now we have to create the server-side counterpart. This has to be in python, because check_mk uses introspection extensively. Create a script named exactly as the identifier in local/share/check_mk/checks starting in the home directory of your check_mk-site-user. In the example given: local/share/check_mk/checks/bacula_system
The first thing we need is the dictionary check_info[] with at least these entries:
- check_function: Name of the function actually performing the check
- inventory_function: Name of the inventory function (called by WATO, the Web Administration)
- service_description: Name of the service, can be a format string
Example:
#!/usr/bin/python
def inventory_bacula_instances(info):
inventory = []
inventory.append( ("storage_daemon", None) )
inventory.append( ("director", None) )
return inventory
def check_bacula_instances(item, params, info):
count = 0
for each in info:
if each[0] == item:
count = int(each[1])
retval = 3
perfdata = [ (item, count) ]
if count == 0:
retstring = "No instance found for %s" % item
return (2, retstring, perfdata)
else:
retstring = "%d instances found for %s" % (int(count), item)
return (0, retstring, perfdata)
return (3, "Checking %s failed" % item, perfdata)
check_info["bacula_system"] = {
"check_function": check_bacula_instances,
"inventory_function": inventory_bacula_instances,
"service_description": 'Bacula: %s',
"has_perfdata": True,
}
3. The inventory function
The inventory function returns an array of Tuples with the items to check, in our case the items storage_daemon and directory returned by our perl script. The Tuples are fed to the check_function, in our case check_bacula_instances(item, params, info).
4. The check_function
The check_function does the actual work. The return values are:
- 0: OK
- 1: Warning
- 2: Critical
- 3: Unknown
The parameters:
- item: The name of the item to check, i. e. the first item of the Tuple returned by the inventory_function. In our case “storage_daemon” or “director”
- params: no idea (TODO)
- info: a dictionary as key and an array with the values returned from the server-side script. In the example given something like this:
{'director': ['director', 1], 'storage_daemon': ['storage_daemon', 1]}
So info[‘director’][1] gives you the count of director processes.
5. Configure the check
- Login to WATO, click WATO-Configuration->Hosts->New Host.
- Enter hostname
- Click Save & Test, check that the agent is available
- Click Save & Exit
- Click Save & go to Services
- Save and activate the new configuration
- Have FUN!
6. Debugging
Sprinkle the python script with “print <somethingorother>” and call
$ cmk <hostname>
from the command line.
Ich habe fertig 🙂