agent debug improvements

This commit is contained in:
Graham McIntire 2026-01-27 14:19:37 -06:00
parent 5fb92dd961
commit 3f3df5938d
No known key found for this signature in database
3 changed files with 79 additions and 24 deletions

View file

@ -59,33 +59,47 @@ defmodule Towerops.Snmp.AgentDiscovery do
@spec process_agent_discovery(DeviceSchema.t(), map()) ::
{:ok, Discovery.Device.t()} | {:error, term()}
def process_agent_discovery(device, oid_values) when is_map(oid_values) do
oid_count = map_size(oid_values)
Logger.info("Processing agent discovery for #{device.name} (#{device.ip_address})",
device_id: device.id,
oid_count: map_size(oid_values)
oid_count: oid_count
)
# Build connection opts with Replay adapter
client_opts = build_replay_opts(device, oid_values)
# Check for empty OID map - this indicates agent couldn't collect any SNMP data
if oid_count == 0 do
Logger.error(
"Agent collected 0 OIDs for #{device.name} (#{device.ip_address})",
device_id: device.id,
troubleshooting:
"Agent couldn't collect SNMP data. Check: 1) Device reachable from agent network (ping #{device.ip_address}), 2) SNMP enabled on device, 3) Firewall allows UDP port #{device.snmp_port || 161}, 4) Community string '#{obscure_community(device)}' correct, 5) SNMP version matches device configuration"
)
# Run discovery using standard pipeline
# This will call all the same functions as direct discovery,
# but read from the OID map instead of making SNMP queries
case Discovery.discover_device_with_opts(device, client_opts) do
{:ok, discovered_device} ->
Logger.info("Agent discovery succeeded for #{device.name}",
device_id: device.id,
interfaces: length(discovered_device.interfaces || []),
sensors: count_sensors(discovered_device)
)
{:error, :agent_collected_no_data}
else
# Build connection opts with Replay adapter
client_opts = build_replay_opts(device, oid_values)
{:ok, discovered_device}
# Run discovery using standard pipeline
# This will call all the same functions as direct discovery,
# but read from the OID map instead of making SNMP queries
case Discovery.discover_device_with_opts(device, client_opts) do
{:ok, discovered_device} ->
Logger.info("Agent discovery succeeded for #{device.name}",
device_id: device.id,
interfaces: length(discovered_device.interfaces || []),
sensors: count_sensors(discovered_device)
)
{:error, reason} = error ->
Logger.error("Agent discovery failed for #{device.name}: #{inspect(reason)}",
device_id: device.id
)
{:ok, discovered_device}
error
{:error, reason} = error ->
Logger.error("Agent discovery failed for #{device.name}: #{inspect(reason)}",
device_id: device.id
)
error
end
end
end
@ -116,4 +130,17 @@ defmodule Towerops.Snmp.AgentDiscovery do
0
end
end
# Obscure community string for logging (show first 3 chars + ***)
@spec obscure_community(DeviceSchema.t()) :: String.t()
defp obscure_community(device) do
snmp_config = Devices.get_snmp_config(device)
community = snmp_config.community || "unknown"
if String.length(community) > 3 do
String.slice(community, 0..2) <> "***"
else
"***"
end
end
end

View file

@ -173,7 +173,26 @@ defmodule Towerops.Snmp.DeferredDiscovery do
if elapsed < fast_threshold, do: :fast, else: :slow
{:error, _} ->
{:error, reason} ->
# Log detailed diagnostics to help troubleshoot connectivity issues
ip = Keyword.get(client_opts, :ip, "unknown")
community = Keyword.get(client_opts, :community, "unknown")
version = Keyword.get(client_opts, :version, "unknown")
port = Keyword.get(client_opts, :port, 161)
adapter = Keyword.get(client_opts, :adapter, "Real SNMP")
Logger.warning(
"Device #{ip} categorized as unresponsive - SNMP GET failed",
ip: ip,
port: port,
version: version,
community: String.slice(community, 0..3) <> "***",
adapter: inspect(adapter),
error: inspect(reason),
troubleshooting:
"Check: 1) Device reachable (ping #{ip}), 2) SNMP enabled on device, 3) Firewall allows UDP #{port}, 4) Community string correct, 5) SNMP version matches"
)
:unresponsive
end
end

View file

@ -143,10 +143,19 @@ defmodule Towerops.Snmp.Discovery do
if device.snmp_enabled do
Logger.info("Starting discovery with custom opts for: #{device.name}")
# Categorize device speed for adaptive timeouts
# Note: For Replay adapter, this will be fast since no network calls
device_speed = DeferredDiscovery.categorize_device_speed(client_opts)
timeouts = DeferredDiscovery.timeouts_for_speed(device_speed)
# Skip speed categorization for Replay adapter (agent-based discovery)
# Agent data is pre-collected, so network checks are not needed
adapter = Keyword.get(client_opts, :adapter)
{device_speed, timeouts} =
if adapter == Towerops.Snmp.Adapters.Replay do
Logger.debug("Using Replay adapter, skipping speed categorization")
{:fast, DeferredDiscovery.timeouts_for_speed(:fast)}
else
# Categorize device speed for adaptive timeouts (real SNMP)
speed = DeferredDiscovery.categorize_device_speed(client_opts)
{speed, DeferredDiscovery.timeouts_for_speed(speed)}
end
if device_speed == :unresponsive do
Logger.warning("Device #{device.name} is unresponsive, aborting discovery")