Creating a custom active check?

Hello!

i’m looking for a way to create custom active check like the one that are available here

i was this here, it’s quite straight forward to create the web part, but how do i create my own check and map it to this one?

An active check is a program executed from your check_mk server that will execute code as you designed it and will evaluate health based on execution code. Pretty much like a local check.

I believe that if you download some examples from exchange.checkmk.com will guide you through what you need.

Resuming :

You’ll need an wato plugin to “draw” the GUI part;
You’ll need a check file to process what you set on that GUI part (argument parse);
The active check it-self;
Optionally, you might want to set metrics plugins for graph purposes.

Download this example (i found it to be very simple to understand (pathing, files, etc)) :

https://exchange.checkmk.com/p/dnsx

Cheers,

1 Like

Hello!,

Thanks for the suggestion, this will work on all Cmk versions ? 1.2 1.6 and 2.0 ? because we have multiple versions installed on multiple sites!

Best Regards

I truly believe so :slight_smile:

Hello Ricardo,
Sorry for the hassle, i’m fixed the WATO file, i did the following:

#!/usr/bin/python

group = “activechecks”

register_rule(group,
“active_checks:esim_profile”,
Tuple(
title=(“Check Esim Profile Download”),
help=
(“Check the Esim profile download steps, Internet, WAF and APP”),
elements=[
TextAscii(
title=(“Link(URL):”),
allow_empty=False,
help=
(‘The URL for the operator.’)),
TextAscii(
title=(“Domain Name:”),
allow_empty=False,
help=
(‘The Domain Name you want to Query.’)),
]
),
match=‘all’
)

when the GUI appeared when i add a check and click apply i get the following error:

Internal automation error: Error running automation call restart (exit code 1), error: 

An error occurred: Error creating configuration: 'NoneType' object has no attribute 'replace'


