diff --git a/lib/towerops/agents/stats.ex b/lib/towerops/agents/stats.ex index 7e012dc5..39874613 100644 --- a/lib/towerops/agents/stats.ex +++ b/lib/towerops/agents/stats.ex @@ -272,29 +272,30 @@ defmodule Towerops.Agents.Stats do ] """ def get_unmonitored_equipment(organization_id) do - from(e in Equipment, - join: s in assoc(e, :site), - left_join: o in assoc(s, :organization), - where: - s.organization_id == ^organization_id and - e.snmp_enabled == true and - e.monitoring_enabled == true, - preload: [site: :organization] + # Use SQL to determine which equipment has no agent assigned + # This avoids loading all equipment into memory + Repo.all( + from(e in Equipment, + join: s in assoc(e, :site), + join: o in assoc(s, :organization), + left_join: aa in AgentAssignment, + on: aa.equipment_id == e.id and aa.enabled == true, + # Equipment has no agent via any method + where: + s.organization_id == ^organization_id and + e.snmp_enabled == true and + e.monitoring_enabled == true and + is_nil(aa.agent_token_id) and + is_nil(s.agent_token_id) and + is_nil(o.default_agent_token_id), + select: %{ + id: e.id, + name: e.name, + ip_address: e.ip_address, + site_name: s.name + } + ) ) - |> Repo.all() - |> Enum.filter(fn equipment -> - # Filter to only equipment with no agent assigned - {agent_id, _source} = Towerops.Agents.get_effective_agent_token_with_source(equipment) - is_nil(agent_id) - end) - |> Enum.map(fn equipment -> - %{ - id: equipment.id, - name: equipment.name, - ip_address: equipment.ip_address, - site_name: equipment.site.name - } - end) end # Private helper functions