bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/keepalived_linux.go (about) 1 package collectors 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 8 "bosun.org/metadata" 9 "bosun.org/opentsdb" 10 "bosun.org/snmp" 11 ) 12 13 type VRRPInstanceEntry struct { 14 VInstanceIndex int64 15 VInstanceName string 16 VInstanceVirtualRouterId int64 17 VInstanceState int64 18 VInstanceInitialState int64 19 VInstanceWantedState int64 20 VInstanceBasePriority int64 21 VInstanceEffectivePriority int64 22 VInstanceVipsStatus int64 23 VInstancePrimaryInterface string 24 VInstanceTrackPrimaryIf int64 25 VInstanceAdvertisementsInt int64 26 VInstancePreempt int64 27 VInstancePreemptDelay int64 28 VInstanceAuthType int64 29 VInstanceLvsSyncDaemon int64 30 VInstanceLvsSyncInterface string 31 VInstanceSyncGroup string 32 VInstanceGarpDelay int64 33 VInstanceSmtpAlert int64 34 VInstanceNotifyExec int64 35 VInstanceScriptMaster string 36 VInstanceScriptBackup string 37 VInstanceScriptFault string 38 VInstanceScriptStop string 39 VInstanceScript string 40 VInstanceAccept int64 41 } 42 43 const ( 44 VRRPInstanceTable = ".1.3.6.1.4.1.9586.100.5.2.3.1" 45 VRRPAddressTable = ".1.3.6.1.4.1.9586.100.5.2.6.1" 46 ) 47 48 const ( 49 descVRRPState = "VRRP Can be in one of the following states: init(0), backup(1), master(2), fault(3), unknown(4)." 50 descVRRPVipsStatus = "Indicates if all the VIPs of this VRRP instance are enabled." 51 descVRRPBasePriority = "Base priority (as defined in the configuration file) for this VRRP instance. This value can be modified to force the virtual router instance to become backup or master." 52 descVRRPEffectivePriority = "Effective priority for this VRRP instance. Status of interfaces and script results are used to compute this value from the base priority." 53 descVRRPAddressStatus = "Indicates if the IP address is set or not." 54 descVRRPAddressAdvertising = "Indicates if the IP address is being advertised or not." 55 ) 56 57 func init() { 58 collectors = append(collectors, &IntervalCollector{F: c_snmp_keepalived_vrrp_instances}) 59 } 60 61 func c_snmp_keepalived_vrrp_instances() (opentsdb.MultiDataPoint, error) { 62 if KeepalivedCommunity == "" { 63 return nil, nil 64 } 65 var md opentsdb.MultiDataPoint 66 entries := make(map[int]*VRRPInstanceEntry) 67 rows, err := snmp.Walk("localhost", KeepalivedCommunity, VRRPInstanceTable) 68 if err != nil { 69 return nil, nil 70 } 71 for rows.Next() { 72 var a interface{} 73 i, err := rows.Scan(&a) 74 if err != nil { 75 return nil, err 76 } 77 id, ok := i.([]int) 78 if !ok || len(id) != 2 { 79 return nil, fmt.Errorf("unexpected type for snmp keepalived index") 80 } 81 entry, ok := entries[id[1]] 82 if !ok { 83 entries[id[1]] = &VRRPInstanceEntry{} 84 entry = entries[id[1]] 85 } 86 s := reflect.ValueOf(entry) 87 nFields := reflect.ValueOf(*entry).NumField() 88 if id[0] > nFields { 89 return nil, fmt.Errorf("unexpected number of fields for snmp keepalived VRRPInstanceTable") 90 } 91 v := s.Elem().Field(id[0] - 1) 92 switch t := a.(type) { 93 case int64: 94 v.SetInt(t) 95 case []uint8: 96 v.SetString(string(t)) 97 } 98 } 99 for _, entry := range entries { 100 ts := opentsdb.TagSet{"instance_name": entry.VInstanceName, "instance_id": fmt.Sprint(entry.VInstanceVirtualRouterId)} 101 Add(&md, "keepalived.vrrp.state", entry.VInstanceState, ts, metadata.Gauge, metadata.StatusCode, descVRRPState) 102 Add(&md, "keepalived.vrrp.wanted_state", entry.VInstanceWantedState, ts, metadata.Gauge, metadata.StatusCode, descVRRPState) 103 Add(&md, "keepalived.vrrp.vips_status", entry.VInstanceVipsStatus, ts, metadata.Gauge, metadata.StatusCode, descVRRPVipsStatus) 104 Add(&md, "keepalived.vrrp.base_priority", entry.VInstanceBasePriority, ts, metadata.Gauge, metadata.Priority, descVRRPBasePriority) 105 Add(&md, "keepalived.vrrp.effective_priority", entry.VInstanceEffectivePriority, ts, metadata.Gauge, metadata.Priority, descVRRPEffectivePriority) 106 } 107 if err := keepalived_vrrp_addresses(&md, entries); err != nil { 108 return nil, err 109 } 110 return md, nil 111 } 112 113 type VRRPAddressEntry struct { 114 VRRPAddressIndex int64 115 VRRPAddressType int64 116 VRRPAddressValue string `snmp:"octet"` 117 VRRPAddressBroadcast string `snmp:"octet"` 118 VRRPAddressMask int64 119 VRRPAddressScope int64 120 VRRPAddressIfIndex int64 121 VRRPAddressIfName string 122 VRRPAddressIfAlias string 123 VRRPAddressStatus int64 124 VRRPAddressAdvertising int64 125 } 126 127 // Field (i.e Vrrp address type), Instance Index, Identifer 128 129 func keepalived_vrrp_addresses(md *opentsdb.MultiDataPoint, instances map[int]*VRRPInstanceEntry) error { 130 entries := make(map[int]map[int]*VRRPAddressEntry) 131 rows, err := snmp.Walk("localhost", KeepalivedCommunity, VRRPAddressTable) 132 if err != nil { 133 return nil 134 } 135 for rows.Next() { 136 var a interface{} 137 i, err := rows.Scan(&a) 138 if err != nil { 139 return err 140 } 141 id, ok := i.([]int) 142 if !ok || len(id) != 3 { 143 return fmt.Errorf("unexpected type for snmp keepalived index") 144 } 145 if _, ok := entries[id[1]]; !ok { 146 entries[id[1]] = make(map[int]*VRRPAddressEntry) 147 } 148 entry, ok := entries[id[1]][id[2]] 149 if !ok { 150 entries[id[1]][id[2]] = &VRRPAddressEntry{} 151 entry = entries[id[1]][id[2]] 152 } 153 s := reflect.ValueOf(entry) 154 nFields := reflect.ValueOf(*entry).NumField() 155 nonPointerType := reflect.ValueOf(*entry).Type() 156 if id[0]-1 > nFields { 157 return fmt.Errorf("unexpected number of fields for snmp keepalived VRRPAddressTable") 158 } 159 v := s.Elem().Field(id[0] - 1) 160 switch t := a.(type) { 161 case int64: 162 v.SetInt(t) 163 case []uint8: 164 if nonPointerType.Kind() == reflect.Struct && nonPointerType.Field(id[0]-1).Tag.Get("snmp") == "octet" { 165 var s []string 166 for _, runeValue := range t { 167 s = append(s, fmt.Sprintf("%v", runeValue)) 168 } 169 v.SetString(strings.Join(s, ".")) 170 } else { 171 v.SetString(string(t)) 172 } 173 } 174 } 175 for instance_id, instance := range instances { 176 for _, entry := range entries[instance_id] { 177 ts := opentsdb.TagSet{ 178 "instance_name": instance.VInstanceName, 179 "instance_id": fmt.Sprint(instance.VInstanceVirtualRouterId), 180 "address": entry.VRRPAddressValue} 181 Add(md, "keepalived.vrrp.address_status", entry.VRRPAddressStatus-1, ts, metadata.Gauge, metadata.Bool, descVRRPAddressStatus) 182 Add(md, "keepalived.vrrp.address_advertising", entry.VRRPAddressAdvertising-1, ts, metadata.Gauge, metadata.Bool, descVRRPAddressStatus) 183 } 184 } 185 return nil 186 }