mirror of
https://github.com/kemko/keenetic-grafana-monitoring.git
synced 2026-01-01 15:45:43 +03:00
Dockerize and type mapping
This commit is contained in:
committed by
Vitaliy Skrypnyk
parent
74109908c4
commit
2c4788e8a3
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
.idea
|
.idea
|
||||||
*.iml
|
*.iml
|
||||||
|
config/influx.json
|
||||||
10
Dockerfile
Normal file
10
Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
FROM python:3
|
||||||
|
|
||||||
|
ADD keentic_influxdb_exporter.py /home
|
||||||
|
ADD requirements.txt /home
|
||||||
|
ADD value_normalizer.py /home
|
||||||
|
ADD influxdb_writter.py /home
|
||||||
|
ADD config/metrics.json /home/config/metrics.json
|
||||||
|
|
||||||
|
RUN pip install -r /home/requirements.txt
|
||||||
|
CMD [ "python", "-u", "/home/keentic_influxdb_exporter.py" ]
|
||||||
48
README.md
Normal file
48
README.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
```
|
||||||
|
_ __ _ _ _____ _ _ _
|
||||||
|
| |/ / | | (_) / ____| | | | | |
|
||||||
|
| ' / ___ ___ _ __ ___| |_ _ ___ | | ___ | | | ___ ___| |_ ___ _ __
|
||||||
|
| < / _ \/ _ \ '_ \ / _ \ __| |/ __| | | / _ \| | |/ _ \/ __| __/ _ \| '__|
|
||||||
|
| . \ __/ __/ | | | __/ |_| | (__ | |___| (_) | | | __/ (__| || (_) | |
|
||||||
|
|_|\_\___|\___|_| |_|\___|\__|_|\___| \_____\___/|_|_|\___|\___|\__\___/|_|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
# Build from sources
|
||||||
|
|
||||||
|
`docker build -t keenetic-grafana-monitoring .`
|
||||||
|
|
||||||
|
# Preparation
|
||||||
|
|
||||||
|
* Create InfluxDB configuration file `influx.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"influxdb": {
|
||||||
|
"host": "<HOST>",
|
||||||
|
"port": 80,
|
||||||
|
"username": "admin",
|
||||||
|
"password": "<PASS>",
|
||||||
|
"db": "keenetic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Expose Keenetic API on your router
|
||||||
|
|
||||||
|
For doing this add port forwarding (Network rules -> Forwarding):
|
||||||
|
```
|
||||||
|
Input: Other destination
|
||||||
|
IP address: Your network ip (like 192.168.1.0)
|
||||||
|
Subnet mask: 255.255.255.0
|
||||||
|
Output: This Keenetic
|
||||||
|
Open the port: 79
|
||||||
|
Destination port: 79
|
||||||
|
```
|
||||||
|
|
||||||
|
# Run with docker-compose.yml
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
9
config/influx.json.sample
Normal file
9
config/influx.json.sample
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"influxdb": {
|
||||||
|
"host": "<HOST>",
|
||||||
|
"port": 80,
|
||||||
|
"username": "admin",
|
||||||
|
"password": "<PASS>",
|
||||||
|
"db": "keenetic"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,6 @@
|
|||||||
{
|
{
|
||||||
"endpoint" : "http://192.168.1.1:79/rci",
|
"endpoint" : "http://192.168.1.1:79/rci",
|
||||||
"interval_sec" : 30,
|
"interval_sec" : 30,
|
||||||
"influxdb" : {
|
|
||||||
"host" : "",
|
|
||||||
"port" : 80,
|
|
||||||
"username" : "",
|
|
||||||
"password" : "",
|
|
||||||
"db" : ""
|
|
||||||
},
|
|
||||||
"metrics" : [
|
"metrics" : [
|
||||||
{
|
{
|
||||||
"command": "processes",
|
"command": "processes",
|
||||||
@@ -51,13 +44,13 @@
|
|||||||
"type": "$.type",
|
"type": "$.type",
|
||||||
"description": "$.description",
|
"description": "$.description",
|
||||||
"interface-name": "$.interface-name",
|
"interface-name": "$.interface-name",
|
||||||
"state": "$.state",
|
|
||||||
"address": "$.address"
|
"address": "$.address"
|
||||||
},
|
},
|
||||||
"values" : {
|
"values" : {
|
||||||
"mtu": "$.mtu",
|
"mtu": "$.mtu",
|
||||||
"uptime": "$.uptime",
|
"uptime": "$.uptime",
|
||||||
"tx-queue": "$.tx-queue"
|
"tx-queue": "$.tx-queue",
|
||||||
|
"state": "$.state"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -106,12 +99,12 @@
|
|||||||
"root" : "$.*.partition.[*]",
|
"root" : "$.*.partition.[*]",
|
||||||
"tags" : {
|
"tags" : {
|
||||||
"label" : "$.label",
|
"label" : "$.label",
|
||||||
"uuid" : "$.uuid",
|
"uuid" : "$.uuid"
|
||||||
"state" : "$.state"
|
|
||||||
},
|
},
|
||||||
"values" : {
|
"values" : {
|
||||||
"total": "$.total",
|
"total": "$.total",
|
||||||
"free": "$.free"
|
"free": "$.free",
|
||||||
|
"state" : "$.state"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -127,6 +120,20 @@
|
|||||||
"rxspeed": "$.rxspeed",
|
"rxspeed": "$.rxspeed",
|
||||||
"txspeed": "$.txspeed"
|
"txspeed": "$.txspeed"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "interface stat",
|
||||||
|
"root" : "$",
|
||||||
|
"param" : {
|
||||||
|
"name" : "PPTP0"
|
||||||
|
},
|
||||||
|
"tags" : {},
|
||||||
|
"values" : {
|
||||||
|
"rxbytes": "$.rxbytes",
|
||||||
|
"txbytes": "$.txbytes",
|
||||||
|
"rxspeed": "$.rxspeed",
|
||||||
|
"txspeed": "$.txspeed"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
11
docker-compose.yml
Normal file
11
docker-compose.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
keenetic-grafana-monitoring:
|
||||||
|
build: .
|
||||||
|
container_name: keenetic-grafana-monitoring
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Kiev
|
||||||
|
volumes:
|
||||||
|
- ./config/influx.json:/home/config/influx.json
|
||||||
|
restart: always
|
||||||
@@ -12,6 +12,7 @@ class InfuxWritter(object):
|
|||||||
def init_database(self):
|
def init_database(self):
|
||||||
print("Connecting to InfluxDB: " + self._configuration['host'])
|
print("Connecting to InfluxDB: " + self._configuration['host'])
|
||||||
db_name = self._configuration['db']
|
db_name = self._configuration['db']
|
||||||
|
# self._client.drop_database(db_name)
|
||||||
|
|
||||||
if db_name not in self._client.get_list_database():
|
if db_name not in self._client.get_list_database():
|
||||||
print("Creating InfluxDB database: " + db_name)
|
print("Creating InfluxDB database: " + db_name)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
from jsonpath_rw import parse
|
||||||
from jsonpath_ng.ext import parse
|
|
||||||
|
|
||||||
from influxdb_writter import InfuxWritter
|
from influxdb_writter import InfuxWritter
|
||||||
from value_normalizer import normalize_value
|
from value_normalizer import normalize_value
|
||||||
@@ -90,13 +90,15 @@ if __name__ == '__main__':
|
|||||||
print(
|
print(
|
||||||
" _ __ _ _ _____ _ _ _ \n | |/ / | | (_) / ____| | | | | | \n | ' / ___ ___ _ __ ___| |_ _ ___ | | ___ | | | ___ ___| |_ ___ _ __ \n | < / _ \/ _ \ '_ \ / _ \ __| |/ __| | | / _ \| | |/ _ \/ __| __/ _ \| '__|\n | . \ __/ __/ | | | __/ |_| | (__ | |___| (_) | | | __/ (__| || (_) | | \n |_|\_\___|\___|_| |_|\___|\__|_|\___| \_____\___/|_|_|\___|\___|\__\___/|_| \n \n ")
|
" _ __ _ _ _____ _ _ _ \n | |/ / | | (_) / ____| | | | | | \n | ' / ___ ___ _ __ ___| |_ _ ___ | | ___ | | | ___ ___| |_ ___ _ __ \n | < / _ \/ _ \ '_ \ / _ \ __| |/ __| | | / _ \| | |/ _ \/ __| __/ _ \| '__|\n | . \ __/ __/ | | | __/ |_| | (__ | |___| (_) | | | __/ (__| || (_) | | \n |_|\_\___|\___|_| |_|\___|\__|_|\___| \_____\___/|_|_|\___|\___|\__\___/|_| \n \n ")
|
||||||
|
|
||||||
configuration = json.load(open("config.json", "r"))
|
metrics_configuration = json.load(open(os.path.dirname(os.path.realpath(__file__)) + "/config/metrics.json", "r"))
|
||||||
endpoint = configuration['endpoint']
|
influx_configuration = json.load(open(os.path.dirname(os.path.realpath(__file__)) + "/config/influx.json", "r"))
|
||||||
metrics = configuration['metrics']
|
|
||||||
|
endpoint = metrics_configuration['endpoint']
|
||||||
|
metrics = metrics_configuration['metrics']
|
||||||
|
|
||||||
collectors = []
|
collectors = []
|
||||||
|
|
||||||
infuxdb_writter = InfuxWritter(configuration)
|
infuxdb_writter = InfuxWritter(influx_configuration)
|
||||||
|
|
||||||
print("Connecting to router: " + endpoint)
|
print("Connecting to router: " + endpoint)
|
||||||
|
|
||||||
@@ -104,8 +106,8 @@ if __name__ == '__main__':
|
|||||||
print("Configuring metric: " + metric_configuration['command'])
|
print("Configuring metric: " + metric_configuration['command'])
|
||||||
collectors.append(KeeneticCollector(infuxdb_writter, endpoint, metric_configuration))
|
collectors.append(KeeneticCollector(infuxdb_writter, endpoint, metric_configuration))
|
||||||
|
|
||||||
print("Configuration done. Start collecting with interval: " + str(configuration['interval_sec']) + " sec")
|
print("Configuration done. Start collecting with interval: " + str(metrics_configuration['interval_sec']) + " sec")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
for collector in collectors: collector.collect()
|
for collector in collectors: collector.collect()
|
||||||
time.sleep(configuration['interval_sec'])
|
time.sleep(metrics_configuration['interval_sec'])
|
||||||
|
|||||||
@@ -1,16 +1,2 @@
|
|||||||
certifi==2020.6.20
|
|
||||||
chardet==3.0.4
|
|
||||||
decorator==4.4.2
|
|
||||||
idna==2.10
|
|
||||||
influxdb==5.3.0
|
influxdb==5.3.0
|
||||||
jsonpath==0.82
|
jsonpath-rw==1.4.0
|
||||||
jsonpath-ng==1.5.1
|
|
||||||
msgpack==0.6.1
|
|
||||||
parse==1.16.0
|
|
||||||
ply==3.11
|
|
||||||
prometheus-client==0.8.0
|
|
||||||
python-dateutil==2.8.1
|
|
||||||
pytz==2020.1
|
|
||||||
requests==2.24.0
|
|
||||||
six==1.15.0
|
|
||||||
urllib3==1.25.10
|
|
||||||
|
|||||||
@@ -6,11 +6,24 @@ def isfloat(value: str): return (re.match(r'^-?\d+(?:\.\d+)?$', value) is not No
|
|||||||
def isinteger(value: str): return (re.match('^\d+$', value) is not None)
|
def isinteger(value: str): return (re.match('^\d+$', value) is not None)
|
||||||
def isvalidmetric(value) : return isinstance(value, int) or isinstance(value, float) or isinstance(value, bool)
|
def isvalidmetric(value) : return isinstance(value, int) or isinstance(value, float) or isinstance(value, bool)
|
||||||
|
|
||||||
|
type_mapping = {
|
||||||
|
"yes" : 1,
|
||||||
|
"no" : 0,
|
||||||
|
"up" : 1,
|
||||||
|
"down" : 0,
|
||||||
|
True: 1,
|
||||||
|
False: 0,
|
||||||
|
"MOUNTED" : 1,
|
||||||
|
"UNMOUNTED" : 0
|
||||||
|
}
|
||||||
|
|
||||||
def normalize_value(value):
|
def normalize_value(value):
|
||||||
|
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
value = type_mapping.get(value) if type_mapping.get(value) is not None else value
|
||||||
|
|
||||||
if isstring(value):
|
if isstring(value):
|
||||||
value = parse_string(value)
|
value = parse_string(value)
|
||||||
|
|
||||||
@@ -22,11 +35,14 @@ def normalize_value(value):
|
|||||||
|
|
||||||
|
|
||||||
def parse_string(value):
|
def parse_string(value):
|
||||||
|
|
||||||
value = remove_data_unit(value)
|
value = remove_data_unit(value)
|
||||||
|
|
||||||
if isinteger(value):
|
if isinteger(value):
|
||||||
value = int(value)
|
value = int(value)
|
||||||
elif isfloat(value):
|
elif isfloat(value):
|
||||||
value = float(value)
|
value = float(value)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user