From 6a29ee16716913396b7c9a7a9d48d8da7c398e36 Mon Sep 17 00:00:00 2001 From: mayor Date: Fri, 6 Feb 2026 12:30:52 -0600 Subject: [PATCH] fix: Split agent polling queries to isolate SNMP failures Changed from one large WALK query with all OIDs to separate WALK queries per table type. This prevents a failure in one unsupported table (like ARP on a device that doesn't support it) from killing the entire polling operation. Before: Single WALK with neighbor + ARP + MAC + IP + HOST-RESOURCES OIDs After: Separate WALKs for each table type This makes polling more resilient - if a device doesn't support ARP tables or HOST-RESOURCES-MIB, those WALKs will fail individually while neighbors, MAC tables, and IP addresses can still succeed. Fixes agent errors where a single SNMP receive error was killing the entire poller thread and failing all subsequent operations with 'Poller thread died'. --- lib/towerops_web/channels/agent_channel.ex | 101 ++++++++++++--------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/lib/towerops_web/channels/agent_channel.ex b/lib/towerops_web/channels/agent_channel.ex index f60bb357..7c23b3cc 100644 --- a/lib/towerops_web/channels/agent_channel.ex +++ b/lib/towerops_web/channels/agent_channel.ex @@ -711,54 +711,69 @@ defmodule ToweropsWeb.AgentChannel do ] end) - # Neighbor discovery OIDs - neighbor_oids = [ - # LLDP - "1.0.8802.1.1.2.1.4.1.1", - # Cisco CDP - "1.3.6.1.4.1.9.9.23" - ] - - # ARP table OIDs - arp_oids = [ - # IP-MIB ipNetToMediaTable (IPv4 ARP) - "1.3.6.1.2.1.4.22", - # IP-MIB ipNetToPhysicalTable (RFC 4293 - unified IPv4/IPv6) - "1.3.6.1.2.1.4.35" - ] - - # MAC address table OIDs - mac_oids = [ - # BRIDGE-MIB dot1dTpFdbTable - "1.3.6.1.2.1.17.4.3" - ] - - # IP address OIDs (for polling changes) - ip_address_oids = [ - # IP-MIB ipAddrTable (IPv4) - "1.3.6.1.2.1.4.20", - # IP-MIB ipAddressTable (IPv6) - "1.3.6.1.2.1.4.34" - ] - - # HOST-RESOURCES-MIB for processors and storage - host_resources_oids = [ - # hrProcessorTable - "1.3.6.1.2.1.25.3.3", - # hrStorageTable - "1.3.6.1.2.1.25.2.3" - ] - - [ + # Build separate WALK queries to isolate failures + # If one table doesn't exist, others can still succeed + base_queries = [ %SnmpQuery{ query_type: :GET, oids: sensor_oids ++ interface_oids - }, - %SnmpQuery{ - query_type: :WALK, - oids: neighbor_oids ++ arp_oids ++ mac_oids ++ ip_address_oids ++ host_resources_oids } ] + + # Neighbor discovery (LLDP/CDP) - separate query + neighbor_query = %SnmpQuery{ + query_type: :WALK, + oids: [ + # LLDP + "1.0.8802.1.1.2.1.4.1.1", + # Cisco CDP + "1.3.6.1.4.1.9.9.23" + ] + } + + # ARP table - separate query (may not be supported on all devices) + arp_query = %SnmpQuery{ + query_type: :WALK, + oids: [ + # IP-MIB ipNetToMediaTable (IPv4 ARP) + "1.3.6.1.2.1.4.22", + # IP-MIB ipNetToPhysicalTable (RFC 4293 - unified IPv4/IPv6) + "1.3.6.1.2.1.4.35" + ] + } + + # MAC address table - separate query (only on switches) + mac_query = %SnmpQuery{ + query_type: :WALK, + oids: [ + # BRIDGE-MIB dot1dTpFdbTable + "1.3.6.1.2.1.17.4.3" + ] + } + + # IP address tables - separate query + ip_query = %SnmpQuery{ + query_type: :WALK, + oids: [ + # IP-MIB ipAddrTable (IPv4) + "1.3.6.1.2.1.4.20", + # IP-MIB ipAddressTable (IPv6) + "1.3.6.1.2.1.4.34" + ] + } + + # HOST-RESOURCES-MIB - separate query (may not be supported) + host_resources_query = %SnmpQuery{ + query_type: :WALK, + oids: [ + # hrProcessorTable + "1.3.6.1.2.1.25.3.3", + # hrStorageTable + "1.3.6.1.2.1.25.2.3" + ] + } + + base_queries ++ [neighbor_query, arp_query, mac_query, ip_query, host_resources_query] end defp build_mikrotik_job(device) do