Move interface counter state from global map to Interface struct
This commit is contained in:
57
snmp.go
57
snmp.go
@@ -6,30 +6,11 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gosnmp/gosnmp"
|
"github.com/gosnmp/gosnmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ifaceCounters struct {
|
|
||||||
inPkts uint64
|
|
||||||
outPkts uint64
|
|
||||||
inBytes uint64
|
|
||||||
outBytes uint64
|
|
||||||
uptime uint64
|
|
||||||
timestamp time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type counterTracker struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
counters map[string]*ifaceCounters
|
|
||||||
}
|
|
||||||
|
|
||||||
var ifaceTracker = &counterTracker{
|
|
||||||
counters: map[string]*ifaceCounters{},
|
|
||||||
}
|
|
||||||
|
|
||||||
var portNameRewrites = []struct {
|
var portNameRewrites = []struct {
|
||||||
re *regexp.Regexp
|
re *regexp.Regexp
|
||||||
repl string
|
repl string
|
||||||
@@ -289,21 +270,19 @@ func (t *Tendrils) queryInterfaceStats(snmp *gosnmp.GoSNMP, node *Node, ifNames
|
|||||||
inPkts := ifHCInUcastPkts[ifIndex] + ifHCInMcastPkts[ifIndex] + ifHCInBcastPkts[ifIndex]
|
inPkts := ifHCInUcastPkts[ifIndex] + ifHCInMcastPkts[ifIndex] + ifHCInBcastPkts[ifIndex]
|
||||||
outPkts := ifHCOutUcastPkts[ifIndex] + ifHCOutMcastPkts[ifIndex] + ifHCOutBcastPkts[ifIndex]
|
outPkts := ifHCOutUcastPkts[ifIndex] + ifHCOutMcastPkts[ifIndex] + ifHCOutBcastPkts[ifIndex]
|
||||||
|
|
||||||
key := node.ID + ":" + name
|
hasPrev := !iface.prevTimestamp.IsZero()
|
||||||
ifaceTracker.mu.Lock()
|
|
||||||
prev, hasPrev := ifaceTracker.counters[key]
|
|
||||||
if hasPrev {
|
if hasPrev {
|
||||||
if prev.uptime > 0 && stats.Uptime > 0 && stats.Uptime < prev.uptime {
|
if iface.prevUptime > 0 && stats.Uptime > 0 && stats.Uptime < iface.prevUptime {
|
||||||
log.Printf("[ERROR] port flap on %s %s: uptime dropped from %d to %d seconds", node.DisplayName(), name, prev.uptime, stats.Uptime)
|
log.Printf("[ERROR] port flap on %s %s: uptime dropped from %d to %d seconds", node.DisplayName(), name, iface.prevUptime, stats.Uptime)
|
||||||
t.errors.AddPortFlap(node, name)
|
t.errors.AddPortFlap(node, name)
|
||||||
}
|
}
|
||||||
if hasInBytes && hasOutBytes {
|
if hasInBytes && hasOutBytes {
|
||||||
elapsed := now.Sub(prev.timestamp).Seconds()
|
elapsed := now.Sub(iface.prevTimestamp).Seconds()
|
||||||
if elapsed > 0 {
|
if elapsed > 0 {
|
||||||
stats.InPktsRate = float64(inPkts-prev.inPkts) / elapsed
|
stats.InPktsRate = float64(inPkts-iface.prevInPkts) / elapsed
|
||||||
stats.OutPktsRate = float64(outPkts-prev.outPkts) / elapsed
|
stats.OutPktsRate = float64(outPkts-iface.prevOutPkts) / elapsed
|
||||||
stats.InBytesRate = float64(inBytes-prev.inBytes) / elapsed
|
stats.InBytesRate = float64(inBytes-iface.prevInBytes) / elapsed
|
||||||
stats.OutBytesRate = float64(outBytes-prev.outBytes) / elapsed
|
stats.OutBytesRate = float64(outBytes-iface.prevOutBytes) / elapsed
|
||||||
|
|
||||||
maxBytesRate := float64(stats.Speed) / 8 * 2
|
maxBytesRate := float64(stats.Speed) / 8 * 2
|
||||||
if stats.InBytesRate < 0 || stats.InBytesRate > maxBytesRate {
|
if stats.InBytesRate < 0 || stats.InBytesRate > maxBytesRate {
|
||||||
@@ -317,19 +296,15 @@ func (t *Tendrils) queryInterfaceStats(snmp *gosnmp.GoSNMP, node *Node, ifNames
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
storedUptime := stats.Uptime
|
|
||||||
if storedUptime == 0 && hasPrev {
|
iface.prevInPkts = inPkts
|
||||||
storedUptime = prev.uptime
|
iface.prevOutPkts = outPkts
|
||||||
|
iface.prevInBytes = inBytes
|
||||||
|
iface.prevOutBytes = outBytes
|
||||||
|
if stats.Uptime > 0 {
|
||||||
|
iface.prevUptime = stats.Uptime
|
||||||
}
|
}
|
||||||
ifaceTracker.counters[key] = &ifaceCounters{
|
iface.prevTimestamp = now
|
||||||
inPkts: inPkts,
|
|
||||||
outPkts: outPkts,
|
|
||||||
inBytes: inBytes,
|
|
||||||
outBytes: outBytes,
|
|
||||||
uptime: storedUptime,
|
|
||||||
timestamp: now,
|
|
||||||
}
|
|
||||||
ifaceTracker.mu.Unlock()
|
|
||||||
|
|
||||||
if poe, ok := poeStats[name]; ok {
|
if poe, ok := poeStats[name]; ok {
|
||||||
stats.PoE = poe
|
stats.PoE = poe
|
||||||
|
|||||||
7
types.go
7
types.go
@@ -362,6 +362,13 @@ type Interface struct {
|
|||||||
IPs IPSet `json:"ips,omitempty"`
|
IPs IPSet `json:"ips,omitempty"`
|
||||||
Up bool `json:"up,omitempty"`
|
Up bool `json:"up,omitempty"`
|
||||||
Stats *InterfaceStats `json:"stats,omitempty"`
|
Stats *InterfaceStats `json:"stats,omitempty"`
|
||||||
|
|
||||||
|
prevInPkts uint64
|
||||||
|
prevOutPkts uint64
|
||||||
|
prevInBytes uint64
|
||||||
|
prevOutBytes uint64
|
||||||
|
prevUptime uint64
|
||||||
|
prevTimestamp time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interface) MarshalJSON() ([]byte, error) {
|
func (i *Interface) MarshalJSON() ([]byte, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user