From 37b30fe78835ff65eaa43d5a4dbec3bc3883e842 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 18 Jan 2026 08:37:13 -0800 Subject: [PATCH] add --log-nodes flag for comprehensive node logging Co-Authored-By: Claude Opus 4.5 --- cmd/tendrils/main.go | 2 ++ nodes.go | 59 ++++++++++++++++++++++++++++++++++---------- tendrils.go | 1 + 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/cmd/tendrils/main.go b/cmd/tendrils/main.go index 5dc76a9..b851f57 100644 --- a/cmd/tendrils/main.go +++ b/cmd/tendrils/main.go @@ -12,6 +12,7 @@ func main() { noLLDP := flag.Bool("no-lldp", false, "disable LLDP discovery") noSNMP := flag.Bool("no-snmp", false, "disable SNMP discovery") logEvents := flag.Bool("log-events", false, "log node events") + logNodes := flag.Bool("log-nodes", false, "log full node details on changes") debugARP := flag.Bool("debug-arp", false, "debug ARP discovery") debugLLDP := flag.Bool("debug-lldp", false, "debug LLDP discovery") debugSNMP := flag.Bool("debug-snmp", false, "debug SNMP discovery") @@ -23,6 +24,7 @@ func main() { t.DisableLLDP = *noLLDP t.DisableSNMP = *noSNMP t.LogEvents = *logEvents + t.LogNodes = *logNodes t.DebugARP = *debugARP t.DebugLLDP = *debugLLDP t.DebugSNMP = *debugSNMP diff --git a/nodes.go b/nodes.go index 2d8fc02..d107899 100644 --- a/nodes.go +++ b/nodes.go @@ -15,21 +15,26 @@ type Interface struct { } func (i *Interface) String() string { - name := i.Name - if name == "" { - name = "??" - } - var ips []string for _, ip := range i.IPs { ips = append(ips, ip.String()) } sort.Strings(ips) - if len(ips) == 0 { - return fmt.Sprintf("%s/%s", name, i.MAC) + var parts []string + parts = append(parts, i.MAC.String()) + if i.Name != "" { + parts = append(parts, fmt.Sprintf("(%s)", i.Name)) } - return fmt.Sprintf("%s/%s %v", name, i.MAC, ips) + if len(ips) > 0 { + parts = append(parts, fmt.Sprintf("%v", ips)) + } + + result := parts[0] + for _, p := range parts[1:] { + result += " " + p + } + return result } type Node struct { @@ -131,11 +136,16 @@ func (n *Nodes) Update(mac net.HardwareAddr, ips []net.IP, ifaceName, nodeName, node.Name = nodeName } - if len(added) > 0 && n.t.LogEvents { - if isNew { - log.Printf("[add] %s %v (via %s)", node, added, source) - } else { - log.Printf("[update] %s +%v (via %s)", node, added, source) + if len(added) > 0 { + if n.t.LogEvents { + if isNew { + log.Printf("[add] %s %v (via %s)", node, added, source) + } else { + log.Printf("[update] %s +%v (via %s)", node, added, source) + } + } + if n.t.LogNodes { + n.logNode(node) } } } @@ -172,6 +182,10 @@ func (n *Nodes) Merge(macs []net.HardwareAddr, source string) { } n.mergeNodes(targetID, ids[i]) } + + if n.t.LogNodes { + n.logNode(n.nodes[targetID]) + } } func (n *Nodes) mergeNodes(keepID, mergeID int) { @@ -223,6 +237,25 @@ func (n *Nodes) GetByMAC(mac net.HardwareAddr) *Node { return nil } +func (n *Nodes) logNode(node *Node) { + name := node.Name + if name == "" { + name = "??" + } + log.Printf("[node] %s", name) + + var macKeys []string + for macKey := range node.Interfaces { + macKeys = append(macKeys, macKey) + } + sort.Strings(macKeys) + + for _, macKey := range macKeys { + iface := node.Interfaces[macKey] + log.Printf("[node] %s", iface) + } +} + func (n *Nodes) All() []*Node { n.mu.RLock() defer n.mu.RUnlock() diff --git a/tendrils.go b/tendrils.go index 6c2d1f9..92964c8 100644 --- a/tendrils.go +++ b/tendrils.go @@ -17,6 +17,7 @@ type Tendrils struct { DisableLLDP bool DisableSNMP bool LogEvents bool + LogNodes bool DebugARP bool DebugLLDP bool DebugSNMP bool