Checkmk Managed Services Edition 2.1.0p28
Greetings plugin gurus. Here to ask for advice again.
I am currently working on a custom plugin for Broadworks related SNMP checks to replace an aging Cacti server.
My thought process is to check for a specific SNMP response for a vendor OID (e.g. ‘Broadworks Application Server’) and create a single service check called “Application Server” in CheckMK for the service to be running. I plan to expand the check to include other services and their associated metrics in the future but for now I am focusing on this.
There are multiple metrics associated with an “Application Server” such as Answer Delay, Auth Challenge, Network attempts. As of this time there are no defined requirements or thresholds to alarm on values for these additional metrics but I anticipate that may be requested in the future.
I think for my initial deployment I would like to include all of these metrics as graphs under the “Application Server” service rather than as individual services and graphs as I have now.
Could someone provide a link to a document, example(s) or describe the methodology to accomplish this? I understand my discovery will need to change to a single result but can’t find anything to start me working with multiple graphs under a single service.
As of this time I have the following file to detect all of the metrics but each as a service:
~/local/lib/check_mk/base/plugins/agent_based/broadworks.py
#!/usr/bin/env python3
# -*- encoding: utf-8; py-indent-offset: 4 -*-
from typing import Dict, List
from .agent_based_api.v1 import (
all_of,
equals,
contains,
register,
Metric,
Result,
SNMPTree,
Service,
State,
)
from .agent_based_api.v1.type_defs import (
StringTable,
StringByteTable,
CheckResult,
DiscoveryResult,
)
# Adding debug support
from cmk.utils import debug
from pprint import pprint
def parse_broadworks(string_table):
section = {}
if debug.enabled():
print("parser string_table contents:\n",type(string_table))
pprint(string_table)
fulllist = []
for itemlist in string_table:
for item in itemlist:
fulllist.extend(item)
if debug.enabled():
print("fulllist contents:\n",type(fulllist))
pprint(fulllist)
section['NetworkOrigAttempt'] = int(fulllist[0])
section['NetworkTermAttempt'] = int(fulllist[1])
section['NetworkTermAnswered'] = int(fulllist[2])
section['NetworkTotalCalls'] = int(fulllist[0]) + int(fulllist[2])
section['UserOrigAttempt'] = int(fulllist[3])
section['UserTermAttempt'] = int(fulllist[4])
section['UserTermAnswered'] = int(fulllist[5])
section['UserTotalCalls'] = int(fulllist[3]) + int(fulllist[5])
section['bwCallpActiveCalls'] = int(fulllist[6])
section['psOciStatsNbUpdateRequests'] = int(fulllist[7])
section['psOciStatsNbQueryRequests'] = int(fulllist[8])
section['bwSipStatsRegisterIns'] = int(fulllist[9])
section['bwSipStatsRegisterResponseOuts.200'] = int(fulllist[10])
section['bwSipStatsRegisterResponseOuts.401'] = int(fulllist[11])
section['bwSipStatsRegisterResponseOuts.403'] = int(fulllist[12])
section['bwSipStatsRegisterResponseOuts.404'] = int(fulllist[13])
section['bwSipStatsSetupSignalDelay'] = int(fulllist[14])
section['bwSipStatsMinSetupSignalDelay'] = int(fulllist[15])
section['bwSipStatsMaxSetupSignalDelay'] = int(fulllist[16])
section['bwSipStatsAnswerSignalDelay'] = int(fulllist[17])
section['bwSipStatsMinAnswerSignalDelay'] = int(fulllist[18])
section['bwSipStatsMaxAnswerSignalDelay'] = int(fulllist[19])
section['bwMeetMeNumPortsInUse'] = int(fulllist[20])
section['bwMeetMeNumJoinFailureLicensing'] = int(fulllist[21])
section['bwMeetMeNumActiveConferences'] = int(fulllist[22])
section['bwMeetMeNumJoinFailureMediaServerBusy'] = int(fulllist[23])
section['bwAuthenticationNumChallenges'] = int(fulllist[24])
section['bwAuthenticationNumValidResponses'] = int(fulllist[25])
section['nbOfMigratedUsers'] = int(fulllist[26])
return section
register.snmp_section(
name = "broadworks_as",
detect = all_of(
equals(".1.3.6.1.2.1.1.1.0", "Broadworks Application Server"),
contains(".1.3.6.1.4.1.6431.1.1.2.1.1.0", "Application Server")
),
parse_function = parse_broadworks,
fetch = [
SNMPTree(
base=".1.3.6.1.4.1.6431.1.2.7.1",
oids=[
"1.0", # BW-Execution::bwCallpNetworkOriginationAttempts.0 Counter32: <INT>
"2.0", # BW-Execution::bwCallpNetworkTerminationAttempts.0 Counter32: <INT>
"3.0", # BW-Execution::bwCallpNetworkTerminationsAnswered.0 Counter32: <INT>
"4.0", # BW-Execution::bwCallpUserOriginationAttempts.0 Counter32: <INT>
"5.0", # BW-Execution::bwCallpUserTerminationAttempts.0 Counter32: <INT>
"6.0", # BW-Execution::bwCallpUserTerminationsAnswered.0 Counter32: <INT>
"10.0", #BW-Execution::bwCallpActiveCalls.0 Gauge32: <INT>
],
),
SNMPTree(
base = ".1.3.6.1.4.1.6431.1.6.8.1",
oids = [
"1.0", # BW-Provisioning::psOciStatsNbUpdateRequests.0 Counter32: <INT>
"3.0", # BW-Provisioning::psOciStatsNbQueryRequests.0 Counter32: <INT>
],
),
SNMPTree(
base = ".1.3.6.1.4.1.6431.1.2.9.1",
oids = [
"12.0", # BW-Execution::bwSipStatsRegisterIns.0 Counter32: <INT>
"26.1.3.200", # BW-Execution::bwSipStatsRegisterResponseOuts.200 Counter32: <INT>
"26.1.3.401", # BW-Execution::bwSipStatsRegisterResponseOuts.401 Counter32: <INT>
"26.1.3.403", # BW-Execution::bwSipStatsRegisterResponseOuts.403 Counter32: <INT>
"26.1.3.404", # BW-Execution::bwSipStatsRegisterResponseOuts.404 Counter32: <INT>
"44.0", # BW-Execution::bwSipStatsSetupSignalDelay.0 Gauge32: <INT>
"45.0", # BW-Execution::bwSipStatsMinSetupSignalDelay.0 Gauge32: <INT>
"46.0", # BW-Execution::bwSipStatsMaxSetupSignalDelay.0 Gauge32: <INT>
"47.0", # BW-Execution::bwSipStatsAnswerSignalDelay.0 Gauge32: <INT>
"49.0", # BW-Execution::bwSipStatsMinAnswerSignalDelay.0 Gauge32: <INT>
"50.0", # BW-Execution::bwSipStatsMaxAnswerSignalDelay.0 Gauge32: <INT>
],
),
SNMPTree(
base = ".1.3.6.1.4.1.6431.1.2.18.1",
oids = [
"1.0", # BW-Execution::nbOfMigratedUsers.0 Gauge32: <INT>
],
),
SNMPTree(
base = ".1.3.6.1.4.1.6431.1.2.11",
oids = [
"89.3.0", # BW-Execution::bwMeetMeNumPortsInUse.0 Gauge32: <INT>
"89.6.0", # BW-Execution::bwMeetMeNumJoinFailureLicensing.0 Counter32: <INT>
"89.1.0", # BW-Execution::bwMeetMeNumActiveConferences.0 Gauge32: <INT>
"89.8.0", # BW-Execution::bwMeetMeNumJoinFailureMediaServerBusy.0 Counter32: <INT>
"3.1.0", # BW-Execution::bwAuthenticationNumChallenges.0 Counter32: <INT>
"3.2.0", # BW-Execution::bwAuthenticationNumValidResponses.0 Counter32: <INT>
],
)
],
)
def discover_broadworks(section) -> DiscoveryResult:
# section comes in as
# {'UserOrigAttempt': 0, 'UserTermAnswered': 0, 'UserTermAttempt': 0}
if debug.enabled():
pprint(section)
for item in section.keys():
yield Service(item=item)
def check_broadworks(item, params, section) -> CheckResult:
if debug.enabled():
pprint(item)
pprint(params)
pprint(section)
yield Result(state=State.OK, summary='Always OK, no thresholds')
yield Metric(item, section[item])
register.check_plugin(
name='broadworks',
sections=['broadworks_as'],
service_name='BW %s',
check_default_parameters={},
discovery_function=discover_broadworks,
check_function=check_broadworks,
)
This file for some logical grouping for some of the graphs
/local/share/check_mk/web/plugins/metrics/broadworks_metric.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from cmk.gui.i18n import _l
from cmk.gui.plugins.metrics.utils import graph_info, metric_info
# .
# .--Metrics-------------------------------------------------------------.
# | __ __ _ _ |
# | | \/ | ___| |_ _ __(_) ___ ___ |
# | | |\/| |/ _ \ __| '__| |/ __/ __| |
# | | | | | __/ |_| | | | (__\__ \ |
# | |_| |_|\___|\__|_| |_|\___|___/ |
# | |
# +----------------------------------------------------------------------+
# | Definitions of metrics |
# '----------------------------------------------------------------------'
# Title are always lower case - except the first character!
# Colors: See indexed_color() in cmk/gui/plugins/metrics/utils.py
metric_info["NetworkOrigAttempt"] = {
"title": _l("Net origination attempts per minute"),
"unit": "count",
"color": "11/a",
}
metric_info["NetworkTermAttempt"] = {
"title": _l("Net Termination attempts per minute"),
"unit": "count",
"color": "14/a",
}
metric_info["NetworkTermAnswered"] = {
"title": _l("Net termination answered per minute"),
"unit": "count",
"color": "21/a",
}
metric_info["NetworkTotalCalls"] = {
"title": _l("Net termination answered per minute"),
"unit": "count",
"color": "21/a",
}
metric_info["UserOrigAttempt"] = {
"title": _l("User origination attempts per minute"),
"unit": "count",
"color": "11/a",
}
metric_info["UserTermAttempt"] = {
"title": _l("User Termination attempts per minute"),
"unit": "count",
"color": "14/a",
}
metric_info["UserTermAnswered"] = {
"title": _l("User termination answered per minute"),
"unit": "count",
"color": "21/a",
}
metric_info["UserTotalCalls"] = {
"title": _l("User termination answered per minute"),
"unit": "count",
"color": "21/a",
}
# .
# .--Graphs--------------------------------------------------------------.
# | ____ _ |
# | / ___|_ __ __ _ _ __ | |__ ___ |
# | | | _| '__/ _` | '_ \| '_ \/ __| |
# | | |_| | | | (_| | |_) | | | \__ \ |
# | \____|_| \__,_| .__/|_| |_|___/ |
# | |_| |
# +----------------------------------------------------------------------+
# | Definitions of time series graphs |
# '----------------------------------------------------------------------'
graph_info["bw_as_network_attempts"] = {
"title": _l("Bw as network attempts"),
"metrics": [
("NetworkOrigAttempt", "area"),
("NetworkTermAttempt", "stack"),
("NetworkTermAnswered", "line"),
("NetworkTotalCalls", "line"),
],
}
graph_info["bw_as_user_attempts"] = {
"title": _l("Bw as user attempts"),
"metrics": [
("UserOrigAttempt", "area"),
("UserTermAttempt", "stack"),
("UserTermAnswered", "line"),
("UserTotalCalls", "line"),
],
}
Critiques, guidance and advice is greatly appreciated. Mistakes are all mine and how I learn.
Sincerely,
Scotsie