1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-25 10:28:36 +00:00

Merge both SB6183 plugins

Add more error handling for bad status from modem

Signed-off-by: Nathaniel Clark <Nathaniel.Clark@misrule.us>
This commit is contained in:
Nathaniel Clark 2020-09-24 08:48:06 -04:00 committed by Lars Kruse
parent 7b07874918
commit 77e5305923
2 changed files with 95 additions and 168 deletions

View file

@ -27,6 +27,7 @@ This provides the following multigraphs:
* upstream and downstream power levels
* downstream signal to noise ratio
* downstream error counts
* 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
@ -74,7 +75,8 @@ import sys
from urllib import request
HOSTNAME = os.getenv("hostname", None)
URL = "http://192.168.100.1/RgConnect.asp"
STATUS_URL = "http://192.168.100.1/RgConnect.asp"
INFO_URL = "http://192.168.100.1/RgSwInfo.asp"
UPCOUNT = 4
DOWNCOUNT = 16
@ -83,6 +85,22 @@ if len(sys.argv) == 2:
if HOSTNAME:
print("host_name {0}\n".format(HOSTNAME))
# UPTIME
print(
"""multigraph arris_uptime
graph_title Modem Uptime
graph_category system
graph_args --base 1000 -l 0
graph_vlabel uptime in days
graph_scale no
graph_category system
graph_info This graph shows the number of days that the the host is up and running so far.
uptime.label uptime
uptime.info The system uptime itself in days.
uptime.draw AREA
"""
)
# POWER
print("multigraph arris_power")
print("graph_title Arris Power (dBmV)")
@ -170,7 +188,7 @@ if len(sys.argv) == 2:
try:
from lxml import html
resp = request.urlopen(URL)
resp = request.urlopen(STATUS_URL)
except ImportError:
print("no (missing lxml module)")
except OSError:
@ -188,26 +206,70 @@ rxblank = re.compile(r"[\x00\n\r\t ]+", re.MULTILINE)
rxcomment = re.compile(r"<!--.*?-->")
rxscript = re.compile(r"<script.*?</script>", re.MULTILINE)
resp = request.urlopen(URL)
data = rxscript.sub(
"",
rxcomment.sub(
def process_url(url):
"""
Extract simpleTables from page at URL
"""
try:
resp = request.urlopen(url)
except OSError:
print("failed to contact router", file=sys.stderr)
return []
if resp.status != 200:
print(
"failed to get status page %d: %s" % (resp.status, resp.reason),
file=sys.stderr,
)
return []
data = rxscript.sub(
"",
rxblank.sub(" ", "".join(map(lambda x: x.decode("utf-8"), resp.readlines()))),
),
)
dom = html.fromstring(data)
rxcomment.sub(
"",
rxblank.sub(
" ", "".join(map(lambda x: x.decode("utf-8"), resp.readlines()))
),
),
)
dom = html.fromstring(data)
arr = dom.xpath('//table[contains(@class, "simpleTable")]')
downstream = arr[1]
upstream = arr[2]
return dom.xpath('//table[contains(@class, "simpleTable")]')
trs = downstream.findall("tr")
# drop title
trs.pop(0)
headings = ["".join(x.itertext()).strip() for x in trs.pop(0).findall("td")]
# ['Channel', 'Lock Status', 'Modulation', 'Channel ID', 'Frequency', 'Power', 'SNR', 'Corrected', 'Uncorrectables']
print("multi_graph arris_uptime")
arr = process_url(INFO_URL)
if arr:
trs = arr[1].findall("tr")
# drop title
trs.pop(0)
date = "".join(trs[0].findall("td")[1].itertext()).strip()
arr = date.split(" ")
rx = re.compile(r"[hms]")
days = int(arr[0])
hms = rx.sub("", arr[2]).split(":")
seconds = ((days * 24 + int(hms[0])) * 60 + int(hms[1])) * 60 + int(hms[2])
print("uptime.value {0}".format(seconds / 86400.0))
else:
print("uptime.value U")
arr = process_url(STATUS_URL)
if arr:
downstream = arr[1]
upstream = arr[2]
trs = downstream.findall("tr")
# drop title
trs.pop(0)
headings = ["".join(x.itertext()).strip() for x in trs.pop(0).findall("td")]
# ['Channel', 'Lock Status', 'Modulation', 'Channel ID', 'Frequency', 'Power', 'SNR', 'Corrected', 'Uncorrectables']
else:
trs = []
headings = []
# Summation Graphs
correct = 0
@ -223,7 +285,7 @@ for row in trs:
channel = int(data["Channel"])
print("multigraph arris_power.down_{0}".format(channel))
print("\nmultigraph arris_power.down_{0}".format(channel))
value = data["Power"].split(" ")[0]
print("power.value {0}".format(value))
power["down"][channel - 1] = value
@ -239,7 +301,7 @@ for row in trs:
# Fill missing
for i in range(len(trs), DOWNCOUNT):
print("multigraph arris_power.down_{0}".format(i + 1))
print("\nmultigraph arris_power.down_{0}".format(i + 1))
print("power.value U")
print("multigraph arris_snr.down_{0}".format(i + 1))
@ -250,19 +312,25 @@ for i in range(len(trs), DOWNCOUNT):
print("uncr.value U")
print("multigraph arris_error")
print("corr.value {0}".format(correct))
print("uncr.value {0}".format(uncorr))
if arr:
print("corr.value {0}".format(correct))
print("uncr.value {0}".format(uncorr))
else:
print("corr.value U")
print("uncr.value U")
print("multigraph arris_snr")
for i in range(0, DOWNCOUNT):
print("down_{0}.value {1}".format(i + 1, snr[i]))
trs = upstream.findall("tr")
# drop title
trs.pop(0)
if arr:
trs = upstream.findall("tr")
# drop title
trs.pop(0)
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']
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']
for row in trs:
data = dict(
zip(headings, ["".join(x.itertext()).strip() for x in row.findall("td")])

View file

@ -1,141 +0,0 @@
#!/usr/bin/env python3
# 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
arris-sb6183_uptime - Uptime monitoring for Arris SB6183 Cable Modem
=head1 CONFIGURATION
Make sure 192.168.100.1 is accessible through your firewall.
To have this register with munin as it's own host set the "env.hostname" in config.
Also ensure that the hostname set is listed in munin.conf.
[arris*]
env.hostname modem
=head1 TESTING
Developed and tested with:
firmware: D30CM-OSPREY-2.4.0.1-GA-02-NOSH
hardware version: 1
=head1 VERSION
0.0.1
=head1 AUTHOR
Nathaniel Clark <nathaniel.clark@misrule.us>
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=contrib
#%# capabilities=autoconf
=cut
"""
import re
import os
import sys
from urllib import request
HOSTNAME = os.getenv("hostname", None)
URL = "http://192.168.100.1/RgSwInfo.asp"
if len(sys.argv) == 2:
if sys.argv[1] == "config":
if HOSTNAME:
print("host_name {0}".format(HOSTNAME))
# POWER
print(
"""graph_title Modem Uptime
graph_category system
graph_args --base 1000 -l 0
graph_vlabel uptime in days
graph_scale no
graph_category system
graph_info This graph shows the number of days that the the host is up and running so far.
uptime.label uptime
uptime.info The system uptime itself in days.
uptime.draw AREA
"""
)
sys.exit(0)
if sys.argv[1] == "autoconfig":
try:
from lxml import html
resp = request.urlopen(URL)
except ImportError:
print("no (missing lxml module)")
except OSError:
print("no (no router)")
else:
if page.status_code == 200:
print("yes")
else:
print("no (Bad status code: %d)" % page.status_code)
sys.exit(0)
from lxml import html
rxblank = re.compile(r"[\x00\n\r\t ]+", re.MULTILINE)
rxcomment = re.compile(r"<!--.*?-->")
rxscript = re.compile(r"<script.*?</script>", re.MULTILINE)
resp = request.urlopen(URL)
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)
arr = dom.xpath('//table[contains(@class, "simpleTable")]')
trs = arr[1].findall("tr")
# drop title
trs.pop(0)
date = "".join(trs[0].findall("td")[1].itertext()).strip()
arr = date.split(" ")
rx = re.compile(r"[hms]")
days = int(arr[0])
hms = rx.sub("", arr[2]).split(":")
seconds = ((days * 24 + int(hms[0])) * 60 + int(hms[1])) * 60 + int(hms[2])
print("uptime.value {0}".format(seconds / 86400.0))