Files
potato-mesh/web/lib/potato_mesh/application/prometheus.rb

197 lines
5.8 KiB
Ruby

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# frozen_string_literal: true
module PotatoMesh
module App
module Prometheus
MESSAGES_TOTAL = ::Prometheus::Client::Counter.new(
:meshtastic_messages_total,
docstring: "Total number of messages received",
)
NODES_GAUGE = ::Prometheus::Client::Gauge.new(
:meshtastic_nodes,
docstring: "Number of nodes tracked",
)
NODE_GAUGE = ::Prometheus::Client::Gauge.new(
:meshtastic_node,
docstring: "Presence of a Meshtastic node",
labels: %i[node short_name long_name hw_model role],
)
NODE_BATTERY_LEVEL = ::Prometheus::Client::Gauge.new(
:meshtastic_node_battery_level,
docstring: "Battery level of a Meshtastic node",
labels: [:node],
)
NODE_VOLTAGE = ::Prometheus::Client::Gauge.new(
:meshtastic_node_voltage,
docstring: "Battery voltage of a Meshtastic node",
labels: [:node],
)
NODE_UPTIME = ::Prometheus::Client::Gauge.new(
:meshtastic_node_uptime_seconds,
docstring: "Uptime reported by a Meshtastic node",
labels: [:node],
)
NODE_CHANNEL_UTIL = ::Prometheus::Client::Gauge.new(
:meshtastic_node_channel_utilization,
docstring: "Channel utilization reported by a Meshtastic node",
labels: [:node],
)
NODE_AIR_UTIL_TX = ::Prometheus::Client::Gauge.new(
:meshtastic_node_transmit_air_utilization,
docstring: "Transmit air utilization reported by a Meshtastic node",
labels: [:node],
)
NODE_LATITUDE = ::Prometheus::Client::Gauge.new(
:meshtastic_node_latitude,
docstring: "Latitude of a Meshtastic node",
labels: [:node],
)
NODE_LONGITUDE = ::Prometheus::Client::Gauge.new(
:meshtastic_node_longitude,
docstring: "Longitude of a Meshtastic node",
labels: [:node],
)
NODE_ALTITUDE = ::Prometheus::Client::Gauge.new(
:meshtastic_node_altitude,
docstring: "Altitude of a Meshtastic node",
labels: [:node],
)
METRICS = [
MESSAGES_TOTAL,
NODES_GAUGE,
NODE_GAUGE,
NODE_BATTERY_LEVEL,
NODE_VOLTAGE,
NODE_UPTIME,
NODE_CHANNEL_UTIL,
NODE_AIR_UTIL_TX,
NODE_LATITUDE,
NODE_LONGITUDE,
NODE_ALTITUDE,
].freeze
METRICS.each do |metric|
::Prometheus::Client.registry.register(metric)
rescue ::Prometheus::Client::Registry::AlreadyRegisteredError
# Ignore duplicate registrations when the code is reloaded.
end
def update_prometheus_metrics(node_id, user = nil, role = "", met = nil, pos = nil)
ids = prom_report_ids
return if ids.empty? || !node_id
return unless ids[0] == "*" || ids.include?(node_id)
if user && user.is_a?(Hash) && role && role != ""
NODE_GAUGE.set(
1,
labels: {
node: node_id,
short_name: user["shortName"],
long_name: user["longName"],
hw_model: user["hwModel"],
role: role,
},
)
end
if met && met.is_a?(Hash)
if met["batteryLevel"]
NODE_BATTERY_LEVEL.set(met["batteryLevel"], labels: { node: node_id })
end
if met["voltage"]
NODE_VOLTAGE.set(met["voltage"], labels: { node: node_id })
end
if met["uptimeSeconds"]
NODE_UPTIME.set(met["uptimeSeconds"], labels: { node: node_id })
end
if met["channelUtilization"]
NODE_CHANNEL_UTIL.set(met["channelUtilization"], labels: { node: node_id })
end
if met["airUtilTx"]
NODE_AIR_UTIL_TX.set(met["airUtilTx"], labels: { node: node_id })
end
end
if pos && pos.is_a?(Hash)
if pos["latitude"]
NODE_LATITUDE.set(pos["latitude"], labels: { node: node_id })
end
if pos["longitude"]
NODE_LONGITUDE.set(pos["longitude"], labels: { node: node_id })
end
if pos["altitude"]
NODE_ALTITUDE.set(pos["altitude"], labels: { node: node_id })
end
end
end
def update_all_prometheus_metrics_from_nodes
nodes = query_nodes(1000)
NODES_GAUGE.set(nodes.size)
ids = prom_report_ids
unless ids.empty?
nodes.each do |n|
node_id = n["node_id"]
next if ids[0] != "*" && !ids.include?(node_id)
update_prometheus_metrics(
node_id,
{
"shortName" => n["short_name"] || "",
"longName" => n["long_name"] || "",
"hwModel" => n["hw_model"] || "",
},
n["role"] || "",
{
"batteryLevel" => n["battery_level"],
"voltage" => n["voltage"],
"uptimeSeconds" => n["uptime_seconds"],
"channelUtilization" => n["channel_utilization"],
"airUtilTx" => n["air_util_tx"],
},
{
"latitude" => n["latitude"],
"longitude" => n["longitude"],
"altitude" => n["altitude"],
},
)
end
end
end
end
end
end