Bug fixes: Changed Histograms to Gages and updated the dashboards

This commit is contained in:
Gleb Tcivie 2024-07-26 20:04:22 +03:00
parent 3cfadccc27
commit 0b487336fb
8 changed files with 1038 additions and 878 deletions

2
.env
View file

@ -13,7 +13,7 @@ MQTT_PORT=1883
MQTT_USERNAME=meshdev MQTT_USERNAME=meshdev
MQTT_PASSWORD=large4cats MQTT_PASSWORD=large4cats
MQTT_KEEPALIVE=60 MQTT_KEEPALIVE=60
MQTT_TOPIC='msh/israel/#' MQTT_TOPIC='msh/#'
MQTT_IS_TLS=false MQTT_IS_TLS=false
# MQTT protocol version (default: MQTTv5) the public MQTT server supports MQTTv311 # MQTT protocol version (default: MQTTv5) the public MQTT server supports MQTTv311

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,5 @@
CREATE EXTENSION IF NOT EXISTS moddatetime;
CREATE TABLE IF NOT EXISTS messages CREATE TABLE IF NOT EXISTS messages
( (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
@ -29,13 +31,10 @@ CREATE TABLE IF NOT EXISTS node_details
role VARCHAR, role VARCHAR,
mqtt_status VARCHAR default 'none', mqtt_status VARCHAR default 'none',
-- Location Data -- Location Data
longitude FLOAT, longitude INT,
latitude FLOAT, latitude INT,
altitude FLOAT, altitude INT,
precision FLOAT, precision INT,
country VARCHAR,
city VARCHAR,
state VARCHAR,
-- SQL Data -- SQL Data
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL

View file

@ -12,7 +12,7 @@ except ImportError:
from meshtastic.protobuf.mesh_pb2 import MeshPacket, Data, HardwareModel from meshtastic.protobuf.mesh_pb2 import MeshPacket, Data, HardwareModel
from meshtastic.protobuf.portnums_pb2 import PortNum from meshtastic.protobuf.portnums_pb2 import PortNum
from prometheus_client import CollectorRegistry, Counter, Histogram, Gauge from prometheus_client import CollectorRegistry, Counter, Gauge
from psycopg_pool import ConnectionPool from psycopg_pool import ConnectionPool
from exporter.client_details import ClientDetails from exporter.client_details import ClientDetails
@ -46,10 +46,14 @@ class MessageProcessor:
'destination_role' 'destination_role'
] ]
self.message_size_in_bytes = Histogram( reduced_labels = [
'source_id', 'destination_id'
]
self.message_size_in_bytes = Gauge(
'text_message_app_size_in_bytes', 'text_message_app_size_in_bytes',
'Size of text messages processed by the app in Bytes', 'Size of text messages processed by the app in Bytes',
common_labels + ['portnum'], reduced_labels + ['portnum'],
registry=self.registry registry=self.registry
) )
@ -74,7 +78,7 @@ class MessageProcessor:
registry=self.registry registry=self.registry
) )
# Histogram for the rx_time (time in seconds) # Histogram for the rx_time (time in seconds)
self.rx_time_histogram = Histogram( self.rx_time_histogram = Gauge(
'mesh_packet_rx_time', 'mesh_packet_rx_time',
'Receive time of mesh packets (seconds since 1970)', 'Receive time of mesh packets (seconds since 1970)',
common_labels, common_labels,
@ -205,10 +209,15 @@ class MessageProcessor:
'destination_role': destination_client_details.role, 'destination_role': destination_client_details.role,
} }
reduced_labels = {
'source_id': source_client_details.node_id,
'destination_id': destination_client_details.node_id
}
self.message_size_in_bytes.labels( self.message_size_in_bytes.labels(
**common_labels, **reduced_labels,
portnum=self.get_port_name_from_portnum(port_num) portnum=self.get_port_name_from_portnum(port_num)
).observe(sys.getsizeof(mesh_packet)) ).set(sys.getsizeof(mesh_packet))
self.source_message_type_counter.labels( self.source_message_type_counter.labels(
**common_labels, **common_labels,
@ -226,7 +235,7 @@ class MessageProcessor:
self.rx_time_histogram.labels( self.rx_time_histogram.labels(
**common_labels **common_labels
).observe(mesh_packet.rx_time) ).set(mesh_packet.rx_time)
self.rx_snr_gauge.labels( self.rx_snr_gauge.labels(
**common_labels **common_labels

View file

@ -167,7 +167,7 @@ class NodeInfoAppProcessor(Processor):
conn.commit() conn.commit()
self.metrics.db.execute_db_operation(db_operation) self.metrics.get_db().execute_db_operation(db_operation)
@ProcessorRegistry.register_processor(PortNum.ROUTING_APP) @ProcessorRegistry.register_processor(PortNum.ROUTING_APP)
@ -499,24 +499,8 @@ class NeighborInfoAppProcessor(Processor):
except Exception as e: except Exception as e:
logger.error(f"Failed to parse NEIGHBORINFO_APP packet: {e}") logger.error(f"Failed to parse NEIGHBORINFO_APP packet: {e}")
return return
self.update_node_graph(neighbor_info, client_details)
self.update_node_neighbors(neighbor_info, client_details) self.update_node_neighbors(neighbor_info, client_details)
def update_node_graph(self, neighbor_info: NeighborInfo, client_details: ClientDetails):
def operation(cur, conn):
cur.execute("""
INSERT INTO node_graph (node_id, last_sent_by_node_id, broadcast_interval_secs)
VALUES (%s, %s, %s)
ON CONFLICT (node_id)
DO UPDATE SET
last_sent_by_node_id = EXCLUDED.last_sent_by_node_id,
broadcast_interval_secs = EXCLUDED.broadcast_interval_secs,
last_sent_at = CURRENT_TIMESTAMP
""", (client_details.node_id, neighbor_info.last_sent_by_id, neighbor_info.node_broadcast_interval_secs))
conn.commit()
self.metrics.db.execute_db_operation(operation)
def update_node_neighbors(self, neighbor_info: NeighborInfo, client_details: ClientDetails): def update_node_neighbors(self, neighbor_info: NeighborInfo, client_details: ClientDetails):
def operation(cur, conn): def operation(cur, conn):
new_neighbor_ids = [str(neighbor.node_id) for neighbor in neighbor_info.neighbors] new_neighbor_ids = [str(neighbor.node_id) for neighbor in neighbor_info.neighbors]
@ -549,7 +533,7 @@ class NeighborInfoAppProcessor(Processor):
conn.commit() conn.commit()
self.metrics.db.execute_db_operation(operation) self.metrics.get_db().execute_db_operation(operation)
@ProcessorRegistry.register_processor(PortNum.ATAK_PLUGIN) @ProcessorRegistry.register_processor(PortNum.ATAK_PLUGIN)

View file

@ -1,4 +1,5 @@
import geopy.point import uuid
from geopy.geocoders import Nominatim from geopy.geocoders import Nominatim
from prometheus_client import CollectorRegistry, Counter, Gauge from prometheus_client import CollectorRegistry, Counter, Gauge
@ -19,9 +20,12 @@ class _Metrics:
self._registry = registry self._registry = registry
self._init_metrics() self._init_metrics()
self.initialized = True # Attribute to indicate initialization self.initialized = True # Attribute to indicate initialization
self.geolocator = Nominatim() self.geolocator = Nominatim(user_agent=f"meshtastic-prometheus-exporter-{str(uuid.uuid4())}")
self.db = db self.db = db
def get_db(self):
return self.db
@staticmethod @staticmethod
def _get_common_labels(): def _get_common_labels():
return [ return [
@ -36,19 +40,21 @@ class _Metrics:
self._init_route_discovery_metrics() self._init_route_discovery_metrics()
def update_metrics_position(self, latitude, longitude, altitude, precision, client_details: ClientDetails): def update_metrics_position(self, latitude, longitude, altitude, precision, client_details: ClientDetails):
point = geopy.point.Point(latitude, longitude, altitude) # Could be used to calculate more complex data (Like distances etc..)
location = self.geolocator.reverse(point, language='en') # point = geopy.point.Point(latitude, longitude, altitude) # Not used for now
country = location.raw.get('address', {}).get('country', 'Unknown') if latitude != 0 and longitude != 0:
city = location.raw.get('address', {}).get('city', 'Unknown') # location = RateLimiter(self.geolocator.reverse, min_delay_seconds=10, swallow_exceptions=False)((latitude, longitude), language='en', timeout=10)
state = location.raw.get('address', {}).get('state', 'Unknown') # country = location.raw.get('address', {}).get('country', 'Unknown')
# city = location.raw.get('address', {}).get('city', 'Unknown')
# state = location.raw.get('address', {}).get('state', 'Unknown')
def db_operation(cur, conn): def db_operation(cur, conn):
cur.execute(""" cur.execute("""
UPDATE node_details UPDATE node_details
SET latitude = %s, longitude = %s, altitude = %s, precision = %s, country = %s, city = %s, state = %s SET latitude = %s, longitude = %s, altitude = %s, precision = %s
WHERE node_id = %s WHERE node_id = %s
""", (latitude, longitude, altitude, precision, country, city, state, client_details.node_id)) """, (latitude, longitude, altitude, precision, client_details.node_id))
conn.commit() conn.commit()
self.db.execute_db_operation(db_operation) self.db.execute_db_operation(db_operation)

View file

@ -7,3 +7,4 @@ psycopg~=3.1.19
psycopg_pool~=3.2.2 psycopg_pool~=3.2.2
meshtastic~=2.3.13 meshtastic~=2.3.13
psycopg-binary~=3.1.20 psycopg-binary~=3.1.20
geopy>=2.4.1