1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-22 02:51:03 +00:00

Address review comments

Signed-off-by: Nathaniel Clark <Nathaniel.Clark@misrule.us>
This commit is contained in:
Nathaniel Clark 2020-09-24 08:30:11 -04:00 committed by Lars Kruse
parent 13e4b4aa94
commit 7b07874918
2 changed files with 104 additions and 62 deletions

View file

@ -1,29 +1,37 @@
#!/usr/bin/python #!/usr/bin/env python3
# modem:
#
# * upstream and downstream power levels
# * downstream signal to noise ratio
# * downstream error counts
#
# The values are retrieved from the cable modem's status web pages at
# 192.168.100.1. So, this plugin must be installed on a munin node
# which can access those pages.
#
# To install, place this plugin in the node's plugins directory,
# /etc/munin/plugins and restart munin-node.
#
# Developed and tested with:
# firmware: D30CM-OSPREY-2.4.0.1-GA-02-NOSH
# hardware version: 1
#
# Copyright 2020 Nathaniel Clark <nathaniel.clark@misrule.us> # Copyright 2020 Nathaniel Clark <nathaniel.clark@misrule.us>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published by
# the Free Software Foundation; version 2 only
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
""" """
=head1 NAME =head1 NAME
arris-sb6183 - Health monitoring plugin for Arris SB6183 Cable Modem arris-sb6183 - Health monitoring plugin for Arris SB6183 Cable Modem
=head1 DESCRIPTION
This provides the following multigraphs:
* upstream and downstream power levels
* downstream signal to noise ratio
* downstream error counts
The values are retrieved from the cable modem's status web pages at
192.168.100.1. So, this plugin must be installed on a munin node
which can access those pages.
=head1 CONFIGURATION =head1 CONFIGURATION
Make sure 192.168.100.1 is accessible through your firewall. Make sure 192.168.100.1 is accessible through your firewall.
@ -34,6 +42,12 @@ Also ensure that the hostname set is listed in munin.conf.
[arris*] [arris*]
env.hostname modem env.hostname modem
=head1 TESTING
Developed and tested with:
firmware: D30CM-OSPREY-2.4.0.1-GA-02-NOSH
hardware version: 1
=head1 VERSION =head1 VERSION
0.0.1 0.0.1
@ -57,14 +71,12 @@ GPLv2
import re import re
import os import os
import sys import sys
import requests from urllib import request
from lxml import html
URL = os.getenv("url", "http://192.168.100.1/RgConnect.asp")
HOSTNAME = os.getenv("hostname", None) HOSTNAME = os.getenv("hostname", None)
UPCOUNT = int(os.getenv("up", 4)) URL = "http://192.168.100.1/RgConnect.asp"
DOWNCOUNT = int(os.getenv("down", 16)) UPCOUNT = 4
DOWNCOUNT = 16
if len(sys.argv) == 2: if len(sys.argv) == 2:
if sys.argv[1] == "config": if sys.argv[1] == "config":
@ -83,7 +95,7 @@ if len(sys.argv) == 2:
for i in range(1, UPCOUNT + 1): for i in range(1, UPCOUNT + 1):
print("up_{0}.label Up Ch {1}".format(i, i)) print("up_{0}.label Up Ch {1}".format(i, i))
print("up_{0}.type GAUGE".format(i)) print("up_{0}.type GAUGE".format(i))
# print("up_{0}.draw LINE1".format(i)) print("up_{0}.draw LINE1".format(i))
for i in range(1, DOWNCOUNT + 1): for i in range(1, DOWNCOUNT + 1):
name = "down_{0}".format(i) name = "down_{0}".format(i)
@ -156,22 +168,34 @@ if len(sys.argv) == 2:
if sys.argv[1] == "autoconfig": if sys.argv[1] == "autoconfig":
try: try:
page = requests.get(URL) from lxml import html
except:
resp = request.urlopen(URL)
except ImportError:
print("no (missing lxml module)")
except OSError:
print("no (no router)") print("no (no router)")
else: else:
if page.status_code == 200: if resp.status == 200:
print("yes") print("yes")
else: else:
print("no (Bad status code: %d)" % page.status_code) print("no (Bad status code: %d)" % page.status_code)
sys.exit(0) sys.exit(0)
from lxml import html
rxblank = re.compile(r"[\x00\n\r\t ]+", re.MULTILINE) rxblank = re.compile(r"[\x00\n\r\t ]+", re.MULTILINE)
rxcomment = re.compile(r"<!--.*?-->") rxcomment = re.compile(r"<!--.*?-->")
rxscript = re.compile(r"<script.*?</script>", re.MULTILINE) rxscript = re.compile(r"<script.*?</script>", re.MULTILINE)
page = requests.get(URL) resp = request.urlopen(URL)
data = rxscript.sub("", rxcomment.sub("", rxblank.sub(" ", page.text))) data = rxscript.sub(
"",
rxcomment.sub(
"",
rxblank.sub(" ", "".join(map(lambda x: x.decode("utf-8"), resp.readlines()))),
),
)
dom = html.fromstring(data) dom = html.fromstring(data)
arr = dom.xpath('//table[contains(@class, "simpleTable")]') arr = dom.xpath('//table[contains(@class, "simpleTable")]')
@ -185,8 +209,6 @@ trs.pop(0)
headings = ["".join(x.itertext()).strip() for x in trs.pop(0).findall("td")] headings = ["".join(x.itertext()).strip() for x in trs.pop(0).findall("td")]
# ['Channel', 'Lock Status', 'Modulation', 'Channel ID', 'Frequency', 'Power', 'SNR', 'Corrected', 'Uncorrectables'] # ['Channel', 'Lock Status', 'Modulation', 'Channel ID', 'Frequency', 'Power', 'SNR', 'Corrected', 'Uncorrectables']
mapper = lambda x, y: (x, y)
# Summation Graphs # Summation Graphs
correct = 0 correct = 0
uncorr = 0 uncorr = 0
@ -194,9 +216,7 @@ power = {"up": ["U"] * UPCOUNT, "down": ["U"] * DOWNCOUNT}
snr = ["U"] * DOWNCOUNT snr = ["U"] * DOWNCOUNT
for row in trs: for row in trs:
data = dict( data = dict(
map( zip(headings, ["".join(x.itertext()).strip() for x in row.findall("td")])
mapper, headings, ["".join(x.itertext()).strip() for x in row.findall("td")]
)
) )
uncorr += int(data["Uncorrectables"]) uncorr += int(data["Uncorrectables"])
correct += int(data["Corrected"]) correct += int(data["Corrected"])
@ -245,9 +265,7 @@ headings = ["".join(x.itertext()).strip() for x in trs.pop(0).findall("td")]
# ['Channel', 'Lock Status', 'US Channel Type', 'Channel ID', 'Symbol Rate', 'Frequency', 'Power'] # ['Channel', 'Lock Status', 'US Channel Type', 'Channel ID', 'Symbol Rate', 'Frequency', 'Power']
for row in trs: for row in trs:
data = dict( data = dict(
map( zip(headings, ["".join(x.itertext()).strip() for x in row.findall("td")])
mapper, headings, ["".join(x.itertext()).strip() for x in row.findall("td")]
)
) )
channel = int(data["Channel"]) channel = int(data["Channel"])
print("multigraph arris_power.up_{0}".format(channel)) print("multigraph arris_power.up_{0}".format(channel))

