Collection of CheckMK checks (see https://checkmk.com/). All checks and plugins are provided as is. Absolutely no warranty. Send any comments to thl-cmk[at]outlook[dot]com

Skip to content
Snippets Groups Projects
Commit 66a1fc0a authored by thl-cmk's avatar thl-cmk :flag_na:
Browse files

update project

parent 11d578b1
No related branches found
No related tags found
No related merge requests found
[PACKAGE]: ../../raw/master/packagee-0.1.2-20230706.mkp "package-0.1.2-20230706.mkp" [PACKAGE]: ../../raw/master/mkp/unbound-1.2.0-20240421.mkp "unbound-1.2.0-20240421.mkp"
# Title # Title
A short description about the plugin A short description about the plugin
......
File added
#!/usr/bin/env python3
# Copyright (C) 2022, Jan-Philipp Litza (PLUTEX) <jpl@plutex.de>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# https://nlnetlabs.nl/projects/unbound/about/
# changes by thl-cmk[at]outlook[dot]com
# 2024-04-21: removed Union -> no need "int | float" should do
# added levels_upper_NOERROR to default parameters -> show up in info line
from typing import (
Any,
Mapping,
# Union,
)
from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
CheckResult,
DiscoveryResult,
StringTable,
)
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
GetRateError,
Service,
check_levels,
get_rate,
get_value_store,
register,
render,
)
# UnboundSection = Mapping[str, Union[int, float, "UnboundSection"]]
UnboundSection = Mapping[str, int | float]
def render_qps(x: float) -> str:
return f'{x:.2f}/s'
def parse_unbound(string_table: StringTable) -> UnboundSection:
section = {}
for key, value in string_table:
try:
section[key] = int(value)
except ValueError:
section[key] = float(value)
return section
register.agent_section(
name="unbound",
parse_function=parse_unbound,
)
def discover_unbound_cache(section: UnboundSection) -> DiscoveryResult:
if 'total.num.cachehits' in section and 'total.num.cachemiss' in section:
yield Service()
def check_unbound_cache(
params: Mapping[str, Any],
section: UnboundSection,
) -> CheckResult:
cumulative_cache_hits = section.get('total.num.cachehits')
cumulative_cache_miss = section.get('total.num.cachemiss')
now = section.get('time.now')
if None in (cumulative_cache_hits, cumulative_cache_miss, now):
return
cache_hits = get_rate(
get_value_store(),
'unbound_cache_hits',
now,
cumulative_cache_hits,
raise_overflow=True,
)
cache_miss = get_rate(
get_value_store(),
'unbound_cache_miss',
now,
cumulative_cache_miss,
raise_overflow=True,
)
total = cache_hits + cache_miss
hit_perc = (cache_hits / float(total)) * 100.0 if total != 0 else 100.0
yield from check_levels(
value=cache_miss,
metric_name="cache_misses_rate",
levels_upper=params.get("cache_misses"),
render_func=render_qps,
label='Cache Misses',
notice_only=True,
)
yield from check_levels(
value=cache_hits,
metric_name="cache_hit_rate",
render_func=render_qps,
label='Cache Hits',
notice_only=True,
)
yield from check_levels(
value=hit_perc,
metric_name="cache_hit_ratio",
levels_lower=params.get("cache_hits"),
render_func=render.percent,
label='Cache Hit Ratio',
)
register.check_plugin(
name="unbound_cache",
service_name="Unbound Cache",
sections=["unbound"],
discovery_function=discover_unbound_cache,
check_function=check_unbound_cache,
check_default_parameters={},
check_ruleset_name="unbound_cache",
)
def discover_unbound_answers(section: UnboundSection) -> DiscoveryResult:
if 'time.now' in section and 'num.answer.rcode.SERVFAIL' in section:
yield Service()
def check_unbound_answers(params: Mapping, section: UnboundSection) -> CheckResult:
key_prefix = 'num.answer.rcode.'
if 'time.now' not in section:
return
now = section['time.now']
total = sum(
value for key, value in section.items()
if key.startswith(key_prefix)
)
for key, value in section.items():
if not key.startswith(key_prefix):
continue
answer = key[len(key_prefix):]
try:
rate = get_rate(
get_value_store(),
f'unbound_answers_{answer}',
now,
value,
raise_overflow=True,
)
except GetRateError:
pass
else:
levels_upper = params.get(f'levels_upper_{answer}')
if levels_upper is not None and len(levels_upper) == 3:
# levels on the ratio of answers
levels_upper = (
levels_upper[0] * total,
levels_upper[1] * total,
)
yield from check_levels(
value=rate,
levels_upper=levels_upper,
metric_name=f'unbound_answers_{answer}',
render_func=render_qps,
label=answer,
notice_only=f'levels_upper_{answer}' not in params,
)
register.check_plugin(
name="unbound_answers",
service_name="Unbound Answers",
sections=["unbound"],
discovery_function=discover_unbound_answers,
check_function=check_unbound_answers,
check_default_parameters={
'levels_upper_NOERROR': (101,101),
'levels_upper_SERVFAIL': (10, 100),
'levels_upper_REFUSED': (10, 100),
},
check_ruleset_name="unbound_answers",
)
def discover_unbound_unwanted_replies(section: UnboundSection) -> DiscoveryResult:
if 'time.now' in section and 'unwanted.replies' in section:
yield Service()
def check_unbound_unwanted_replies(section: UnboundSection) -> CheckResult:
if 'time.now' not in section or 'unwanted.replies' not in section:
return
rate = get_rate(
get_value_store(),
'unbound_unwanted_replies',
section['time.now'],
section['unwanted.replies'],
raise_overflow=True,
)
yield from check_levels(
value=rate,
levels_upper=(10, 100),
metric_name='unbound_unwanted_replies',
render_func=render_qps,
label='Unwanted Replies',
)
register.check_plugin(
name="unbound_unwanted_replies",
service_name="Unbound Unwanted Replies",
sections=["unbound"],
discovery_function=discover_unbound_unwanted_replies,
check_function=check_unbound_unwanted_replies,
)
#!/bin/sh
echo '<<<unbound:sep(61)>>>'
unbound-control stats_noreset
echo '<<<>>>'
title: Dummy check man page - used as template for new check manuals
agents: linux, windows, aix, solaris, hpux, vms, freebsd, snmp
catalog: see modules/catalog.py for possible values
license: GPL
distribution: check_mk
description:
Describe here: (1) what the check actually does, (2) under which
circumstances it goes warning/critical, (3) which devices are supported
by the check, (4) if the check requires a separated plugin or
tool or separate configuration on the target host.
item:
Describe the syntax and meaning of the check's item here. Provide all
information one needs if coding a manual check with {checks +=} in {main.mk}.
Give an example. If the check uses {None} as sole item,
then leave out this section.
examples:
# Give examples for configuration in {main.mk} here. If the check has
# configuration variable, then give example for them here.
# set default levels to 40 and 60 percent:
foo_default_values = (40, 60)
# another configuration variable here:
inventory_foo_filter = [ "superfoo", "superfoo2" ]
perfdata:
Describe precisely the number and meaning of performance variables
the check sends. If it outputs no performance data, then leave out this
section.
inventory:
Describe how the inventory for the check works. Which items
will it find? Describe the influence of check specific
configuration parameters to the inventory.
[parameters]
foofirst(int): describe the first parameter here (if parameters are grouped
as tuple)
fooother(string): describe another parameter here.
[configuration]
foo_default_levels(int, int): Describe global configuration variable of
foo here. Important: also tell the user how they are preset.
#!/usr/bin/env python3
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# Copyright (C) 2022, Jan-Philipp Litza (PLUTEX) <jpl@plutex.de>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# modifications by thl-cmk[at]outlook[dot]com
# 2024-02-21: changed import path form mk.gui.plugins.metrics to mk.gui.plugins.metrics.utils
# added metrics/graph for unbound_unwanted_replies
# moved to ~/local/lib/check_mk/gui/plugins/metrics (from local/share/check_mk/web/plugins/metrics)
# added perfometer for unbound_answers (NOERROR/SERVFAIL) and unbound_unwanted_replies
from cmk.gui.i18n import _
from cmk.gui.plugins.metrics.utils import (
metric_info,
graph_info,
perfometer_info,
)
metric_info['unbound_answers_NOERROR'] = {
'title': _('Rate of NOERROR answers'),
'unit': '1/s',
'color': '31/a',
}
metric_info['unbound_answers_FORMERR'] = {
'title': _('Rate of FORMERR answers'),
'unit': '1/s',
'color': '21/a',
}
metric_info['unbound_answers_SERVFAIL'] = {
'title': _('Rate of SERVFAIL answers'),
'unit': '1/s',
'color': '11/a',
}
metric_info['unbound_answers_NXDOMAIN'] = {
'title': _('Rate of NXDOMAIN answers'),
'unit': '1/s',
'color': '51/a',
}
metric_info['unbound_answers_NOTIMPL'] = {
'title': _('Rate of NOTIMPL answers'),
'unit': '1/s',
'color': '41/a',
}
metric_info['unbound_answers_REFUSED'] = {
'title': _('Rate of REFUSED answers'),
'unit': '1/s',
'color': '26/a',
}
metric_info['unbound_answers_nodata'] = {
'title': _('Rate of answers without data'),
'unit': '1/s',
'color': '52/a',
}
graph_info['unbound_answers'] = {
'title': _('Rate of answers'),
'metrics': [
(f'unbound_answers_{answer}', 'line')
for answer in ('NOERROR', 'FORMERR', 'SERVFAIL', 'NXDOMAIN', 'NOTIMPL', 'REFUSED', 'nodata')
],
}
perfometer_info.append(('stacked', [
{
'type': 'logarithmic',
'metric': 'unbound_answers_NOERROR',
'half_value': 100.0, # ome year
'exponent': 2,
},
{
'type': 'logarithmic',
'metric': 'unbound_answers_SERVFAIL',
'half_value': 50.0,
'exponent': 2,
},
]))
metric_info['cache_hit_rate'] = {
'title': _('Cache hits per second'),
'unit': '1/s',
'color': '26/a',
}
graph_info['cache_hit_misses'] = {
'title': _('Cache Hits and Misses'),
'metrics': [('cache_hit_rate', 'line'), ('cache_misses_rate', 'line')],
}
metric_info['unbound_unwanted_replies'] = {
'title': _('Unwanted replies'),
'unit': '1/s',
'color': '26/a',
}
graph_info['unbound_unwanted_replies'] = {
'title': _('Unwanted replies'),
'metrics': [('unbound_unwanted_replies', 'area')],
}
perfometer_info.append({
'type': 'logarithmic',
'metric': 'unbound_unwanted_replies',
'half_value': 100.0, # ome year
'exponent': 2,
})
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2022, Jan-Philipp Litza (PLUTEX) <jpl@plutex.de>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# modifications by thl-cmk[at]outlook[dot]com
# 2024-04-21: fixed missing FixedValue in import
# changed Alternative titles to "Upper levels in qps"/"Upper levels in %" to better differentiate between them
# added explicit unit "%2
# added ruleset for bakery
# renamed to unbound.py (from unbound_parameters.py)
# moved to ~/local/lib/check_mk/gui/plugins/wato/check_parameters (from local/share/check_mk/web/plugins/wato)
#
from cmk.gui.i18n import _
from cmk.gui.plugins.wato.utils import (
CheckParameterRulespecWithoutItem,
rulespec_registry,
RulespecGroupCheckParametersApplications,
HostRulespec,
)
from cmk.gui.cee.plugins.wato.agent_bakery.rulespecs.utils import (
RulespecGroupMonitoringAgentsAgentPlugins,
)
from cmk.gui.valuespec import Dictionary, Float, Percentage, Tuple, Alternative, FixedValue
def _parameter_valuespec_unbound_cache():
return Dictionary(
title=_("Unbound: Cache"),
elements=[
(
"cache_misses",
Tuple(
title="Levels on cache misses per second",
elements=[
Float(
title="warn",
),
Float(
title="crit",
),
],
),
),
(
"cache_hits",
Tuple(
title="Lower levels for hits in %",
elements=[
Percentage(
title="warn",
),
Percentage(
title="crit",
),
],
),
),
],
)
rulespec_registry.register(
CheckParameterRulespecWithoutItem(
check_group_name="unbound_cache",
group=RulespecGroupCheckParametersApplications,
match_type="dict",
parameter_valuespec=_parameter_valuespec_unbound_cache,
title=lambda: _("Unbound Cache"),
)
)
def _parameter_valuespec_unbound_answers():
return Dictionary(
elements=[
(
f"levels_upper_{answer}",
Alternative(
title=f'Upper levels for {answer} answers',
show_alternative_title=True,
elements=[
Tuple(
elements=[
Float(title=_("Warning at"), unit=_("qps")),
Float(title=_("Critical at"), unit=_("qps")),
],
title=f'Upper levels in qps',
),
Tuple(
elements=[
Percentage(title=_("Warning at"), unit=_("%")),
Percentage(title=_("Critical at"), unit=_("%")),
FixedValue(value="%", totext=""), # need to decide between both variants
],
title=f'Upper levels in %',
),
]
)
)
for answer in (
'NOERROR',
'FORMERR',
'SERVFAIL',
'NXDOMAIN',
'NOTIMPL',
'REFUSED',
'nodata',
)
],
)
rulespec_registry.register(
CheckParameterRulespecWithoutItem(
check_group_name="unbound_answers",
group=RulespecGroupCheckParametersApplications,
match_type="dict",
parameter_valuespec=_parameter_valuespec_unbound_answers,
title=lambda: _("Unbound Answers"),
)
)
def _parameter_valuespec_unbound_bakery():
return Alternative(
title=_('unbound'),
elements=[
FixedValue(
True,
title=_('Deploy the unbound agent plugin'),
totext=_('The unbound agent plugin will be deployed')
),
FixedValue(
None,
title=_('Do not deploy the unbound agent plugin'),
totext=_('The unbound agent plugin will not be deployed')
),
],
)
rulespec_registry.register(
HostRulespec(
group=RulespecGroupMonitoringAgentsAgentPlugins,
name='agent_config:unbound',
valuespec=_parameter_valuespec_unbound_bakery,
)
)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# License: GNU General Public License v2
#
# Author: thl-cmk[at]outlook[dot]com
# URL : https://thl-cmk.hopto.org
# Date : 2024-04-21
# File : share/check_mk/agents/unbound.py
#
# bakery unbound plugin
#
from pathlib import Path
from cmk.base.cee.plugins.bakery.bakery_api.v1 import (
FileGenerator,
OS,
Plugin,
register
)
def get_unbound_files(conf) -> FileGenerator:
if conf is True:
yield Plugin(
base_os=OS.LINUX,
source=Path('unbound'),
)
register.bakery_plugin(
name='unbound',
files_function=get_unbound_files,
)
{'author': 'Jan-Philipp Litza <jpl@plutex.de>',
'description': 'Plugin to gather statistics from unbound caching DNS resolver '
'via agent plugin. It monitors answer types, cache hit ratio '
'and miss rate as well as unwanted reply rate.\n'
'\n'
'needs in server config:\n'
' server:\n'
' extended-statistics: yes\n',
'download_url': 'https://github.com/PLUTEX/checkmk-unbound/',
'files': {'agent_based': ['unbound.py'],
'agents': ['plugins/unbound'],
'gui': ['metrics/unbound.py', 'wato/check_parameters/unbound.py'],
'lib': ['python3/cmk/base/cee/plugins/bakery/unbound.py']},
'name': 'unbound',
'title': 'Unbound',
'version': '1.2.0-20240421',
'version.min_required': '2.2.0b1',
'version.packaged': '2.2.0p24',
'version.usable_until': None}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment