{"id":68,"date":"2015-07-25T15:59:33","date_gmt":"2015-07-25T14:59:33","guid":{"rendered":"https:\/\/tollana.d-tor.org\/notes-to-self\/?p=68"},"modified":"2016-11-27T01:02:12","modified_gmt":"2016-11-27T00:02:12","slug":"custom-checks-with-check_mk_agent","status":"publish","type":"post","link":"https:\/\/tollana.d-tor.org\/notes-to-self\/?p=68","title":{"rendered":"Custom Checks with check_mk_agent"},"content":{"rendered":"<h3>1. Install xinetd and check_mk_agent<\/h3>\n<p>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.<\/p>\n<h3>2. Write the custom check (Service to check)<\/h3>\n<p>The server-side check can be written in any language, as long as it can print to STDOUT. The output format is quite simple:<\/p>\n<pre>&lt;&lt;&lt;check_name&gt;&gt;&gt;\r\ndata1 data2 ... dataN\r\ndata1 data2 ... dataN\r\n...<\/pre>\n<p>check_name is the identifier. It can be anything, but it has to be enclosed in &lt;&lt;&lt;&gt;&gt;&gt;. 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.<\/p>\n<p>Simple example: check if bacula-director and bacula-storage-daemon is running (in perl):<\/p>\n<pre>#!\/usr\/bin\/perl -w \r\n \r\nuse strict; \r\n \r\nmy @instances = `ps o cmd ax`; \r\nmy %count; \r\nforeach my $i (@instances){ \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if($i =~ m#bacula-sd#){ \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$count{\"storage_daemon\"}++; \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if($i =~ m#bacula-dir#){ \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$count{\"director\"}++; \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \r\n} \r\n \r\nprint \"&lt;&lt;&lt;bacula_system&gt;&gt;&gt;\\n\"; \r\nforeach my $k (keys %count){ \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print \"$k $count{$k}\\n\"; \r\n}<\/pre>\n<p>Output:<\/p>\n<pre>&lt;&lt;&lt;bacula_system&gt;&gt;&gt; \r\nstorage_daemon 1 \r\ndirector 1<\/pre>\n<p>One storage daemon process and one director process running. Perfect! Drop this script in \/usr\/lib\/check_mk\/plugins and make it executable.<\/p>\n<h3>3. The check_mk-Server-Part<\/h3>\n<p>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:\u00a0local\/share\/check_mk\/checks\/bacula_system<\/p>\n<p>The first thing we need is the\u00a0dictionary\u00a0check_info[] with at least these entries:<\/p>\n<ul>\n<li>check_function: Name of the function actually performing the check<\/li>\n<li>inventory_function: Name of the inventory function (called by WATO, the Web Administration)<\/li>\n<li>service_description: Name of the service, can be a format string<\/li>\n<\/ul>\n<p>Example:<\/p>\n<pre>#!\/usr\/bin\/python \r\n \r\ndef inventory_bacula_instances(info): \r\n \u00a0\u00a0\u00a0inventory = [] \r\n \u00a0\u00a0\u00a0inventory.append( (\"storage_daemon\", None) ) \r\n \u00a0\u00a0\u00a0inventory.append( (\"director\", None) ) \r\n \u00a0\u00a0\u00a0return inventory \r\n \r\ndef check_bacula_instances(item, params, info): \r\n \u00a0\u00a0\u00a0count = 0 \r\n \u00a0\u00a0\u00a0for each in info: \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if each[0] == item: \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0count = int(each[1]) \r\n \r\n \u00a0\u00a0\u00a0retval = 3 \r\n \u00a0\u00a0\u00a0perfdata = [ (item, count) ] \r\n \u00a0\u00a0\u00a0if count == 0: \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0retstring = \"No instance found for %s\" % item \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return (2, retstring, perfdata) \r\n \u00a0\u00a0\u00a0else: \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0retstring = \"%d instances found for %s\" % (int(count), item) \r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return (0, retstring, perfdata) \r\n \r\n \u00a0\u00a0\u00a0return (3, \"Checking %s failed\" % item, perfdata) \r\n \r\ncheck_info[\"bacula_system\"] = { \r\n \u00a0\u00a0\u00a0\"check_function\": \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0check_bacula_instances, \r\n \u00a0\u00a0\u00a0\"inventory_function\": \u00a0\u00a0inventory_bacula_instances, \r\n \u00a0\u00a0\u00a0\"service_description\": \u00a0'Bacula: %s', \r\n \u00a0\u00a0\u00a0\"has_perfdata\": \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0True, \r\n}<\/pre>\n<h3>3. The inventory function<\/h3>\n<p>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).<\/p>\n<h3>4. The check_function<\/h3>\n<p>The check_function does the actual work. The return values are:<\/p>\n<ul>\n<li>0: OK<\/li>\n<li>1: Warning<\/li>\n<li>2: Critical<\/li>\n<li>3: Unknown<\/li>\n<\/ul>\n<p>The parameters:<\/p>\n<ul>\n<li>item: The name of the item to check, i. e. the first item of the Tuple returned by the inventory_function. In our case &#8220;storage_daemon&#8221; or &#8220;director&#8221;<\/li>\n<li>params: no idea (TODO)<\/li>\n<li>info: a dictionary as key and an array with the values returned from the server-side script. In the example given something like this:<\/li>\n<\/ul>\n<pre>{'director': ['director', 1], 'storage_daemon': ['storage_daemon', 1]}<\/pre>\n<p>So info[&#8216;director&#8217;][1] gives you the count of director processes.<\/p>\n<h3>5. Configure the check<\/h3>\n<ol>\n<li>Login to WATO, click WATO-Configuration-&gt;Hosts-&gt;New Host.<\/li>\n<li>Enter hostname<\/li>\n<li>Click Save &amp; Test, check that the agent is available<\/li>\n<li>Click Save &amp; Exit<\/li>\n<li>Click Save &amp; go to Services<\/li>\n<li>Save and activate the new configuration<\/li>\n<li>Have FUN!<\/li>\n<\/ol>\n<h3>6. Debugging<\/h3>\n<p>Sprinkle the python script with &#8220;print &lt;somethingorother&gt;&#8221; and call<\/p>\n<pre>$ cmk &lt;hostname&gt;<\/pre>\n<p>from the command line.<\/p>\n<p>Ich habe fertig \ud83d\ude42<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <a href=\"https:\/\/tollana.d-tor.org\/notes-to-self\/?p=68\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Custom Checks with check_mk_agent<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[27],"class_list":["post-68","post","type-post","status-publish","format-standard","hentry","category-check_mk","tag-check_mk"],"_links":{"self":[{"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=\/wp\/v2\/posts\/68","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=68"}],"version-history":[{"count":3,"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=\/wp\/v2\/posts\/68\/revisions"}],"predecessor-version":[{"id":98,"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=\/wp\/v2\/posts\/68\/revisions\/98"}],"wp:attachment":[{"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=68"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=68"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tollana.d-tor.org\/notes-to-self\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=68"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}