diff --git a/agent_based/traefik_info.py b/agent_based/traefik_info.py new file mode 100644 index 0000000..233dcc5 --- /dev/null +++ b/agent_based/traefik_info.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +# pylint: disable=missing-module-docstring, unused-argument, +# pylint: disable=missing-function-docstring, line-too-long + +from pprint import pprint + +from cmk.utils import debug + +# import necessary elements from API version 2 +from cmk.agent_based.v2 import ( + AgentSection, + CheckPlugin, + Service, + State, + Metric, + Result, + DiscoveryResult, + CheckResult, +) + + +def get_state_upper( + levels: tuple[int | float, int | float], value: int | float +) -> State: + """returns OK/WARN/CRIT depending on the given parameters""" + warn, crit = levels + if value >= crit: + return State.CRIT + if value >= warn: + return State.WARN + return State.OK + + +def parse_traefik_info(string_table): + """the parse function""" + parsed_data = {} + for line in string_table: + if line[0] == "Traefik_Version": + parsed_data["version"] = line[1] + elif line[0] == "Traefik_CodeName": + parsed_data["codename"] = line[1] + elif line[0] == "Traefik_StartDate": + parsed_data["startdate"] = line[1] + elif line[0] == "Agent_Runtime": + # convert seconds into ms + parsed_data["agent_runtime"] = float(line[1]) * 1_000 + elif line[0] == "Agent_Version": + parsed_data["agent_version"] = line[1] + return parsed_data + + +def discover_traefik_info(section) -> DiscoveryResult: + """the discover function""" + yield Service() + + +def check_traefik_info(params, section) -> CheckResult: + """the check function""" + if debug.enabled(): + pprint(section) + _level_type, levels = params["levels_traefik_agent_execution_time"] + codename: str = section["codename"] + version: str = section["version"] + startdate: str = section["startdate"] + agent_version: str = section["agent_version"] + agent_runtime: float = section["agent_runtime"] + state: State = get_state_upper(levels=levels, value=agent_runtime) + + yield Metric( + name="traefik_agent_execution_time", + value=agent_runtime, + levels=levels, + ) + summary: str = f"Traefik version: {version}, code name: {codename}" + details: str = f"Traefik start date: {startdate}\nAgent version: {agent_version}\nAgent execution time: {agent_runtime}" + yield Result(state=state, summary=summary, details=details) + + +# create the new agent section, must begin with "agent_section_" +# and must be an instance of "AgentSection" +agent_section_traefik_info = AgentSection( + # "name" must exactly match the section name within the agent output + name="traefik_info", + # define the parse function, name is arbitrary, a good choice is to choose + # "parse_" as prefix and append the section name + parse_function=parse_traefik_info, +) + +# create the new check plugin, must begin with "check_plugin_" +# and must be an instance of "CheckPlugin" +check_plugin_traefik_info = CheckPlugin( + # "name" should be the same as the corresponding section within the agent output + name="traefik_info", + service_name="Traefik Info", + # define the discovery function, name is arbitrary, a good choice is to choose + # "discover_" as prefix and append the section name + discovery_function=discover_traefik_info, + # define the check function, name is arbitrary, a good choice is to choose + # "check_" as prefix and append the section name + check_function=check_traefik_info, + # define the default parameters + check_default_parameters={ + "levels_traefik_agent_execution_time": ("fixed", (500.0, 750.0)) + }, + # connect to the ruleset where parameters can be defined + # must match the name of the ruleset exactly + check_ruleset_name="traefik_info", +) diff --git a/checkman/traefik_info b/checkman/traefik_info new file mode 100644 index 0000000..d666d32 --- /dev/null +++ b/checkman/traefik_info @@ -0,0 +1,10 @@ +title: Traefik: Various information +agents: linux +catalog: unsorted +license: GPL +distribution: check_mk +description: + Shows several information about a Traefik instance, e.g. version and code name. + The check will raise WARN/CRIT if the agent execution time is above the configurable levels. +inventory: + one service is created (with several details) \ No newline at end of file diff --git a/graphing/graph_traefik.py b/graphing/graph_traefik.py new file mode 100644 index 0000000..024c5a8 --- /dev/null +++ b/graphing/graph_traefik.py @@ -0,0 +1,23 @@ +# pylint: disable=unused-import +"""graphing and metrics definitions""" + +from cmk.graphing.v1 import Title + +# from cmk.graphing.v1.graphs import Graph, MinimalRange +from cmk.graphing.v1.metrics import Color, DecimalNotation, Metric, Unit +from cmk.graphing.v1.perfometers import Closed, FocusRange, Perfometer + +metric_traefik_agent_execution_time = Metric( + # "name" must be exactly the "metric_name" within the check function + name="traefik_agent_execution_time", + title=Title("Agent execution time"), + unit=Unit(DecimalNotation("ms")), + color=Color.DARK_ORANGE, +) + +perfometer_traefik_agent_execution_time = Perfometer( + name="traefik_agent_execution_time", + focus_range=FocusRange(Closed(0), Closed(100)), + # "segments" must be exactly the name of the metric + segments=["traefik_agent_execution_time"], +) diff --git a/rulesets/rs_traefik_info.py b/rulesets/rs_traefik_info.py new file mode 100644 index 0000000..317ddce --- /dev/null +++ b/rulesets/rs_traefik_info.py @@ -0,0 +1,49 @@ +#!/user/bin/env python3 +"""general parameter form for Traefik""" + +from cmk.rulesets.v1 import Title, Help +from cmk.rulesets.v1.form_specs import ( + DictElement, + Dictionary, + SimpleLevels, + DefaultValue, + Float, + LevelDirection, +) + +from cmk.rulesets.v1.rule_specs import CheckParameters, Topic, HostCondition + + +# function name should begin with an underscore to limit it's visibility +def _parameter_form(): + return Dictionary( + elements={ + "levels_traefik_agent_execution_time": DictElement( + parameter_form=SimpleLevels( + title=Title("Levels for agent execution time"), + help_text=Help( + "Define the levels for the maximum agent execution time" + ), + form_spec_template=Float(unit_symbol="ms"), + level_direction=LevelDirection.UPPER, + prefill_fixed_levels=DefaultValue(value=(500.0, 750.0)), + ), + required=True, + ), + } + ) + + +# name must begin with "rule_spec_", should refer to the used check plugin +# must be an instance of "CheckParameters" +rule_spec_traefik_info = CheckParameters( + # "name" should be the same as the check plugin + name="traefik_info", + # the title is shown in the GUI + title=Title("Traefik general parameters"), + # this ruleset can be found under Setup|Service monitoring rules|Applications... + topic=Topic.APPLICATIONS, + # define the name of the function which creates the GUI elements + parameter_form=_parameter_form, + condition=HostCondition(), +)