switch_legacy v1
This commit is contained in:
parent
0cdc0fb8aa
commit
b16543bf2e
|
@ -1,7 +1,7 @@
|
|||
# # collect interval
|
||||
# interval = "300s"
|
||||
|
||||
switch_id_label = "ident"
|
||||
switch_id_label = "ip"
|
||||
|
||||
[mappings]
|
||||
"192.168.88.160" = "switch001.bj"
|
||||
|
|
4
go.mod
4
go.mod
|
@ -3,6 +3,7 @@ module flashcat.cloud/categraf
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/gaochao1/sw v1.0.0
|
||||
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
|
@ -21,15 +22,18 @@ require (
|
|||
github.com/prometheus/prometheus v2.5.0+incompatible
|
||||
github.com/shirou/gopsutil/v3 v3.22.3
|
||||
github.com/toolkits/pkg v1.2.9
|
||||
github.com/ulricqin/gosnmp v0.0.1
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.1.0 // indirect
|
||||
github.com/alouca/gologger v0.0.0-20120904114645-7d4b7291de9c // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/fatih/camelcase v1.0.0 // indirect
|
||||
github.com/fatih/structs v1.1.0 // indirect
|
||||
github.com/freedomkk-qfeng/go-fastping v0.0.0-20160109021039-d7bb493dee3e // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
|
|
9
go.sum
9
go.sum
|
@ -40,6 +40,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alouca/gologger v0.0.0-20120904114645-7d4b7291de9c h1:k/7/05/5kPRX7HaKyVYlsGVX6XkFTyYLqkqHzceUVlU=
|
||||
github.com/alouca/gologger v0.0.0-20120904114645-7d4b7291de9c/go.mod h1:SI1d/2/wpSTDjHgdS9ZLy6hqvsdhzVYAc8RLztweMpA=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
|
@ -71,9 +73,13 @@ github.com/frankban/quicktest v1.11.0/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P
|
|||
github.com/frankban/quicktest v1.11.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
|
||||
github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk=
|
||||
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
|
||||
github.com/freedomkk-qfeng/go-fastping v0.0.0-20160109021039-d7bb493dee3e h1:g8x+P3+xjxt7c53bucQW0ymvj+whjKfCLZH+99UMLS0=
|
||||
github.com/freedomkk-qfeng/go-fastping v0.0.0-20160109021039-d7bb493dee3e/go.mod h1:UcrAEbxjAhuq5beDj0conKRHGUhBPLkFt8aUmN/jrHY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gaochao1/sw v1.0.0 h1:qctwr8LR1lLHpPTV+vw+YibSD3F3aaDnaK2xjUFyIDw=
|
||||
github.com/gaochao1/sw v1.0.0/go.mod h1:+n1WufEIsjuBADDSvPzycop9F3zAbXNMuV3U84UdwKE=
|
||||
github.com/garyburd/redigo v1.6.2/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
|
@ -307,6 +313,8 @@ github.com/toolkits/pkg v1.2.9 h1:zGlrJDl+2sMBoxBRIoMtAwvKmW5wctuji2+qHCecMKk=
|
|||
github.com/toolkits/pkg v1.2.9/go.mod h1:ZUsQAOoaR99PSbes+RXSirvwmtd6+XIUvizCmrjfUYc=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ulricqin/gosnmp v0.0.1 h1:LmJ4y0tmnIe+qBeBAX9UjQvRLezso7VnN0bgslYnfzI=
|
||||
github.com/ulricqin/gosnmp v0.0.1/go.mod h1:9OasJbP94MjBGOLNghlVwgG3UN05ATurou1Gw+6rdzU=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
@ -387,6 +395,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
|||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package switch_legacy
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/gaochao1/sw"
|
||||
)
|
||||
|
||||
type LastifMap struct {
|
||||
lock *sync.RWMutex
|
||||
ifstat map[string][]sw.IfStats
|
||||
}
|
||||
|
||||
func NewLastifMap() *LastifMap {
|
||||
return &LastifMap{
|
||||
lock: new(sync.RWMutex),
|
||||
ifstat: make(map[string][]sw.IfStats),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *LastifMap) Get(k string) []sw.IfStats {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
if val, ok := m.ifstat[k]; ok {
|
||||
return val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *LastifMap) Set(k string, v []sw.IfStats) {
|
||||
m.lock.Lock()
|
||||
m.ifstat[k] = v
|
||||
m.lock.Unlock()
|
||||
}
|
||||
|
||||
func (m *LastifMap) Check(k string) bool {
|
||||
m.lock.RLock()
|
||||
_, ok := m.ifstat[k]
|
||||
m.lock.RUnlock()
|
||||
return ok
|
||||
}
|
|
@ -1,13 +1,20 @@
|
|||
package switch_legacy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"flashcat.cloud/categraf/config"
|
||||
"flashcat.cloud/categraf/inputs"
|
||||
"flashcat.cloud/categraf/pkg/conv"
|
||||
"flashcat.cloud/categraf/types"
|
||||
"github.com/gaochao1/sw"
|
||||
"github.com/toolkits/pkg/concurrent/semaphore"
|
||||
"github.com/toolkits/pkg/container/list"
|
||||
go_snmp "github.com/ulricqin/gosnmp"
|
||||
)
|
||||
|
||||
const inputName = "switch_legacy"
|
||||
|
@ -85,7 +92,7 @@ type Instance struct {
|
|||
ConcurrencyForAddress int `toml:"concurrency_for_address"`
|
||||
ConcurrencyForRequest int `toml:"concurrency_for_request"`
|
||||
|
||||
PingEnable int64 `toml:"ping_enable"`
|
||||
PingEnable bool `toml:"ping_enable"`
|
||||
PingModeFastping bool `toml:"ping_mode_fastping"`
|
||||
PingTimeoutMs int64 `toml:"ping_timeout_ms"`
|
||||
PingRetries int `toml:"ping_retries"`
|
||||
|
@ -119,6 +126,7 @@ type Instance struct {
|
|||
Customs []Custom `toml:"customs"`
|
||||
|
||||
parent *Switch
|
||||
lastifmap *LastifMap
|
||||
}
|
||||
|
||||
type Custom struct {
|
||||
|
@ -128,9 +136,523 @@ type Custom struct {
|
|||
}
|
||||
|
||||
func (ins *Instance) Init() error {
|
||||
ins.lastifmap = NewLastifMap()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ins *Instance) gatherOnce(slist *list.SafeList) error {
|
||||
ips := ins.parseIPs()
|
||||
if len(ips) == 0 {
|
||||
log.Println("W! switch ips empty")
|
||||
return nil
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
log.Println("I! switch gather use:", time.Since(start))
|
||||
}()
|
||||
|
||||
log.Println("I! switch total ip count:", len(ips))
|
||||
|
||||
if ins.PingEnable {
|
||||
ips = ins.gatherPing(ips, slist)
|
||||
}
|
||||
|
||||
if ins.GatherFlowMetrics {
|
||||
ins.gatherFlowMetrics(ips, slist)
|
||||
}
|
||||
|
||||
if ins.GatherCpuMetrics {
|
||||
ins.gatherCpuMetrics(ips, slist)
|
||||
}
|
||||
|
||||
if ins.GatherMemMetrics {
|
||||
ins.gatherMemMetrics(ips, slist)
|
||||
}
|
||||
|
||||
if len(ins.Customs) > 0 {
|
||||
ins.gatherCustoms(ips, slist)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ins *Instance) gatherCustoms(ips []string, slist *list.SafeList) {
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
for i := 0; i < len(ips); i++ {
|
||||
ip := ips[i]
|
||||
for j := 0; j < len(ins.Customs); j++ {
|
||||
wg.Add(1)
|
||||
go ins.custstat(wg, ip, slist, ins.Customs[j])
|
||||
}
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (ins *Instance) custstat(wg *sync.WaitGroup, ip string, slist *list.SafeList, cust Custom) {
|
||||
defer wg.Done()
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println("E! recovered in custstat, ip:", ip, "oid:", cust.OID, "error:", r)
|
||||
}
|
||||
}()
|
||||
|
||||
var value float64
|
||||
var err error
|
||||
var snmpPDUs []go_snmp.SnmpPDU
|
||||
for i := 0; i < ins.SnmpRetries; i++ {
|
||||
snmpPDUs, err = sw.RunSnmp(ip, ins.Community, cust.OID, "get", int(ins.SnmpTimeoutMs))
|
||||
if len(snmpPDUs) > 0 && err == nil {
|
||||
value, err = conv.ToFloat64(snmpPDUs[0].Value)
|
||||
if err == nil {
|
||||
slist.PushFront(inputs.NewSample(cust.Metric, value, cust.Tags, ins.Labels))
|
||||
} else {
|
||||
log.Println("E! failed to convert to float64, ip:", ip, "oid:", cust.OID, "value:", snmpPDUs[0].Value)
|
||||
}
|
||||
break
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func (ins *Instance) gatherMemMetrics(ips []string, slist *list.SafeList) {
|
||||
result := make(map[string]float64)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
result[ips[i]] = -1
|
||||
}
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
se := semaphore.NewSemaphore(ins.ConcurrencyForAddress)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
ip := ips[i]
|
||||
wg.Add(1)
|
||||
se.Acquire()
|
||||
go ins.memstat(wg, se, ip, result)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for ip, utilPercent := range result {
|
||||
if utilPercent == -1 {
|
||||
continue
|
||||
}
|
||||
slist.PushFront(inputs.NewSample("mem_util", utilPercent, map[string]string{ins.parent.SwitchIdLabel: ip}, ins.Labels))
|
||||
}
|
||||
}
|
||||
|
||||
func (ins *Instance) memstat(wg *sync.WaitGroup, sema *semaphore.Semaphore, ip string, result map[string]float64) {
|
||||
defer func() {
|
||||
sema.Release()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
utilPercent, err := sw.MemUtilization(ip, ins.Community, int(ins.SnmpTimeoutMs), ins.SnmpRetries)
|
||||
if err != nil {
|
||||
log.Println("E! failed to gather mem, ip:", ip, "error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
result[ip] = float64(utilPercent)
|
||||
}
|
||||
|
||||
func (ins *Instance) gatherCpuMetrics(ips []string, slist *list.SafeList) {
|
||||
result := make(map[string]float64)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
result[ips[i]] = -1
|
||||
}
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
se := semaphore.NewSemaphore(ins.ConcurrencyForAddress)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
ip := ips[i]
|
||||
wg.Add(1)
|
||||
se.Acquire()
|
||||
go ins.cpustat(wg, se, ip, result)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for ip, utilPercent := range result {
|
||||
if utilPercent == -1 {
|
||||
continue
|
||||
}
|
||||
slist.PushFront(inputs.NewSample("cpu_util", utilPercent, map[string]string{ins.parent.SwitchIdLabel: ip}, ins.Labels))
|
||||
}
|
||||
}
|
||||
|
||||
func (ins *Instance) cpustat(wg *sync.WaitGroup, sema *semaphore.Semaphore, ip string, result map[string]float64) {
|
||||
defer func() {
|
||||
sema.Release()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
utilPercent, err := sw.CpuUtilization(ip, ins.Community, int(ins.SnmpTimeoutMs), ins.SnmpRetries)
|
||||
if err != nil {
|
||||
log.Println("E! failed to gather cpu, ip:", ip, "error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
result[ip] = float64(utilPercent)
|
||||
}
|
||||
|
||||
type ChIfStat struct {
|
||||
IP string
|
||||
UseTime int64
|
||||
IfStatsList []sw.IfStats
|
||||
}
|
||||
|
||||
func (ins *Instance) gatherFlowMetrics(ips []string, slist *list.SafeList) {
|
||||
result := make(map[string]*ChIfStat)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
result[ips[i]] = nil
|
||||
}
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
se := semaphore.NewSemaphore(ins.ConcurrencyForAddress)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
ip := ips[i]
|
||||
wg.Add(1)
|
||||
se.Acquire()
|
||||
go ins.ifstat(wg, se, ip, result)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for ip := range result {
|
||||
if result[ip].IP == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
stats := result[ip].IfStatsList
|
||||
for i := 0; i < len(stats); i++ {
|
||||
ifStat := stats[i]
|
||||
|
||||
if ifStat.IfName == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
ins.parent.SwitchIdLabel: ip,
|
||||
"ifname": ifStat.IfName,
|
||||
}
|
||||
|
||||
if ins.IndexTag {
|
||||
tags["ifindex"] = fmt.Sprint(ifStat.IfIndex)
|
||||
}
|
||||
|
||||
for k, v := range ins.Labels {
|
||||
tags[k] = v
|
||||
}
|
||||
|
||||
if ins.GatherOperStatus {
|
||||
slist.PushFront(inputs.NewSample("if_oper_status", ifStat.IfOperStatus, tags))
|
||||
}
|
||||
|
||||
slist.PushFront(inputs.NewSample("if_speed", ifStat.IfSpeed, tags))
|
||||
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
|
||||
speedlimit := ins.SpeedLimit
|
||||
if speedlimit == 0 {
|
||||
speedlimit = float64(ifStat.IfSpeed)
|
||||
}
|
||||
|
||||
IfHCInOctets := 8 * (float64(ifStat.IfHCInOctets) - float64(lastifStat.IfHCInOctets)) / float64(interval)
|
||||
IfHCOutOctets := 8 * (float64(ifStat.IfHCOutOctets) - float64(lastifStat.IfHCOutOctets)) / float64(interval)
|
||||
|
||||
if limitCheck(IfHCInOctets, speedlimit) {
|
||||
slist.PushFront(inputs.NewSample("if_in", IfHCInOctets, tags))
|
||||
if ifStat.IfSpeed > 0 {
|
||||
slist.PushFront(inputs.NewSample("if_in_speed_percent", 100*IfHCInOctets/float64(ifStat.IfSpeed), tags))
|
||||
}
|
||||
} else {
|
||||
log.Println("W! if_in out of range, current:", ifStat.IfHCInOctets, "lasttime:", lastifStat.IfHCInOctets, "tags:", tags)
|
||||
}
|
||||
|
||||
if limitCheck(IfHCOutOctets, speedlimit) {
|
||||
slist.PushFront(inputs.NewSample("if_out", IfHCOutOctets, tags))
|
||||
if ifStat.IfSpeed > 0 {
|
||||
slist.PushFront(inputs.NewSample("if_out_speed_percent", 100*IfHCOutOctets/float64(ifStat.IfSpeed), tags))
|
||||
}
|
||||
} else {
|
||||
log.Println("W! if_out out of range, current:", ifStat.IfHCOutOctets, "lasttime:", lastifStat.IfHCOutOctets, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ins.GatherBroadcastPkt {
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
|
||||
IfHCInBroadcastPkts := (float64(ifStat.IfHCInBroadcastPkts) - float64(lastifStat.IfHCInBroadcastPkts)) / float64(interval)
|
||||
IfHCOutBroadcastPkts := (float64(ifStat.IfHCOutBroadcastPkts) - float64(lastifStat.IfHCOutBroadcastPkts)) / float64(interval)
|
||||
|
||||
if limitCheck(IfHCInBroadcastPkts, ins.BroadcastPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_in_broadcast_pkt", IfHCInBroadcastPkts, tags))
|
||||
} else {
|
||||
log.Println("W! if_in_broadcast_pkt out of range, current:", ifStat.IfHCInBroadcastPkts, "lasttime:", lastifStat.IfHCInBroadcastPkts, "tags:", tags)
|
||||
}
|
||||
|
||||
if limitCheck(IfHCOutBroadcastPkts, ins.BroadcastPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_out_broadcast_pkt", IfHCOutBroadcastPkts, tags))
|
||||
} else {
|
||||
log.Println("W! if_out_broadcast_pkt out of range, current:", ifStat.IfHCOutBroadcastPkts, "lasttime:", lastifStat.IfHCOutBroadcastPkts, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ins.GatherMulticastPkt {
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
|
||||
IfHCInMulticastPkts := (float64(ifStat.IfHCInMulticastPkts) - float64(lastifStat.IfHCInMulticastPkts)) / float64(interval)
|
||||
IfHCOutMulticastPkts := (float64(ifStat.IfHCOutMulticastPkts) - float64(lastifStat.IfHCOutMulticastPkts)) / float64(interval)
|
||||
|
||||
if limitCheck(IfHCInMulticastPkts, ins.MulticastPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_in_multicast_pkt", IfHCInMulticastPkts, tags))
|
||||
} else {
|
||||
log.Println("W! if_in_multicast_pkt out of range, current:", ifStat.IfHCInMulticastPkts, "lasttime:", lastifStat.IfHCInMulticastPkts, "tags:", tags)
|
||||
}
|
||||
|
||||
if limitCheck(IfHCOutMulticastPkts, ins.MulticastPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_out_multicast_pkt", IfHCOutMulticastPkts, tags))
|
||||
} else {
|
||||
log.Println("W! if_out_multicast_pkt out of range, current:", ifStat.IfHCOutMulticastPkts, "lasttime:", lastifStat.IfHCOutMulticastPkts, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ins.GatherDiscards {
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
|
||||
IfInDiscards := (float64(ifStat.IfInDiscards) - float64(lastifStat.IfInDiscards)) / float64(interval)
|
||||
IfOutDiscards := (float64(ifStat.IfOutDiscards) - float64(lastifStat.IfOutDiscards)) / float64(interval)
|
||||
|
||||
if limitCheck(IfInDiscards, ins.DiscardsPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_in_discards", IfInDiscards, tags))
|
||||
} else {
|
||||
log.Println("W! if_in_discards out of range, current:", ifStat.IfInDiscards, "lasttime:", lastifStat.IfInDiscards, "tags:", tags)
|
||||
}
|
||||
|
||||
if limitCheck(IfOutDiscards, ins.DiscardsPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_out_discards", IfOutDiscards, tags))
|
||||
} else {
|
||||
log.Println("W! if_out_discards out of range, current:", ifStat.IfOutDiscards, "lasttime:", lastifStat.IfOutDiscards, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ins.GatherErrors {
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
|
||||
IfInErrors := (float64(ifStat.IfInErrors) - float64(lastifStat.IfInErrors)) / float64(interval)
|
||||
IfOutErrors := (float64(ifStat.IfOutErrors) - float64(lastifStat.IfOutErrors)) / float64(interval)
|
||||
|
||||
if limitCheck(IfInErrors, ins.ErrorsPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_in_errors", IfInErrors, tags))
|
||||
} else {
|
||||
log.Println("W! if_in_errors out of range, current:", ifStat.IfInErrors, "lasttime:", lastifStat.IfInErrors, "tags:", tags)
|
||||
}
|
||||
|
||||
if limitCheck(IfOutErrors, ins.ErrorsPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_out_errors", IfOutErrors, tags))
|
||||
} else {
|
||||
log.Println("W! if_out_errors out of range, current:", ifStat.IfOutErrors, "lasttime:", lastifStat.IfOutErrors, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ins.GatherUnknownProtos {
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
IfInUnknownProtos := (float64(ifStat.IfInUnknownProtos) - float64(lastifStat.IfInUnknownProtos)) / float64(interval)
|
||||
if limitCheck(IfInUnknownProtos, ins.UnknownProtosPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_in_unknown_protos", IfInUnknownProtos, tags))
|
||||
} else {
|
||||
log.Println("W! if_in_unknown_protos out of range, current:", ifStat.IfInUnknownProtos, "lasttime:", lastifStat.IfInUnknownProtos, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ins.GatherOutQlen {
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
IfOutQLen := (float64(ifStat.IfOutQLen) - float64(lastifStat.IfOutQLen)) / float64(interval)
|
||||
if limitCheck(IfOutQLen, ins.OutQlenPktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_out_qlen", IfOutQLen, tags))
|
||||
} else {
|
||||
log.Println("W! if_out_qlen out of range, current:", ifStat.IfOutQLen, "lasttime:", lastifStat.IfOutQLen, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ins.GatherPkt {
|
||||
if lastIfStatList := ins.lastifmap.Get(ip); lastIfStatList != nil {
|
||||
for _, lastifStat := range lastIfStatList {
|
||||
if ifStat.IfIndex == lastifStat.IfIndex {
|
||||
interval := ifStat.TS - lastifStat.TS
|
||||
|
||||
IfHCInUcastPkts := (float64(ifStat.IfHCInUcastPkts) - float64(lastifStat.IfHCInUcastPkts)) / float64(interval)
|
||||
IfHCOutUcastPkts := (float64(ifStat.IfHCOutUcastPkts) - float64(lastifStat.IfHCOutUcastPkts)) / float64(interval)
|
||||
|
||||
if limitCheck(IfHCInUcastPkts, ins.PktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_in_pkts", IfHCInUcastPkts, tags))
|
||||
} else {
|
||||
log.Println("W! if_in_pkts out of range, current:", ifStat.IfHCInUcastPkts, "lasttime:", lastifStat.IfHCInUcastPkts, "tags:", tags)
|
||||
}
|
||||
|
||||
if limitCheck(IfHCOutUcastPkts, ins.PktLimit) {
|
||||
slist.PushFront(inputs.NewSample("if_out_pkts", IfHCOutUcastPkts, tags))
|
||||
} else {
|
||||
log.Println("W! if_out_pkts out of range, current:", ifStat.IfHCOutUcastPkts, "lasttime:", lastifStat.IfHCOutUcastPkts, "tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update lastifmap
|
||||
ins.lastifmap.Set(ip, stats)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (ins *Instance) ifstat(wg *sync.WaitGroup, sema *semaphore.Semaphore, ip string, result map[string]*ChIfStat) {
|
||||
defer func() {
|
||||
sema.Release()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
var (
|
||||
ifList []sw.IfStats
|
||||
err error
|
||||
start = time.Now()
|
||||
)
|
||||
|
||||
if ins.SnmpModeGosnmp {
|
||||
ifList, err = sw.ListIfStats(ip, ins.Community, int(ins.SnmpTimeoutMs), ins.IgnoreIfaces, ins.SnmpRetries, ins.ConcurrencyForRequest, !ins.GatherPkt, !ins.GatherOperStatus, !ins.GatherBroadcastPkt, !ins.GatherMulticastPkt, !ins.GatherDiscards, !ins.GatherErrors, !ins.GatherUnknownProtos, !ins.GatherOutQlen)
|
||||
} else {
|
||||
ifList, err = sw.ListIfStatsSnmpWalk(ip, ins.Community, int(ins.SnmpTimeoutMs)*5, ins.IgnoreIfaces, ins.SnmpRetries, !ins.GatherPkt, !ins.GatherOperStatus, !ins.GatherBroadcastPkt, !ins.GatherMulticastPkt, !ins.GatherDiscards, !ins.GatherErrors, !ins.GatherUnknownProtos, !ins.GatherOutQlen)
|
||||
}
|
||||
|
||||
if config.Config.DebugMode {
|
||||
log.Println("D! switch gather ifstat, ip:", ip, "use:", time.Since(start))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Println("E! failed to gather ifstat, ip:", ip, "error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(ifList) > 0 {
|
||||
result[ip] = &ChIfStat{
|
||||
IP: ip,
|
||||
IfStatsList: ifList,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ins *Instance) gatherPing(ips []string, slist *list.SafeList) []string {
|
||||
// init ping result
|
||||
pingResult := make(map[string]bool)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
// init ping result
|
||||
pingResult[ips[i]] = false
|
||||
}
|
||||
|
||||
wg := new(sync.WaitGroup)
|
||||
se := semaphore.NewSemaphore(ins.ConcurrencyForAddress)
|
||||
for i := 0; i < len(ips); i++ {
|
||||
ip := ips[i]
|
||||
wg.Add(1)
|
||||
se.Acquire()
|
||||
go ins.ping(wg, se, ip, pingResult)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
ips = make([]string, 0, len(ips))
|
||||
for ip, succ := range pingResult {
|
||||
val := 0
|
||||
if succ {
|
||||
val = 1
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
|
||||
if ins.GatherPingMetrics {
|
||||
slist.PushFront(inputs.NewSample("ping_up", val, map[string]string{ins.parent.SwitchIdLabel: ip}, ins.Labels))
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("I! switch alive ip count:", len(ips))
|
||||
return ips
|
||||
}
|
||||
|
||||
func (ins *Instance) parseIPs() (lst []string) {
|
||||
for i := 0; i < len(ins.IPs); i++ {
|
||||
item := ins.IPs[i]
|
||||
|
||||
aip := sw.ParseIp(item)
|
||||
for _, ip := range aip {
|
||||
lst = append(lst, ip)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ins *Instance) ping(wg *sync.WaitGroup, sema *semaphore.Semaphore, ip string, result map[string]bool) {
|
||||
defer func() {
|
||||
sema.Release()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
for i := 0; i < ins.PingRetries; i++ {
|
||||
succ := sw.Ping(ip, int(ins.PingTimeoutMs), ins.PingModeFastping)
|
||||
if succ {
|
||||
result[ip] = succ
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func limitCheck(value float64, limit float64) bool {
|
||||
if value < 0 {
|
||||
return false
|
||||
}
|
||||
if limit > 0 {
|
||||
if value > limit {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@ func ToFloat64(val interface{}) (float64, error) {
|
|||
return f, nil
|
||||
}
|
||||
|
||||
// try int
|
||||
if i, err := strconv.ParseInt(v, 0, 64); err == nil {
|
||||
return float64(i), nil
|
||||
}
|
||||
|
||||
// try bool
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err == nil {
|
||||
|
|
Loading…
Reference in New Issue