bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/snmp_ifaces.go (about) 1 package collectors 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "bosun.org/cmd/scollector/conf" 9 "bosun.org/metadata" 10 "bosun.org/opentsdb" 11 ) 12 13 const ( 14 ifAlias = ".1.3.6.1.2.1.31.1.1.1.18" 15 ifDescr = ".1.3.6.1.2.1.2.2.1.2" 16 ifType = ".1.3.6.1.2.1.2.2.1.3" 17 ifMTU = ".1.3.6.1.2.1.2.2.1.4" 18 ifPhysAddress = ".1.3.6.1.2.1.2.2.1.6" 19 ifHighSpeed = ".1.3.6.1.2.1.31.1.1.1.15" 20 ifAdminStatus = ".1.3.6.1.2.1.2.2.1.7" 21 ifOperStatus = ".1.3.6.1.2.1.2.2.1.8" 22 ifHCInBroadcastPkts = ".1.3.6.1.2.1.31.1.1.1.9" 23 ifHCInMulticastPkts = ".1.3.6.1.2.1.31.1.1.1.8" 24 ifHCInUcastPkts = ".1.3.6.1.2.1.31.1.1.1.7" 25 ifHCOutBroadcastPkts = ".1.3.6.1.2.1.31.1.1.1.13" 26 ifHCOutMulticastPkts = ".1.3.6.1.2.1.31.1.1.1.12" 27 ifHCOutOctets = ".1.3.6.1.2.1.31.1.1.1.10" 28 ifHCOutUcastPkts = ".1.3.6.1.2.1.31.1.1.1.11" 29 ifHCinOctets = ".1.3.6.1.2.1.31.1.1.1.6" 30 ifInDiscards = ".1.3.6.1.2.1.2.2.1.13" 31 ifInErrors = ".1.3.6.1.2.1.2.2.1.14" 32 ifInPauseFrames = ".1.3.6.1.2.1.10.7.10.1.3" 33 ifName = ".1.3.6.1.2.1.31.1.1.1.1" 34 ifOutDiscards = ".1.3.6.1.2.1.2.2.1.19" 35 ifOutErrors = ".1.3.6.1.2.1.2.2.1.20" 36 ifOutPauseFrames = ".1.3.6.1.2.1.10.7.10.1.4" 37 ) 38 39 // SNMPIfaces registers a SNMP Interfaces collector for the given community and host. 40 func SNMPIfaces(cfg conf.SNMP) { 41 collectors = append(collectors, &IntervalCollector{ 42 F: func() (opentsdb.MultiDataPoint, error) { 43 return c_snmp_ifaces(cfg.Community, cfg.Host) 44 }, 45 Interval: time.Second * 30, 46 name: fmt.Sprintf("snmp-ifaces-%s", cfg.Host), 47 }) 48 } 49 50 const osNet = "os.net" 51 52 func switchInterfaceMetric(metric string, iname string, ifType int64) string { 53 switch ifType { 54 case 6: 55 return metric 56 case 53, 161: 57 return osNet + ".bond" + strings.TrimPrefix(metric, osNet) 58 case 135: 59 return osNet + ".virtual" + strings.TrimPrefix(metric, osNet) 60 case 131: 61 return osNet + ".tunnel" + strings.TrimPrefix(metric, osNet) 62 default: 63 //Cisco ASAs don't mark port channels correctly 64 if strings.Contains(iname, "port-channel") { 65 return osNet + ".bond" + strings.TrimPrefix(metric, osNet) 66 } 67 return osNet + ".other" + strings.TrimPrefix(metric, osNet) 68 } 69 } 70 71 func c_snmp_ifaces(community, host string) (opentsdb.MultiDataPoint, error) { 72 ifNamesRaw, err := snmp_subtree(host, community, ifName) 73 if err != nil || len(ifNamesRaw) == 0 { 74 ifNamesRaw, err = snmp_subtree(host, community, ifDescr) 75 if err != nil { 76 return nil, err 77 } 78 } 79 ifAliasesRaw, err := snmp_subtree(host, community, ifAlias) 80 if err != nil { 81 return nil, err 82 } 83 ifTypesRaw, err := snmp_subtree(host, community, ifType) 84 if err != nil { 85 return nil, err 86 } 87 ifPhysAddressRaw, err := snmp_subtree(host, community, ifPhysAddress) 88 if err != nil { 89 return nil, err 90 } 91 ifNames := make(map[interface{}]string, len(ifNamesRaw)) 92 ifAliases := make(map[interface{}]string, len(ifAliasesRaw)) 93 ifTypes := make(map[interface{}]int64, len(ifTypesRaw)) 94 ifPhysAddresses := make(map[interface{}]string, len(ifPhysAddressRaw)) 95 for k, v := range ifNamesRaw { 96 ifNames[k] = fmt.Sprintf("%s", v) 97 } 98 for k, v := range ifTypesRaw { 99 val, ok := v.(int64) 100 if !ok { 101 return nil, fmt.Errorf("unexpected type from from MIB::ifType") 102 } 103 ifTypes[k] = val 104 } 105 for k, v := range ifAliasesRaw { 106 // In case clean would come up empty, prevent the point from being removed 107 // by setting our own empty case. 108 ifAliases[k], _ = opentsdb.Clean(fmt.Sprintf("%s", v)) 109 if ifAliases[k] == "" { 110 ifAliases[k] = "NA" 111 } 112 } 113 for k, v := range ifPhysAddressRaw { 114 ifPhysAddresses[k] = fmt.Sprintf("%X", v) 115 } 116 var md opentsdb.MultiDataPoint 117 add := func(sA snmpAdd) error { 118 m, err := snmp_subtree(host, community, sA.oid) 119 if err != nil { 120 return err 121 } 122 var sum int64 123 for k, v := range m { 124 tags := opentsdb.TagSet{ 125 "host": host, 126 "iface": fmt.Sprintf("%s", k), 127 "iname": ifNames[k], 128 } 129 if sA.dir != "" { 130 tags["direction"] = sA.dir 131 } 132 if iVal, ok := v.(int64); ok && ifTypes[k] == 6 { 133 sum += iVal 134 } 135 Add(&md, switchInterfaceMetric(sA.metric, ifNames[k], ifTypes[k]), v, tags, sA.rate, sA.unit, sA.desc) 136 metadata.AddMeta("", tags, "alias", ifAliases[k], false) 137 metadata.AddMeta("", tags, "mac", ifPhysAddresses[k], false) 138 } 139 if sA.metric == osNetBytes { 140 tags := opentsdb.TagSet{"host": host, "direction": sA.dir} 141 Add(&md, osNetBytes+".total", sum, tags, metadata.Counter, metadata.Bytes, "The total number of bytes transfered through the network device.") 142 } 143 return nil 144 } 145 oids := []snmpAdd{ 146 {ifHCInBroadcastPkts, osNetBroadcast, "in", metadata.Counter, metadata.Packet, osNetBroadcastDesc}, 147 {ifHCInMulticastPkts, osNetMulticast, "in", metadata.Counter, metadata.Packet, osNetMulticastDesc}, 148 {ifHCInUcastPkts, osNetUnicast, "in", metadata.Counter, metadata.Packet, osNetUnicastDesc}, 149 {ifHCOutBroadcastPkts, osNetBroadcast, "out", metadata.Counter, metadata.Packet, osNetBroadcastDesc}, 150 {ifHCOutMulticastPkts, osNetMulticast, "out", metadata.Counter, metadata.Packet, osNetMulticastDesc}, 151 {ifHCOutOctets, osNetBytes, "out", metadata.Counter, metadata.Bytes, osNetBytesDesc}, 152 {ifHCOutUcastPkts, osNetUnicast, "out", metadata.Counter, metadata.Packet, osNetUnicastDesc}, 153 {ifHCinOctets, osNetBytes, "in", metadata.Counter, metadata.Bytes, osNetBytesDesc}, 154 {ifInDiscards, osNetDropped, "in", metadata.Counter, metadata.Packet, osNetDroppedDesc}, 155 {ifInErrors, osNetErrors, "in", metadata.Counter, metadata.Error, osNetErrorsDesc}, 156 {ifOutDiscards, osNetDropped, "out", metadata.Counter, metadata.Packet, osNetDroppedDesc}, 157 {ifOutErrors, osNetErrors, "out", metadata.Counter, metadata.Error, osNetErrorsDesc}, 158 {ifInPauseFrames, osNetPauseFrames, "in", metadata.Counter, metadata.Frame, osNetPauseFrameDesc}, 159 {ifOutPauseFrames, osNetPauseFrames, "out", metadata.Counter, metadata.Frame, osNetPauseFrameDesc}, 160 {ifMTU, osNetMTU, "", metadata.Gauge, metadata.Bytes, osNetMTUDesc}, 161 {ifHighSpeed, osNetIfSpeed, "", metadata.Gauge, metadata.Megabit, osNetIfSpeedDesc}, 162 {ifAdminStatus, osNetAdminStatus, "", metadata.Gauge, metadata.StatusCode, osNetAdminStatusDesc}, 163 {ifOperStatus, osNetOperStatus, "", metadata.Gauge, metadata.StatusCode, osNetOperStatusDesc}, 164 } 165 for _, sA := range oids { 166 if err := add(sA); err != nil { 167 return nil, err 168 } 169 } 170 return md, nil 171 } 172 173 type snmpAdd struct { 174 oid string 175 metric string 176 dir string 177 rate metadata.RateType 178 unit metadata.Unit 179 desc string 180 }