Compare commits
10 Commits
b23afaeac8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 684d6ab857 | |||
| 4a051f02d9 | |||
| 9ec41da15e | |||
| 14e62c4a6c | |||
| aaafebdef1 | |||
| f564068ea5 | |||
| b794cbd6cf | |||
| d65f7e3f1f | |||
| 3133d64a6e | |||
| f7444768c4 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/.venv/
|
||||||
|
.idea/
|
||||||
18
Dockerfile
Normal file
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Use the official Python image from the Docker Hub
|
||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
# Set the working directory inside the container
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the requirements file and the script into the container
|
||||||
|
COPY requirements.txt .
|
||||||
|
COPY tmobile_monitor.py .
|
||||||
|
|
||||||
|
# Install the Python dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Expose the port that the Prometheus client will use
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Run the script
|
||||||
|
CMD ["python", "tmobile_monitor.py"]
|
||||||
32
README.md
Normal file
32
README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# LTE/5G Router Metrics Exporter
|
||||||
|
|
||||||
|
This project provides a simple Prometheus exporter that collects signal metrics
|
||||||
|
from a local network device (commonly a home LTE/5G router) by scraping its
|
||||||
|
web interface at `http://192.168.1.1`.
|
||||||
|
|
||||||
|
The exporter parses the router’s status page using BeautifulSoup and exposes
|
||||||
|
the following metrics on port **8000**:
|
||||||
|
|
||||||
|
- `snr` — Signal-to-Noise Ratio
|
||||||
|
- `rsrp` — Reference Signal Received Power
|
||||||
|
- `rsrq` — Reference Signal Received Quality
|
||||||
|
|
||||||
|
These metrics can be scraped by Prometheus and visualized in Grafana.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Scrapes metrics directly from your router's HTML status page
|
||||||
|
- Exposes them in Prometheus format
|
||||||
|
- Lightweight and easy to deploy
|
||||||
|
- Designed to run continuously (default refresh interval: **10 seconds**)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install requests beautifulsoup4 prometheus_client
|
||||||
35
main.py
35
main.py
@@ -1,35 +0,0 @@
|
|||||||
import requests
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
|
|
||||||
url = 'http://192.168.1.1'
|
|
||||||
|
|
||||||
response = requests.get(url, verify=False)
|
|
||||||
soup = BeautifulSoup(response.text, 'html.parser')
|
|
||||||
snr_element = soup.find('div', id='snr')
|
|
||||||
pci_element = soup.find('div', id='pci')
|
|
||||||
rsrp_element = soup.find('div', id='internetStatusRSRP')
|
|
||||||
rsrq_element = soup.find('div', id='internetStatusRSRQ')
|
|
||||||
|
|
||||||
if snr_element:
|
|
||||||
snr_value = snr_element.text.strip().split()[0] # Extracting the numerical part
|
|
||||||
print(f"SNR value: {snr_value}")
|
|
||||||
else:
|
|
||||||
print("SNR value not found on the page.")
|
|
||||||
|
|
||||||
if pci_element:
|
|
||||||
pci_value = pci_element.text.strip()
|
|
||||||
print(f"PCI value: {pci_value}")
|
|
||||||
else:
|
|
||||||
print("PCI value not found on the page.")
|
|
||||||
|
|
||||||
if rsrp_element:
|
|
||||||
rsrp_value = rsrp_element.text.strip()
|
|
||||||
print(f"RSRP value: {rsrp_value}")
|
|
||||||
else:
|
|
||||||
print("RSRP value not found on the page.")
|
|
||||||
|
|
||||||
if rsrq_element:
|
|
||||||
rsrq_value = rsrq_element.text.strip()
|
|
||||||
print(f"RSRQ value: {rsrq_value}")
|
|
||||||
else:
|
|
||||||
print("RSRQ value not found on the page.")
|
|
||||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
requests~=2.31.0
|
||||||
|
beautifulsoup4~=4.12.3
|
||||||
|
prometheus_client~=0.20.0
|
||||||
39
tmobile_monitor.py
Normal file
39
tmobile_monitor.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import requests
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
from prometheus_client import start_http_server, Gauge
|
||||||
|
import time
|
||||||
|
|
||||||
|
metrics = {
|
||||||
|
'snr': Gauge('snr', 'Signal to Noise Ratio'),
|
||||||
|
'internetStatusRSRP': Gauge('rsrp', 'Reference Signal Received Power'),
|
||||||
|
'internetStatusRSRQ': Gauge('rsrq', 'Reference Signal Received Quality')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def collect_metrics():
|
||||||
|
url = 'http://192.168.1.1'
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(url, verify=False)
|
||||||
|
response.raise_for_status()
|
||||||
|
soup = BeautifulSoup(response.text, 'html.parser')
|
||||||
|
|
||||||
|
for key in metrics:
|
||||||
|
element = soup.find('div', id=key)
|
||||||
|
if element:
|
||||||
|
value = float(element.text.strip().split()[0])
|
||||||
|
metrics[key].set(value)
|
||||||
|
else:
|
||||||
|
print(f"{key.upper()} value not found on the page.")
|
||||||
|
|
||||||
|
except requests.RequestException as e:
|
||||||
|
print(f"Error fetching data from {url}: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
start_http_server(8000)
|
||||||
|
print("HTTP server started on port 8000")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
collect_metrics()
|
||||||
|
time.sleep(10)
|
||||||
Reference in New Issue
Block a user