The latency graph does not show and perf-o-meter has no data

CMK version: RAW

Hi All, I am using a python script and use the intergrated nagios plugin rules with command line to do the http check for my company’s websites ( Due to the webiste is on cloud with WAF, the native checkmk’s http check check service doesn’t work, so i geneated a python script to simulate the browser traffic so it can bypass the WAF. The current situation is that , the script works and it returns the ok/critial state and realtime latency , but it doesn’t show the historical graph and there is no data un Perf-O-Meter . Can someone please help ? Thanks

Hey @MingC

the issue is that your Python script is not outputting performance data
in the Nagios plugin format. Without performance data, Checkmk has
nothing to feed into the RRD database — so no graphs and no Perf-O-Meter.

Nagios plugins must output performance data after a pipe character |:

OK - Website latency: 0.342s | latency=0.342s;1.0;2.0;0;

The format is:
label=value[unit][;warn][;crit][;min][;max]

So in your Python script, make sure the output looks like this:

import sys

latency = 0.342  # your measured value
warn = 1.0
crit = 2.0

print(f"OK - Latency: {latency:.3f}s | latency={latency:.3f}s;{warn};{crit};0;")
sys.exit(0)

Once the script outputs the | section correctly, Checkmk will
automatically start writing RRD data and the graph and Perf-O-Meter
will appear after the next check cycle.

Reference: https://docs.checkmk.com/latest/en/nagios_checks.html

Greetz Bernd

Thanks a lot.

we amended the script ,now the yellow graph icon appears and can see the data. But the Perf-O-meter still no empty, can you advise ? Thanks

Hi Ming

I didn`t know your Script but I have detailed explained in this thread how it works

Perfometer oder ein andere Namen für Wahnsinn? - Global Community / Deutsch - Checkmk Forum

Thank Bernd, below is my script. Appreciate if you can help check it. Thanks a millon

———————————————————–

#!/usr/bin/env python3

-*- coding: utf-8 -*-

import argparse
import sys
import time
import requests
from urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

def check_url(url: str,
timeout: int = 10,
verify_ssl: bool = True,
user_agent: str = “Checkmk-HTTP-Monitor/1.0”,
expected_string: str = None,
warn_ms: float = None,
crit_ms: float = None):
headers = {
“User-Agent”: user_agent,
“Accept”: “text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8”,
“Accept-Language”: “en-US,en;q=0.5”,
“Accept-Encoding”: “gzip, deflate”,
“Connection”: “keep-alive”,
“Upgrade-Insecure-Requests”: “1”,
}

start = time.time()
try:
    resp = requests.get(
        url,
        headers=headers,
        timeout=timeout,
        verify=verify_ssl,
        allow_redirects=True,
    )
    end = time.time()
    elapsed_ms = (end - start) \* 1000.0
    elapsed_s = (end - start)
    size = len(resp.content)



    if resp.status_code != 200:
        status_code = 2
        msg = f"HTTP CRITICAL - Status {resp.status_code} - time {elapsed_ms:.0f}ms - size {size}B - {url}"
    else:
        if crit_ms is not None and elapsed_ms > crit_ms:
            status_code = 2
            msg = (f"HTTP CRITICAL - response time {elapsed_ms:.0f}ms - threadshold {crit_ms:.0f}ms "
                   f"- Status 200 - size {size}B - {url}")
        elif warn_ms is not None and elapsed_ms > warn_ms:
            status_code = 1
            msg = (f"HTTP WARNING - response time {elapsed_ms:.0f}ms - threadshold {warn_ms:.0f}ms "
                   f"- Status 200 - size {size}B - {url}")
        else:
            status_code = 0
            msg = f"HTTP OK - Status 200 - time {elapsed_ms:.0f}ms - size {size}B - {url}"



        if expected_string:
            try:
                text = resp.text
            except Exception:
                text = resp.content.decode(resp.encoding or "utf-8", errors="ignore")
            if expected_string not in text:
                status_code = 2
                msg = (f"HTTP CRITICAL - expected string not found: '{expected_string}' "
                       f"- time {elapsed_ms:.0f}ms - Status 200 - size {size}B - {url}")



    \# === perfdata:用秒,不带单位;size 用字节纯数字 ===
    perf = f"latency={elapsed_ms:.0f}ms;"
    if warn_ms is not None or crit_ms is not None:
        warn_s = "" if warn_ms is None else (float(warn_ms))
        crit_s = "" if crit_ms is None else (float(crit_ms))
        perf += f"{warn_s};{crit_s};0;"
    else:
        perf += ";;;0;"



    perf += f" size={size};;;0;"



    print(f"{status_code} HTTP_Check {msg} | {perf}")
    return status_code



except requests.exceptions.SSLError as e:
    print(f"2 HTTP_Check HTTP CRITICAL - SSL Error: {e}")
    return 2
except requests.exceptions.Timeout as e:
    elapsed_ms = (time.time() - start) \* 1000.0
    print(f"2 HTTP_Check HTTP CRITICAL - Timeout after {elapsed_ms:.0f}ms: {e}")
    return 2
except requests.exceptions.ConnectionError as e:
    print(f"2 HTTP_Check HTTP CRITICAL - Connection Error: {e}")
    return 2
except requests.exceptions.RequestException as e:
    print(f"2 HTTP_Check HTTP CRITICAL - Request Error: {e}")
    return 2
except Exception as e:
    print(f"3 HTTP_Check HTTP UNKNOWN - {e}")
    return 3

def main():
parser = argparse.ArgumentParser(description=“Generic HTTP/HTTPS monitor for Checkmk/Nagios”)
parser.add_argument(“url”, help=“URL to monitor, e.g. https://example.com/health")
parser.add_argument(”-t", “–timeout”, type=int, default=10, help=“Timeout seconds (default: 10)”)
parser.add_argument(“–no-verify-ssl”, action=“store_false”, dest=“verify_ssl”,
help=“Disable SSL certificate verification”)
parser.add_argument(“-e”, “–expected-string”, help=“Expected string in response body (optional)”)
parser.add_argument(“-w”, “–warn-ms”, type=float, help=“Warning threshold for response time (ms)”)
parser.add_argument(“-c”, “–crit-ms”, type=float, help=“Critical threshold for response time (ms)”)
parser.add_argument(“–user-agent”, default=“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36”,
help=“Custom User-Agent (optional)”)
args = parser.parse_args()

if not args.url.startswith(("http://", "https://")):
    print("2 HTTP_Check HTTP CRITICAL - URL must start with http:// or https://")
    sys.exit(2)



rc = check_url(
    url=args.url,
    timeout=args.timeout,
    verify_ssl=args.verify_ssl,
    user_agent=args.user_agent,
    expected_string=args.expected_string,
    warn_ms=args.warn_ms,
    crit_ms=args.crit_ms,
)
sys.exit(rc)

if _name_ == “_main_”:
main()

I`ll take a look for that later … but on the first glance it looks like an old nagios plugin

perhaps a rewrite to the actual CMK check_api will be a better solution:

Plugin APIs — Checkmk’s Plug-in APIs documentation