From c0b4dcd28af5ad93b1c1f06a02e171001aa534ac Mon Sep 17 00:00:00 2001 From: Thibault Cohen Date: Wed, 17 Feb 2016 00:08:20 -0500 Subject: [PATCH] Add snmp table feature #540 --- plugins/inputs/snmp/snmp.go | 125 ++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/plugins/inputs/snmp/snmp.go b/plugins/inputs/snmp/snmp.go index 1932fed41ea30..a4f3cb43ea54e 100644 --- a/plugins/inputs/snmp/snmp.go +++ b/plugins/inputs/snmp/snmp.go @@ -20,6 +20,8 @@ type Snmp struct { Host []Host Get []Data Bulk []Data + Table []Table + Subtable []Subtable SnmptranslateFile string } @@ -36,9 +38,52 @@ type Host struct { Collect []string // easy get oids GetOids []string + // Table + Table []HostTable // Oids getOids []Data bulkOids []Data + tables []HostTable +} + + +type Table struct { + // name = "iftable" + Name string + // oid = ".1.3.6.1.2.1.31.1.1.1" + Oid string + //if empty get all instances + //mapping_table = ".1.3.6.1.2.1.31.1.1.1.1" + MappingTable string + // if empty get all subtables + // sub_tables could be not "real subtables" + //sub_tables=[".1.3.6.1.2.1.2.2.1.13", "bytes_recv", "bytes_send"] + SubTables []string +} + +type HostTable struct { + // name = "iftable" + Name string + // Includes only these instances + // include_instances = ["eth0", "eth1"] + IncludeInstances []string + // Excludes only these instances + // exclude_instances = ["eth20", "eth21"] + ExcludeInstances []string + // From Table struct + oid string + mappingTable string + subTables []string + +} + +type Subtable struct { + //name = "bytes_send" + Name string + //oid = ".1.3.6.1.2.1.31.1.1.1.10" + Oid string + //unit = "octets" + Unit string } type Data struct { @@ -71,6 +116,8 @@ var initNode = Node{ var NameToOid = make(map[string]string) +var OidInstanceMapping = make(map[string]string) + var sampleConfig = ` ### Use 'oids.txt' file to translate oids to names ### To generate 'oids.txt' you need to run: @@ -273,6 +320,23 @@ func (s *Snmp) Gather(acc telegraf.Accumulator) error { } } } + // Table + for _, hostTable := range host.Table { + for _, snmpTable := range s.Table { + if hostTable.Name == snmpTable.Name { + table := hostTable + table.oid = snmpTable.Oid + table.mappingTable = snmpTable.MappingTable + table.subTables = snmpTable.SubTables + host.tables = append(host.tables, table) + } + } + } + // Launch Mapping + // only if len(OidInstanceMapping) == 0 + if err := host.SNMPMap(acc); err != nil { + return err + } // Launch Get requests if err := host.SNMPGet(acc); err != nil { return err @@ -284,6 +348,67 @@ func (s *Snmp) Gather(acc telegraf.Accumulator) error { return nil } +func (h *Host) SNMPMap(acc telegraf.Accumulator) error { + // Get snmp client + snmpClient, err := h.GetSNMPClient() + if err != nil { + return err + } + // Deconnection + defer snmpClient.Conn.Close() + // Prepare OIDs + for _, table := range h.tables { + oid_asked := table.mappingTable + need_more_requests := true + // Set max repetition + maxRepetition := uint8(32) + // Launch requests + for need_more_requests { + // Launch request + result, err3 := snmpClient.GetBulk([]string{oid_asked}, 0, maxRepetition) + if err3 != nil { + return err3 + } + + lastOid := "" + for _, variable := range result.Variables { + lastOid = variable.Name + if strings.HasPrefix(variable.Name, oid_asked) { + switch variable.Type { + // handle Metrics + case gosnmp.OctetString: + key := strings.Replace(variable.Name, oid_asked, "", 1) + OidInstanceMapping[key] = string(variable.Value.([]byte)) + for _, sb := range table.subTables{ + oid := Data{} + oid.Oid = sb + key + log.Print(string(variable.Value.([]byte))) + log.Print(sb + key) + //Name string + // Unit + //Unit string + + } + default: + } + } + } + // Determine if we need more requests + if strings.HasPrefix(lastOid, oid_asked) { + need_more_requests = true + } else { + need_more_requests = false + } + + } + } + // Mapping finished + + // Create newoids based on mapping + + return nil +} + func (h *Host) SNMPGet(acc telegraf.Accumulator) error { // Get snmp client snmpClient, err := h.GetSNMPClient()