SNMP fix concurrency issue
This commit is contained in:
parent
3f2a04b25b
commit
f349c390ec
|
@ -23,6 +23,13 @@ type Snmp struct {
|
||||||
Table []Table
|
Table []Table
|
||||||
Subtable []Subtable
|
Subtable []Subtable
|
||||||
SnmptranslateFile string
|
SnmptranslateFile string
|
||||||
|
|
||||||
|
nameToOid map[string]string
|
||||||
|
initNode Node
|
||||||
|
subTableMap map[string]Subtable
|
||||||
|
|
||||||
|
// TODO change as unexportable
|
||||||
|
//OidInstanceMapping map[string]map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Host struct {
|
type Host struct {
|
||||||
|
@ -110,16 +117,7 @@ type Node struct {
|
||||||
subnodes map[string]Node
|
subnodes map[string]Node
|
||||||
}
|
}
|
||||||
|
|
||||||
var initNode = Node{
|
// TODO move this var to snmp struct
|
||||||
id: "1",
|
|
||||||
name: "",
|
|
||||||
subnodes: make(map[string]Node),
|
|
||||||
}
|
|
||||||
|
|
||||||
var SubTableMap = make(map[string]Subtable)
|
|
||||||
|
|
||||||
var NameToOid = make(map[string]string)
|
|
||||||
|
|
||||||
var OidInstanceMapping = make(map[string]map[string]string)
|
var OidInstanceMapping = make(map[string]map[string]string)
|
||||||
|
|
||||||
var sampleConfig = `
|
var sampleConfig = `
|
||||||
|
@ -286,14 +284,24 @@ func findnodename(node Node, ids []string) (string, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Snmp) Gather(acc telegraf.Accumulator) error {
|
func (s *Snmp) Gather(acc telegraf.Accumulator) error {
|
||||||
|
// TODO put this in cache on first run
|
||||||
// Create subtables mapping
|
// Create subtables mapping
|
||||||
if len(SubTableMap) == 0 {
|
if len(s.subTableMap) == 0 {
|
||||||
|
s.subTableMap = make(map[string]Subtable)
|
||||||
for _, sb := range s.Subtable {
|
for _, sb := range s.Subtable {
|
||||||
SubTableMap[sb.Name] = sb
|
s.subTableMap[sb.Name] = sb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO put this in cache on first run
|
||||||
// Create oid tree
|
// Create oid tree
|
||||||
if s.SnmptranslateFile != "" && len(initNode.subnodes) == 0 {
|
if s.SnmptranslateFile != "" && len(s.initNode.subnodes) == 0 {
|
||||||
|
s.nameToOid = make(map[string]string)
|
||||||
|
s.initNode = Node{
|
||||||
|
id: "1",
|
||||||
|
name: "",
|
||||||
|
subnodes: make(map[string]Node),
|
||||||
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(s.SnmptranslateFile)
|
data, err := ioutil.ReadFile(s.SnmptranslateFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Reading SNMPtranslate file error: %s", err)
|
log.Printf("Reading SNMPtranslate file error: %s", err)
|
||||||
|
@ -305,8 +313,8 @@ func (s *Snmp) Gather(acc telegraf.Accumulator) error {
|
||||||
if oids[2] != "" {
|
if oids[2] != "" {
|
||||||
oid_name := oids[1]
|
oid_name := oids[1]
|
||||||
oid := oids[2]
|
oid := oids[2]
|
||||||
fillnode(initNode, oid_name, strings.Split(string(oid), "."))
|
fillnode(s.initNode, oid_name, strings.Split(string(oid), "."))
|
||||||
NameToOid[oid_name] = oid
|
s.nameToOid[oid_name] = oid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,7 +338,7 @@ func (s *Snmp) Gather(acc telegraf.Accumulator) error {
|
||||||
// Get Easy GET oids
|
// Get Easy GET oids
|
||||||
for _, oidstring := range host.GetOids {
|
for _, oidstring := range host.GetOids {
|
||||||
oid := Data{}
|
oid := Data{}
|
||||||
if val, ok := NameToOid[oidstring]; ok {
|
if val, ok := s.nameToOid[oidstring]; ok {
|
||||||
// TODO should we add the 0 instance ?
|
// TODO should we add the 0 instance ?
|
||||||
oid.Name = oidstring
|
oid.Name = oidstring
|
||||||
oid.Oid = val
|
oid.Oid = val
|
||||||
|
@ -351,7 +359,7 @@ func (s *Snmp) Gather(acc telegraf.Accumulator) error {
|
||||||
// Get GET oids
|
// Get GET oids
|
||||||
for _, oid := range s.Get {
|
for _, oid := range s.Get {
|
||||||
if oid.Name == oid_name {
|
if oid.Name == oid_name {
|
||||||
if val, ok := NameToOid[oid.Oid]; ok {
|
if val, ok := s.nameToOid[oid.Oid]; ok {
|
||||||
// TODO should we add the 0 instance ?
|
// TODO should we add the 0 instance ?
|
||||||
if oid.Instance != "" {
|
if oid.Instance != "" {
|
||||||
oid.rawOid = "." + val + "." + oid.Instance
|
oid.rawOid = "." + val + "." + oid.Instance
|
||||||
|
@ -367,7 +375,7 @@ func (s *Snmp) Gather(acc telegraf.Accumulator) error {
|
||||||
// Get GETBULK oids
|
// Get GETBULK oids
|
||||||
for _, oid := range s.Bulk {
|
for _, oid := range s.Bulk {
|
||||||
if oid.Name == oid_name {
|
if oid.Name == oid_name {
|
||||||
if val, ok := NameToOid[oid.Oid]; ok {
|
if val, ok := s.nameToOid[oid.Oid]; ok {
|
||||||
oid.rawOid = "." + val
|
oid.rawOid = "." + val
|
||||||
} else {
|
} else {
|
||||||
oid.rawOid = oid.Oid
|
oid.rawOid = oid.Oid
|
||||||
|
@ -389,26 +397,27 @@ func (s *Snmp) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Launch Mapping
|
// Launch Mapping
|
||||||
|
// TODO put this in cache on first run
|
||||||
// TODO save mapping and computed oids
|
// TODO save mapping and computed oids
|
||||||
// to do it only the first time
|
// to do it only the first time
|
||||||
// only if len(OidInstanceMapping) == 0
|
// only if len(s.OidInstanceMapping) == 0
|
||||||
if len(OidInstanceMapping) >= 0 {
|
if len(OidInstanceMapping) >= 0 {
|
||||||
if err := host.SNMPMap(acc); err != nil {
|
if err := host.SNMPMap(acc, s.nameToOid, s.subTableMap); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Launch Get requests
|
// Launch Get requests
|
||||||
if err := host.SNMPGet(acc); err != nil {
|
if err := host.SNMPGet(acc, s.initNode); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := host.SNMPBulk(acc); err != nil {
|
if err := host.SNMPBulk(acc, s.initNode); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Host) SNMPMap(acc telegraf.Accumulator) error {
|
func (h *Host) SNMPMap(acc telegraf.Accumulator, nameToOid map[string]string, subTableMap map[string]Subtable) error {
|
||||||
// Get snmp client
|
// Get snmp client
|
||||||
snmpClient, err := h.GetSNMPClient()
|
snmpClient, err := h.GetSNMPClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -426,7 +435,7 @@ func (h *Host) SNMPMap(acc telegraf.Accumulator) error {
|
||||||
// This is just a bulk request
|
// This is just a bulk request
|
||||||
oid := Data{}
|
oid := Data{}
|
||||||
oid.Oid = table.oid
|
oid.Oid = table.oid
|
||||||
if val, ok := NameToOid[oid.Oid]; ok {
|
if val, ok := nameToOid[oid.Oid]; ok {
|
||||||
oid.rawOid = "." + val
|
oid.rawOid = "." + val
|
||||||
} else {
|
} else {
|
||||||
oid.rawOid = oid.Oid
|
oid.rawOid = oid.Oid
|
||||||
|
@ -441,7 +450,7 @@ func (h *Host) SNMPMap(acc telegraf.Accumulator) error {
|
||||||
// ... we create a new Data (oid) object
|
// ... we create a new Data (oid) object
|
||||||
oid := Data{}
|
oid := Data{}
|
||||||
// Looking for more information about this subtable
|
// Looking for more information about this subtable
|
||||||
ssb, exists := SubTableMap[sb]
|
ssb, exists := subTableMap[sb]
|
||||||
if exists {
|
if exists {
|
||||||
// We found a subtable section in config files
|
// We found a subtable section in config files
|
||||||
oid.Oid = ssb.Oid
|
oid.Oid = ssb.Oid
|
||||||
|
@ -528,7 +537,7 @@ func (h *Host) SNMPMap(acc telegraf.Accumulator) error {
|
||||||
// Add table oid in bulk oid list
|
// Add table oid in bulk oid list
|
||||||
oid := Data{}
|
oid := Data{}
|
||||||
oid.Oid = table.oid
|
oid.Oid = table.oid
|
||||||
if val, ok := NameToOid[oid.Oid]; ok {
|
if val, ok := nameToOid[oid.Oid]; ok {
|
||||||
oid.rawOid = "." + val
|
oid.rawOid = "." + val
|
||||||
} else {
|
} else {
|
||||||
oid.rawOid = oid.Oid
|
oid.rawOid = oid.Oid
|
||||||
|
@ -545,7 +554,7 @@ func (h *Host) SNMPMap(acc telegraf.Accumulator) error {
|
||||||
// ... we create a new Data (oid) object
|
// ... we create a new Data (oid) object
|
||||||
oid := Data{}
|
oid := Data{}
|
||||||
// Looking for more information about this subtable
|
// Looking for more information about this subtable
|
||||||
ssb, exists := SubTableMap[sb]
|
ssb, exists := subTableMap[sb]
|
||||||
if exists {
|
if exists {
|
||||||
// We found a subtable section in config files
|
// We found a subtable section in config files
|
||||||
oid.Oid = ssb.Oid + key
|
oid.Oid = ssb.Oid + key
|
||||||
|
@ -587,7 +596,7 @@ func (h *Host) SNMPMap(acc telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Host) SNMPGet(acc telegraf.Accumulator) error {
|
func (h *Host) SNMPGet(acc telegraf.Accumulator, initNode Node) error {
|
||||||
// Get snmp client
|
// Get snmp client
|
||||||
snmpClient, err := h.GetSNMPClient()
|
snmpClient, err := h.GetSNMPClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -620,7 +629,7 @@ func (h *Host) SNMPGet(acc telegraf.Accumulator) error {
|
||||||
return err3
|
return err3
|
||||||
}
|
}
|
||||||
// Handle response
|
// Handle response
|
||||||
_, err = h.HandleResponse(oidsList, result, acc)
|
_, err = h.HandleResponse(oidsList, result, acc, initNode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -628,7 +637,7 @@ func (h *Host) SNMPGet(acc telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Host) SNMPBulk(acc telegraf.Accumulator) error {
|
func (h *Host) SNMPBulk(acc telegraf.Accumulator, initNode Node) error {
|
||||||
// Get snmp client
|
// Get snmp client
|
||||||
snmpClient, err := h.GetSNMPClient()
|
snmpClient, err := h.GetSNMPClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -663,7 +672,7 @@ func (h *Host) SNMPBulk(acc telegraf.Accumulator) error {
|
||||||
return err3
|
return err3
|
||||||
}
|
}
|
||||||
// Handle response
|
// Handle response
|
||||||
last_oid, err := h.HandleResponse(oidsList, result, acc)
|
last_oid, err := h.HandleResponse(oidsList, result, acc, initNode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -715,7 +724,7 @@ func (h *Host) GetSNMPClient() (*gosnmp.GoSNMP, error) {
|
||||||
return snmpClient, nil
|
return snmpClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Host) HandleResponse(oids map[string]Data, result *gosnmp.SnmpPacket, acc telegraf.Accumulator) (string, error) {
|
func (h *Host) HandleResponse(oids map[string]Data, result *gosnmp.SnmpPacket, acc telegraf.Accumulator, initNode Node) (string, error) {
|
||||||
var lastOid string
|
var lastOid string
|
||||||
for _, variable := range result.Variables {
|
for _, variable := range result.Variables {
|
||||||
lastOid = variable.Name
|
lastOid = variable.Name
|
||||||
|
|
Loading…
Reference in New Issue