Traceback (most recent call last):
  File "/omd/sites/montyuk/lib/python3/cmk/gui/wato/pages/automation.py", line 168, in _execute_automation_command
    html.write(repr(automation.execute(automation.get_request())))
  File "/omd/sites/montyuk/lib/python3/cmk/gui/wato/pages/activate_changes.py", line 666, in execute
    return cmk.gui.watolib.activate_changes.execute_activate_changes(request.domains)
  File "/omd/sites/montyuk/lib/python3/cmk/gui/watolib/activate_changes.py", line 1781, in execute_activate_changes
    warnings = domain_class().activate()
  File "/omd/sites/montyuk/lib/python3/cmk/gui/watolib/config_domains.py", line 60, in activate
    return check_mk_local_automation(config.wato_activation_method)
  File "/omd/sites/montyuk/lib/python3/cmk/gui/watolib/automations.py", line 143, in check_mk_local_automation
    raise _local_automation_failure(command=command,
cmk.utils.exceptions.MKGeneralException: Error running automation call restart (exit code 1), error: 

An error occurred: Error creating configuration: 'NoneType' object has no attribute 'replace'

any hint?

Thanks!

@moritz @joerg.herbel
would one of you care to take a look?

1 Like

You could look at the output of “cmk --debug -U” to see what’s going on. But this looks very old, a modern WATO plugin should look like this:


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.
"""WATO ruleset for special agent exchange

This file is part of the tribe29 development training.

This file goes into ~MySITE/local/share/check_mk/web/plugins/wato.
"""

from cmk.gui.i18n import _
from cmk.gui.plugins.wato import HostRulespec, rulespec_registry
from cmk.gui.plugins.wato.active_checks import RulespecGroupActiveChecks
from cmk.gui.valuespec import (
    Dictionary,
    Integer,
    Tuple,
)


def _valuespec_check_exchange():
    return Dictionary(
        ....
    )


rulespec_registry.register(
    HostRulespec(
        group=RulespecGroupActiveChecks,
        name="active_checks:exchange",
        valuespec=_valuespec_check_exchange,
    ))

Dear @moritz,

it would be great if there is an example somewhere i can have hints on, i tried the following:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.
"""WATO ruleset for special agent exchange

This file is part of the tribe29 development training.

This file goes into ~MySITE/local/share/check_mk/web/plugins/wato.
"""

from cmk.gui.i18n import _
from cmk.gui.plugins.wato import HostRulespec, rulespec_registry
from cmk.gui.plugins.wato.active_checks import RulespecGroupActiveChecks
from cmk.gui.valuespec import (
    Dictionary,
    Integer,
    Tuple,
)


def _valuespec_check_esim_profile():
    return Dictionary(
        title=_("Check Esim Profile Download"),
        help=_("Check the Esim profile download steps, Internet, WAF and APP"),
        elements=[
            TextAscii(
                title=_("Link(URL):"),
                allow_empty=False,
                help=_('The URL for the operator.')),
            TextAscii(
                title=_("Domain Name:"),
                allow_empty=False,
                help=_('The Domain Name you want to Query.')),
        ]
    ),


rulespec_registry.register(
    HostRulespec(
        group=RulespecGroupActiveChecks,
        name="active_checks:esim_profile",
        valuespec=_valuespec_check_esim_profile,
    ))


i’m getting the following error:

  File "/omd/sites/montyholding/lib/python3/cmk/gui/wsgi/applications/checkmk.py", line 165, in _process_request
    response = page_handler()
  File "/omd/sites/montyholding/lib/python3/cmk/gui/wsgi/applications/utils.py", line 59, in _call_auth
    func()
  File "/omd/sites/montyholding/lib/python3/cmk/gui/pages.py", line 186, in <lambda>
    return (lambda hc: lambda: hc().handle_page())(handle_class)
  File "/omd/sites/montyholding/lib/python3/cmk/gui/pages.py", line 48, in handle_page
    self.page()
  File "/omd/sites/montyholding/lib/python3/cmk/gui/pages.py", line 158, in <lambda>
    "page": lambda self: self._wrapped_callable[0]()
  File "/omd/sites/montyholding/lib/python3/cmk/gui/wato/page_handler.py", line 93, in page_handler
    _wato_page_handler(current_mode, mode_permissions, mode_class)
  File "/omd/sites/montyholding/lib/python3/cmk/gui/wato/page_handler.py", line 174, in _wato_page_handler
    mode.handle_page()
  File "/omd/sites/montyholding/lib/python3/cmk/gui/plugins/wato/utils/base_modes.py", line 157, in handle_page
    return self.page()
  File "/omd/sites/montyholding/lib/python3/cmk/gui/wato/pages/rulesets.py", line 216, in page
    rulesets = watolib.SearchedRulesets(rulesets, self._search_options)
  File "/omd/sites/montyholding/lib/python3/cmk/gui/watolib/rulesets.py", line 416, in __init__
    self._load_filtered()
  File "/omd/sites/montyholding/lib/python3/cmk/gui/watolib/rulesets.py", line 425, in _load_filtered
    if ruleset.matches_search_with_rules(self._search_options):
  File "/omd/sites/montyholding/lib/python3/cmk/gui/watolib/rulesets.py", line 574, in matches_search_with_rules
    if not self.matches_ruleset_search_options(search_options):
  File "/omd/sites/montyholding/lib/python3/cmk/gui/watolib/rulesets.py", line 621, in matches_ruleset_search_options
    if not _match_search_expression(search_options, "ruleset_title", self.title()):
  File "/omd/sites/montyholding/lib/python3/cmk/gui/watolib/rulesets.py", line 699, in title
    return self.rulespec.title
  File "/omd/sites/montyholding/lib/python3/cmk/gui/watolib/rulespecs.py", line 436, in title
    return self.valuespec.title()

Best Regards.

In your case i looks like a problem with the returned Dictionary.
A valuespec section from ssh active check looks like this.

def _valuespec_active_checks_ssh():
    return Dictionary(
        title=_("Check SSH service"),
        help=_("This rulset allow you to configure a SSH check for a host"),
        elements=[
            ("description", TextUnicode(title=_("Service Description"),)),
            ("port",
             Integer(title=_("TCP port number"),
                 default_value=22,
            )),
            ("timeout",
             Integer(title=_("Connect Timeout"),
                     help=_("Seconds before connection times out"),
                     default_value=10,
            )),
            ("remote_version",
             TextAscii(
                 title=_("Version of Server"),
                 help=_("Warn if string doesn't match expected server version (ex: OpenSSH_3.9p1)"),
             )),
            ("remote_protocol",
             TextAscii(
                 title=_("Protocol of Server"),
                 help=_("Warn if protocol doesn't match expected protocol version (ex: 2.0)"),
             )),
        ],
    )

rulespec_registry.register(
    HostRulespec(
        group=RulespecGroupIntegrateOtherServices,
        match_type="all",
        name="active_checks:ssh",
        valuespec=_valuespec_active_checks_ssh,
    ))

Hello Guys! sorry for the hassle! but it’s either me or either me :rofl:… i did exactly what you provided in the example here the code below:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.
"""WATO ruleset for special agent exchange

This file is part of the tribe29 development training.

This file goes into ~MySITE/local/share/check_mk/web/plugins/wato.
"""

from cmk.gui.i18n import _
from cmk.gui.plugins.wato import HostRulespec, rulespec_registry
from cmk.gui.plugins.wato.active_checks import RulespecGroupActiveChecks
from cmk.gui.valuespec import (
    Dictionary,
    Integer,
    Tuple,
    TextAscii,
)


def _valuespec_check_esim_profile():
    return Dictionary(
        title=_("Check Esim Profile Download"),
        help=_("Check the Esim profile download steps, Internet, WAF and APP"),
        elements=[
            ("link",
             TextAscii(
                 title=_("Link(URL):"),
                 allow_empty=False)),
            ("domain",
             TextAscii(
                 title=_("Domain Name:"),
                 allow_empty=False)),
        ],
    )



rulespec_registry.register(
    HostRulespec(
        group=RulespecGroupActiveChecks,
        name="active_checks:esim_profile",
        match_type="all",
        valuespec=_valuespec_check_esim_profile,
    ))

now i can see the ActiveCheck in the WATO


But when i apply the change i get the error below, please note that it’s the same error as i first started…

Got invalid data:

Internal automation error: Error running automation call restart (exit code 1), error: 

An error occurred: Error creating configuration: 'NoneType' object has no attribute 'replace'


Traceback (most recent call last):
  File "/omd/sites/montyuk/lib/python3/cmk/gui/wato/pages/automation.py", line 168, in _execute_automation_command
    html.write(repr(automation.execute(automation.get_request())))
  File "/omd/sites/montyuk/lib/python3/cmk/gui/wato/pages/activate_changes.py", line 666, in execute
    return cmk.gui.watolib.activate_changes.execute_activate_changes(request.domains)
  File "/omd/sites/montyuk/lib/python3/cmk/gui/watolib/activate_changes.py", line 1781, in execute_activate_changes
    warnings = domain_class().activate()
  File "/omd/sites/montyuk/lib/python3/cmk/gui/watolib/config_domains.py", line 60, in activate
    return check_mk_local_automation(config.wato_activation_method)
  File "/omd/sites/montyuk/lib/python3/cmk/gui/watolib/automations.py", line 143, in check_mk_local_automation
    raise _local_automation_failure(command=command,
cmk.utils.exceptions.MKGeneralException: Error running automation call restart (exit code 1), error: 

An error occurred: Error creating configuration: 'NoneType' object has no attribute 'replace'



Now the problem lies i think at the wrapper code for your active check.
Every active check has a small code part inside the /share/check_mk/checks/ folder and is processed at the time of activating the changes. Your code needs to be inside the corresponding local folder.

1 Like

Hello @andreas-doehler the check actualy is quite simple for now check it below and i placed it in local/share/check_mk/checks/

#!/usr/bin/python

def check_esim_profile_args(params):
    description, settings = params
    print(description, settings)


def check_esim_profile_desc(params):
    print(params)

active_check_info['esim_profile'] = {
    "command_line": '$USER2$/check_esim_profile $ARG1$',
    "argument_function": check_esim_profile_args,
    "service_description" : check_esim_profile_desc,
    "has_perfdata"        : True,
}

i added the argument_function and the command_line just trying to copy the check_dns but i don’t need any args i just want to pass the values from the WATO to the check file.

A-ha!
Those two Functions have to return something. You are not returning anything, which means python implicityly returns “None”. The Backend expects a string, tries to sanitize it (using “replace”), and crashes.
Try


#!/usr/bin/python

def check_esim_profile_args(params):
    # assuming 'your_actvice_check --option an-option-value YourHOST' is how you call your active check
    return ["--option", "an-option-value", host_name()]


def check_esim_profile_desc(params):
    return "This is my service description"

active_check_info['esim_profile'] = {
    "command_line": '$USER2$/check_esim_profile $ARG1$',
    "argument_function": check_esim_profile_args,
    "service_description" : check_esim_profile_desc,
    "has_perfdata"        : True,
}
1 Like

Ayeee this is it, sorry i forgot to tell that i was able to implement the active check successfully thanks you all!

another note i found this handy tutorial here too:
https://www.steinkogler.org/2016/08/21/check-mk-write-your-own-active-check/

but i have one more question, sorry i’m asking too much but i’m used to custom scripts, but not this active checks, okay the error is gone using your suggestion, but i have another problem, how do i debug this to check how to check is behaving and fix what is required, on normal checks i used cmk -nv --debug /check_esim_profile--detect-plugins={{check_name}} {{sitename}}' i tried to do the same here cmk -nv --debug --detect-plugins=esim_profile CheckMK_MontyHolding but i’m not getting any response from the print instructions.

That is because the active checks are not triggert by cmk HOST.
The above functions are run when the configuration is generated, which you can trigger by cmk -U.
You can then take a look at the final result of the commandline call in the details view of the service (“Service check command”).

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed. Contact an admin if you think this should be re-opened.