View file

@ -1,21 +1,20 @@
#!/usr/bin/python #!/usr/bin/env python3
# modem:
#
# * uptime
#
# The values are retrieved from the cable modem's status web pages at
# 192.168.100.1. So, this plugin must be installed on a munin node
# which can access those pages.
#
# To install, place this plugin in the node's plugins directory,
# /etc/munin/plugins and restart munin-node.
#
# Developed and tested with:
# firmware: D30CM-OSPREY-2.4.0.1-GA-02-NOSH
# hardware version: 1
#
# Copyright 2020 Nathaniel Clark <nathaniel.clark@misrule.us> # Copyright 2020 Nathaniel Clark <nathaniel.clark@misrule.us>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published by
# the Free Software Foundation; version 2 only
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
""" """
=head1 NAME =head1 NAME
@ -32,6 +31,12 @@ Also ensure that the hostname set is listed in munin.conf.
[arris*] [arris*]
env.hostname modem env.hostname modem
=head1 TESTING
Developed and tested with:
firmware: D30CM-OSPREY-2.4.0.1-GA-02-NOSH
hardware version: 1
=head1 VERSION =head1 VERSION
0.0.1 0.0.1
@ -54,16 +59,16 @@ GPLv2
import re import re
import os import os
import sys import sys
import requests from urllib import request
from lxml import html
URL = os.getenv("url", "http://192.168.100.1/RgSwInfo.asp")
HOSTNAME = os.getenv("hostname", None) HOSTNAME = os.getenv("hostname", None)
URL = "http://192.168.100.1/RgSwInfo.asp"
if len(sys.argv) == 2: if len(sys.argv) == 2:
if sys.argv[1] == "config": if sys.argv[1] == "config":
print("host_name {0}".format(HOSTNAME)) if HOSTNAME:
print("host_name {0}".format(HOSTNAME))
# POWER # POWER
print( print(
@ -83,8 +88,12 @@ uptime.draw AREA
if sys.argv[1] == "autoconfig": if sys.argv[1] == "autoconfig":
try: try:
page = requests.get(URL) from lxml import html
except:
resp = request.urlopen(URL)
except ImportError:
print("no (missing lxml module)")
except OSError:
print("no (no router)") print("no (no router)")
else: else:
if page.status_code == 200: if page.status_code == 200:
@ -93,12 +102,27 @@ uptime.draw AREA
print("no (Bad status code: %d)" % page.status_code) print("no (Bad status code: %d)" % page.status_code)
sys.exit(0) sys.exit(0)
from lxml import html
rxblank = re.compile(r"[\x00\n\r\t ]+", re.MULTILINE) rxblank = re.compile(r"[\x00\n\r\t ]+", re.MULTILINE)
rxcomment = re.compile(r"<!--.*?-->") rxcomment = re.compile(r"<!--.*?-->")
rxscript = re.compile(r"<script.*?</script>", re.MULTILINE) rxscript = re.compile(r"<script.*?</script>", re.MULTILINE)
page = requests.get(URL) resp = request.urlopen(URL)
data = rxscript.sub("", rxcomment.sub("", rxblank.sub(" ", page.text))) if resp.status != 200:
print(
"failed to get status page %d: %s" % (resp.status, resp.reason), file=sys.stderr
)
print("uptime.value U")
sys.exit(0)
data = rxscript.sub(
"",
rxcomment.sub(
"",
rxblank.sub(" ", "".join(map(lambda x: x.decode("utf-8"), resp.readlines()))),
),
)
dom = html.fromstring(data) dom = html.fromstring(data)
arr = dom.xpath('//table[contains(@class, "simpleTable")]') arr = dom.xpath('//table[contains(@class, "simpleTable")]')