60 lines
1.4 KiB
Elixir
60 lines
1.4 KiB
Elixir
defmodule Localiser.MQTT.Telemetry do
|
|
@moduledoc """
|
|
GenServer responsible for tracking telemetry data related to MQTT messages.
|
|
"""
|
|
|
|
use GenServer
|
|
require Logger
|
|
|
|
def start_link(opts) do
|
|
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
|
end
|
|
|
|
def count_reading() do
|
|
GenServer.cast(__MODULE__, :count_reading)
|
|
end
|
|
|
|
def count_error() do
|
|
GenServer.cast(__MODULE__, :count_error)
|
|
end
|
|
|
|
@log_interval 60_000
|
|
|
|
# GenServer Callbacks
|
|
|
|
@impl true
|
|
def init(_opts) do
|
|
schedule_log()
|
|
{:ok, %{total_readings: 0, total_errors: 0}}
|
|
end
|
|
|
|
@impl true
|
|
def handle_cast(:count_reading, state) do
|
|
new_count = state.total_readings + 1
|
|
{:noreply, %{state | total_readings: new_count}}
|
|
end
|
|
|
|
@impl true
|
|
def handle_cast(:count_error, state) do
|
|
new_count = state.total_errors + 1
|
|
{:noreply, %{state | total_errors: new_count}}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info(:log_stats, state) do
|
|
rate = if state.total_readings > 0 do
|
|
Float.round(state.total_errors / state.total_readings * 100, 2)
|
|
else
|
|
0.0
|
|
end
|
|
Logger.info("[MQTT.Telemetry] #{state.total_readings} readings, #{state.total_errors} errors (#{rate} err rate) in last #{@log_interval / 1000}s.")
|
|
schedule_log()
|
|
{:noreply, state}
|
|
end
|
|
|
|
# Private helper functions
|
|
defp schedule_log() do
|
|
Process.send_after(self(), :log_stats, @log_interval)
|
|
end
|
|
end
|