fix agent-polled devices stuck in unknown status
store_monitoring_check saved ping results from agents but never updated device status. DeviceMonitorWorker skips agent-assigned devices, so nothing ever moved them from :unknown to :up/:down. added update_device_status_from_check to derive status from check result, update the device, create alerts on transitions, and broadcast via PubSub — matching DeviceMonitorWorker behavior.
This commit is contained in:
parent
cb3f2edf50
commit
2875866c07
2 changed files with 81 additions and 0 deletions
|
|
@ -1,6 +1,17 @@
|
|||
CHANGELOG - towerops-web
|
||||
========================
|
||||
|
||||
2026-02-11 - fix: update device status from agent monitoring checks
|
||||
- File: lib/towerops_web/channels/agent_channel.ex (store_monitoring_check/2)
|
||||
- Bug: Devices polled by remote agents stayed in "unknown" state because
|
||||
store_monitoring_check saved the ping result but never called
|
||||
Devices.update_device_status/2. The DeviceMonitorWorker (Phoenix-side)
|
||||
skips agent-assigned devices entirely, so nothing ever updated status.
|
||||
- Fix: Added update_device_status_from_check/2 and handle_agent_status_change/3
|
||||
to derive :up/:down from check status, update device, create alerts on
|
||||
transitions, and broadcast via PubSub — matching DeviceMonitorWorker behavior
|
||||
- Also added alias Towerops.Alerts to the channel module
|
||||
|
||||
2026-02-11 - fix: update last_snmp_poll_at for agent-polled devices
|
||||
- File: lib/towerops_web/channels/agent_channel.ex (process_polling_result/3)
|
||||
- Bug: Devices polled by remote agents showed "Last Polled: Never" because
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
alias Towerops.Agent.SnmpQuery
|
||||
alias Towerops.Agent.Validator
|
||||
alias Towerops.Agents
|
||||
alias Towerops.Alerts
|
||||
alias Towerops.Devices
|
||||
alias Towerops.Devices.BackupRequests
|
||||
alias Towerops.Devices.MikrotikBackups
|
||||
|
|
@ -1163,6 +1164,7 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
|
||||
case Monitoring.create_check(attrs) do
|
||||
{:ok, _check} ->
|
||||
update_device_status_from_check(device, status)
|
||||
:ok
|
||||
|
||||
{:error, changeset} ->
|
||||
|
|
@ -1184,6 +1186,74 @@ defmodule ToweropsWeb.AgentChannel do
|
|||
end
|
||||
end
|
||||
|
||||
defp update_device_status_from_check(device, check_status) do
|
||||
new_status = if check_status in [:success, :up, :ok], do: :up, else: :down
|
||||
old_status = device.status
|
||||
|
||||
Devices.update_device_status(device, new_status)
|
||||
|
||||
if old_status != new_status do
|
||||
handle_agent_status_change(device, old_status, new_status)
|
||||
end
|
||||
|
||||
Phoenix.PubSub.broadcast(
|
||||
Towerops.PubSub,
|
||||
"device:#{device.id}",
|
||||
{:device_status_changed, device.id, new_status, nil}
|
||||
)
|
||||
end
|
||||
|
||||
defp handle_agent_status_change(device, _old_status, :down) do
|
||||
if !Alerts.has_active_alert?(device.id, :device_down) do
|
||||
now = DateTime.truncate(DateTime.utc_now(), :second)
|
||||
|
||||
message =
|
||||
if device.snmp_enabled,
|
||||
do: "Device is not responding to SNMP",
|
||||
else: "Device is not responding to ping"
|
||||
|
||||
Alerts.create_alert(%{
|
||||
device_id: device.id,
|
||||
alert_type: :device_down,
|
||||
triggered_at: now,
|
||||
message: message
|
||||
})
|
||||
|
||||
Phoenix.PubSub.broadcast(
|
||||
Towerops.PubSub,
|
||||
"alerts:new",
|
||||
{:new_alert, device.id, :device_down}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_agent_status_change(device, _old_status, :up) do
|
||||
now = DateTime.truncate(DateTime.utc_now(), :second)
|
||||
|
||||
message =
|
||||
if device.snmp_enabled,
|
||||
do: "Device is now responding to SNMP",
|
||||
else: "Device is now responding to ping"
|
||||
|
||||
Alerts.create_alert(%{
|
||||
device_id: device.id,
|
||||
alert_type: :device_up,
|
||||
triggered_at: now,
|
||||
message: message
|
||||
})
|
||||
|
||||
case Alerts.get_active_alert(device.id, :device_down) do
|
||||
nil -> :ok
|
||||
alert -> Alerts.resolve_alert(alert)
|
||||
end
|
||||
|
||||
Phoenix.PubSub.broadcast(
|
||||
Towerops.PubSub,
|
||||
"alerts:resolved",
|
||||
{:alert_resolved, device.id, :device_down}
|
||||
)
|
||||
end
|
||||
|
||||
defp fetch_device(device_id) do
|
||||
case Devices.get_device_with_details(device_id) do
|
||||
nil -> {:error, :device_not_found}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue