Check plugin with Metrics

Hello, its me again. Since the first check_mk plugin is running smoothly, thanks to Marius, I wrote the next plugin for an antenna and this wasn’t that funny but its working really fine. Since the Antenna is only supporting SNMP v1 you don’t discover a lot of services, its like 3 Interfaces and thats it.

I want to monitor some of the values as Metric so I followed for the Metric Stuff this docs:

But I didn’t make it so far. I tested the yield Metric(…) stuff with the rxCapacity which gets an in and the txCapcity which gets an int too.
http://www.circitor.fr/Mibs/Html/U/UBNT-AirFIBER-MIB.php#rxCapacity

Because the whole Plugin is really really long I try to add only the important parts :slight_smile:

def check_airfiber_port(item, section):
    #meassure = section[item].get(2)
    #if meassure == None:
    #    meassure = ""
    # https://docs.checkmk.com/latest/en/dev_guidelines.html

    # If the Entry gets the tag "True" it will be handled as Metric
    if section[item][1]:
        used = int(section[item][0])
        yield Metric(item, used)
        #yield Result(state=State.OK, summary=section[item][0])
    else:
        yield Result(state=State.OK, summary=section[item][0])

section[item][0] is the value in the case of rxCapacity and txCapacity its already an int.
section[item][1] is a bool which I set in my parse function for values which I want as Metric

If I use the default Result(...) the value will be displayed as whole number in checkmk and is marked as OK. If I use the Metric(...) the status switches to Unknown and the summary is Item not found in monitoring data. And I do not understand why this happens.

I also added under ~/local/share/check_mk/web/plugins/metrics$ an airfiber_metrics.py plugin with the following input:

from cmk.gui.i18n import _
from cmk.gui.plugins.metrics import metric_info

metric_info["rxCapacity"] = {
    "title": _("rxCapacity"),
    "unit": "Bits/Sec",
    "color": "14/a",
}
metric_info["txCapacity"] = {
    "title": _("txCapacity"),
    "unit": "Bits/Sec",
    "color": "15/a",
}

I also added airfiber_performeter.py too
~/local/share/check_mk/web/plugins/perfometer$

from cmk.gui.plugins.metrics import perfometer_info

perfometer_info.append({
    "type": "logarithmic",
    "metric": "Port rxCapacity",
    "half_value": 5,
    "exponent": 2.0,
})

perfometer_info.append({
    "type": "logarithmic",
    "metric": "Port txCapacity",
    "half_value": 5,
    "exponent": 2.0,
})

I want to have some Metrics / Performance data, that I can quickly see how its going :slight_smile:

Maybe one of you have an idea how to proceed :slight_smile:
If you need additional information, feel free to ask!

Regards Kai

Hi @kano

If a check does not return a Result at all its asumed its not found. However you can return Results and Metric at the same time.

yield Result(state=State.OK, summary='Interface is UP')
yield Result(state=State.WARN, summary='Power is low')
yield Metric('power', 55)
yield Metric('time', 22)

This Would result in a WARN State “Interface is UP, Power is low” as description and two metrics power and time returnd. yield unless return can be called multiple times within a function.

If you not only what to output the value but perform a check if it is in certain limits you can us the check_levels function from .agent_based_api.v1 it yields the result and the metric and performs the checks. I use this for example in phion_firewall.py

    yield from check_levels(
        section['traffic'], # The value to check
        levels_upper=params.get('traffic', None),
        label='Data Throughput',
        metric_name='traffic',
        render_func=lambda v: render.networkbandwidth(v / 8)
    )

The new perfometer syntax you are using belong into the same fiel as the metrics. Have a look at the metrics i defined for the phion_firewall plugin in local/share/check_mk/web/plugins/metrics/phion.py

On a side not. If you are creating a check for a type of device which checkmk has already support for but just not for you specific device. Then it would be best to check how the built in checks name there metrics and just name yours the same way. You then not even need to define the metrics and perfometer settings as checkmk already knows how to handle this kind of metrics. I tend to just check the metrics name of a similare service, the Service performance data (source code) field in the check details shows you all the metric.

Regards Marius

1 Like

Hey, Marius
thanks again for your fast reaction and help. I did some researched based on the input you gave me and I was able to add metrics :slight_smile:

For all with the same problem maybe:
Here is my airfiber_metrics.py
~/local/share/check_mk/web/plugins/metrics$

from cmk.gui.i18n import _
from cmk.gui.plugins.metrics import (
    metric_info,
    graph_info,
    perfometer_info,
)

metric_info["traffic"] = {
    "title": _("Traffic"),
    "unit": "bytes/s",
    "color": "13/a",
}

metric_info["rxCapacity"] = {
    "title": _("rxCapacity"),
    "unit": "bytes/s",
    "color": "33/a",
}

And here are the check_plugin function from the checkmk plugin:
~/local/lib/check_mk/base/plugins/agent_based$
Here you can see, at this time I create two times the same graph, this is just for testing, later on of them will disappear.

#check airfiber port
def check_airfiber_port(item, section):
    #meassure = section[item].get(2)
    #if meassure == None:
    meassure = ""

    # https://docs.checkmk.com/latest/en/dev_guidelines.html
    # If the Entry gets the tag "True" it will be handled as Metric
    if section[item][1]:
        used = int(section[item][0])
        yield Metric(name=item, value=used)

        # https://github.com/tribe29/checkmk/blob/40f17ba2ea6b74ccabee40bf86a817430ecdd5a6/cmk/base/api/agent_based/utils.py#L293
        yield from check_levels(
            used,                                                   # the value as int to check
            label = "Data Throughput",                              # Summary Text
            metric_name = 'traffic',                                # Name from metric which should be used
            render_func = lambda v: render.networkbandwidth(v / 8)  # Bits/Sec to MBits/Sec
        )
    yield Result(state=State.OK, summary="" + section[item][0] + " " + meassure)

Maybe I’ll modify my files later, but this is the first working solution I found :slight_smile:
Thanks!
Regards Kai

Hey guys, I have one more question, maybe I am blind, if yes, SORRY! I looked at this a decent amount of time already :slight_smile:

I created a airfiber-metrics.py in the ~/local/share/check_mk/web/plugins/metrics$ folder. And the “normal” metrics are working fine so far but the I’ll call it “combined” metrics/graphs are still a little bit like a blackbox for me right now.
In this file I have the code below:

metric_info["rxCapacity"] = {
    "title": _("Input Capacity"),
    "unit": "bytes/s",
    "color": "#2ecc71",
}

metric_info["txCapacity"] = {
    "title": _("Output Capacity"),
    "unit": "bytes/s",
    "color": "#3498db",
}

metric_info["rxoctetsAll"] = {
    "title": _("Input Octets All"),
    "unit": "bytes/s",
    "color": "#2ecc71",
}

metric_info["txoctetsAll"] = {
    "title": _("Output Octets All"),
    "unit": "bytes/s",
    "color": "#3498db",
}

graph_info.append({
    "title": _("Traffic"),
    "metrics":[
        ("rxoctetsAll", "area"),
        ("txoctetsAll", "-area"),
        ("rxCapacity", "line"),
        ("txCapacity", "-line"),
    ]
})

If the code is correct, where can I find the graph in checkmk? If the code isnt correct, how should it look like?

Kind Regards Kai

Hi, i think this would be correct.
graph_info.append({
“title”: _(“Traffic”),
“metrics”:[
(“rxoctetsAll”, “area”),
(“txoctetsAll”, “-area”),
(“rxCapacity”, “line”),
(“txCapacity”, “-line”),
],
})

The Graph should be shown with the check.

Regards,
Peter