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:
parent
13e4b4aa94
commit
7b07874918
2 changed files with 104 additions and 62 deletions
|
@ -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))
|
||||||
|
|
|
@ -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")]')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue