chore(go.d/snmp): small cleanup snmp profiles code (#20274)
Ilya Mashchenko committed
May 12, 2025 at 16:20 UTC
897c2ba9d1ab7585f27bb19f27095c1344490ea3
11 files changed
+293
-470
src/go/plugin/go.d/agent/discovery/sd/discoverer/snmpsd/discoverer_test.go
+1
@@ -274,6 +274,7 @@ func prepareNewTarget(sub subnet, ip string) *target {
274
Contact: mockSysContact,
275
Name: mockSysName,
276
Location: mockSysLocation,
277
+ SysObjectID: mockSysObject[1:],
278
Organization: "net-snmp",
279
})
280
}
src/go/plugin/go.d/agent/discovery/sd/discoverer/snmpsd/sysinfo.go
+2
@@ -25,6 +25,7 @@ type SysInfo struct {
25
Name string `json:"name"`
26
Location string `json:"location"`
27
Organization string `json:"organization"`
28
+ SysObjectID string `json:"-"`
29
}
30
31
func GetSysInfo(client gosnmp.Handler) (*SysInfo, error) {
@@ -52,6 +53,7 @@ func GetSysInfo(client gosnmp.Handler) (*SysInfo, error) {
53
var sysObj string
54
if sysObj, err = PduToString(pdu); err == nil {
55
si.Organization = LookupBySysObject(sysObj)
56
+ si.SysObjectID = sysObj
57
}
58
case OidSysContact:
59
si.Contact, err = PduToString(pdu)
src/go/plugin/go.d/collector/snmp/collect.go
+10
-81
@@ -6,7 +6,6 @@ import (
6
"errors"
7
"fmt"
8
"slices"
9
- "strings"
9
10
"github.com/google/uuid"
11
"github.com/gosnmp/gosnmp"
@@ -17,25 +16,6 @@ import (
16
)
17
18
func (c *Collector) collect() (map[string]int64, error) {
20
-
21
- mx := make(map[string]int64)
22
-
23
- if c.EnableProfiles {
24
- sysObjectID, err := c.getSysObjectID(snmpsd.OidSysObject)
25
- if err != nil {
26
- return nil, err
27
- }
28
-
29
- matchingProfiles := ddsnmp.Find(sysObjectID)
30
-
31
- metricMap, err := c.parseMetricsFromProfiles(matchingProfiles)
32
- if err != nil {
33
- return nil, err
34
- }
35
- seen := make(map[string]bool)
36
- c.makeChartsFromMetricMap(mx, metricMap, seen)
37
- }
38
-
19
if c.sysInfo == nil {
20
si, err := snmpsd.GetSysInfo(c.snmpClient)
21
if err != nil {
@@ -48,6 +28,16 @@ func (c *Collector) collect() (map[string]int64, error) {
28
if c.CreateVnode {
29
c.vnode = c.setupVnode(si)
30
}
31
+
32
+ if c.EnableProfiles {
33
+ c.snmpProfiles = ddsnmp.Find(c.sysInfo.SysObjectID)
34
+ }
35
+ }
36
+
37
+ mx := make(map[string]int64)
38
+
39
+ if err := c.collectProfiles(mx); err != nil {
40
+ return nil, err
41
}
42
43
if err := c.collectSysUptime(mx); err != nil {
@@ -69,45 +59,6 @@ func (c *Collector) collect() (map[string]int64, error) {
59
return mx, nil
60
}
61
72
-func (c *Collector) getSysObjectID(oid string) (string, error) {
73
- resp, err := c.snmpClient.Get([]string{oid})
74
- if err != nil {
75
- return "", err
76
- }
77
- return strings.Replace(resp.Variables[0].Value.(string), ".", "", 1), nil
78
-}
79
-
80
-func (c *Collector) makeChartsFromMetricMap(mx map[string]int64, metricMap map[string]processedMetric, seen map[string]bool) error {
81
- for _, metric := range metricMap {
82
- if metric.tableName == "" {
83
- switch s := metric.value.(type) {
84
- case int:
85
- name := metric.name
86
- if name == "" {
87
- continue
88
- }
89
-
90
- seen[name] = true
91
-
92
- if !c.seenMetrics[name] {
93
- c.seenMetrics[name] = true
94
- c.addSNMPChart(metric)
95
- }
96
-
97
- mx[metric.name] = int64(s)
98
- }
99
- }
100
-
101
- }
102
- for name := range c.seenMetrics {
103
- if !seen[name] {
104
- delete(c.seenMetrics, name)
105
- c.removeSNMPChart(name)
106
- }
107
- }
108
- return nil
109
-}
110
-
62
func (c *Collector) collectSysUptime(mx map[string]int64) error {
63
resp, err := c.snmpClient.Get([]string{snmpsd.OidSysUptime})
64
if err != nil {
@@ -167,28 +118,6 @@ func (c *Collector) setupVnode(si *snmpsd.SysInfo) *vnodes.VirtualNode {
118
}
119
}
120
170
-func pduToString(pdu gosnmp.SnmpPDU) (string, error) {
171
- switch pdu.Type {
172
- case gosnmp.OctetString:
173
- // TODO: this isn't reliable (e.g. physAddress we need hex.EncodeToString())
174
- bs, ok := pdu.Value.([]byte)
175
- if !ok {
176
- return "", fmt.Errorf("OctetString is not a []byte but %T", pdu.Value)
177
- }
178
- return strings.ToValidUTF8(string(bs), "�"), nil
179
- case gosnmp.Counter32, gosnmp.Counter64, gosnmp.Integer, gosnmp.Gauge32:
180
- return gosnmp.ToBigInt(pdu.Value).String(), nil
181
- case gosnmp.ObjectIdentifier:
182
- v, ok := pdu.Value.(string)
183
- if !ok {
184
- return "", fmt.Errorf("ObjectIdentifier is not a string but %T", pdu.Value)
185
- }
186
- return strings.TrimPrefix(v, "."), nil
187
- default:
188
- return "", fmt.Errorf("unussported type: '%v'", pdu.Type)
189
- }
190
-}
191
-
121
func pduToInt(pdu gosnmp.SnmpPDU) (int64, error) {
122
switch pdu.Type {
123
case gosnmp.Counter32, gosnmp.Counter64, gosnmp.Integer, gosnmp.Gauge32, gosnmp.TimeTicks:
src/go/plugin/go.d/collector/snmp/collect_if_mib.go
+4
-3
@@ -10,6 +10,7 @@ import (
10
"strings"
11
12
"github.com/netdata/netdata/go/plugins/logger"
13
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/discovery/sd/discoverer/snmpsd"
14
15
"github.com/gosnmp/gosnmp"
16
)
@@ -82,7 +83,7 @@ func (c *Collector) collectNetworkInterfaces(mx map[string]int64) error {
83
case oidIfIndex:
84
iface.ifIndex, err = pduToInt(pdu)
85
case oidIfDescr:
85
- iface.ifDescr, err = pduToString(pdu)
86
+ iface.ifDescr, err = snmpsd.PduToString(pdu)
87
case oidIfType:
88
iface.ifType, err = pduToInt(pdu)
89
case oidIfMtu:
@@ -116,7 +117,7 @@ func (c *Collector) collectNetworkInterfaces(mx map[string]int64) error {
117
case oidIfOutErrors:
118
iface.ifOutErrors, err = pduToInt(pdu)
119
case oidIfName:
119
- iface.ifName, err = pduToString(pdu)
120
+ iface.ifName, err = snmpsd.PduToString(pdu)
121
case oidIfInMulticastPkts:
122
iface.ifInMulticastPkts, err = pduToInt(pdu)
123
case oidIfInBroadcastPkts:
@@ -144,7 +145,7 @@ func (c *Collector) collectNetworkInterfaces(mx map[string]int64) error {
145
case oidIfHighSpeed:
146
iface.ifHighSpeed, err = pduToInt(pdu)
147
case oidIfAlias:
147
- iface.ifAlias, err = pduToString(pdu)
148
+ iface.ifAlias, err = snmpsd.PduToString(pdu)
149
default:
150
continue
151
}
src/go/plugin/go.d/collector/snmp/collect_profiles.go
new
+165
@@ -0,0 +1,165 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package snmp
4
+
5
+import (
6
+ "fmt"
7
+ "log"
8
+ "strings"
9
+
10
+ "github.com/gosnmp/gosnmp"
11
+)
12
+
13
+type processedMetric struct {
14
+ oid string
15
+ name string
16
+ value interface{}
17
+ metricType gosnmp.Asn1BER
18
+ tableName string
19
+ unit string
20
+ description string
21
+}
22
+
23
+func (c *Collector) collectProfiles(mx map[string]int64) error {
24
+ if len(c.snmpProfiles) == 0 {
25
+ return nil
26
+ }
27
+
28
+ metricMap := map[string]processedMetric{}
29
+
30
+ for _, prof := range c.snmpProfiles {
31
+ results, err := parseMetrics(prof.Definition.Metrics)
32
+ if err != nil {
33
+ return err
34
+ }
35
+
36
+ for _, oid := range results.OIDs {
37
+ response, err := c.snmpClient.Get([]string{oid})
38
+ if err != nil {
39
+ return err
40
+ }
41
+ for _, metric := range results.parsedMetrics {
42
+ switch s := metric.(type) {
43
+ case parsedSymbolMetric:
44
+ if s.baseoid == oid {
45
+ metricMap[oid] = processedMetric{
46
+ oid: oid,
47
+ name: s.name,
48
+ value: response.Variables[0].Value,
49
+ metricType: response.Variables[0].Type,
50
+ unit: s.unit,
51
+ description: s.description,
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ for _, oid := range results.nextOIDs {
59
+ if len(oid) == 0 {
60
+ continue
61
+ }
62
+
63
+ tableRows, err := c.walkOIDTree(oid)
64
+ if err != nil {
65
+ return fmt.Errorf("error walking OID tree: %v, oid %s", err, oid)
66
+ }
67
+
68
+ for _, metric := range results.parsedMetrics {
69
+ switch s := metric.(type) {
70
+ case parsedTableMetric:
71
+ if s.rowOID == oid {
72
+ for key, value := range tableRows {
73
+ value.name = s.name
74
+ value.tableName = s.tableName
75
+ tableRows[key] = value
76
+ }
77
+ metricMap = mergeProcessedMetricMaps(metricMap, tableRows)
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ c.makeChartsFromMetricMap(mx, metricMap)
85
+
86
+ return nil
87
+}
88
+
89
+func (c *Collector) walkOIDTree(baseOID string) (map[string]processedMetric, error) {
90
+ tableRows := make(map[string]processedMetric)
91
+
92
+ currentOID := baseOID
93
+ for {
94
+ result, err := c.snmpClient.GetNext([]string{currentOID})
95
+ if err != nil {
96
+ return tableRows, fmt.Errorf("snmpgetnext failed: %v", err)
97
+ }
98
+ if len(result.Variables) == 0 {
99
+ log.Println("No OID returned, ending walk.")
100
+ return tableRows, nil
101
+ }
102
+ pdu := result.Variables[0]
103
+
104
+ nextOID := strings.Replace(pdu.Name, ".", "", 1) //remove dot at the start of the OID
105
+
106
+ // If the next OID does not start with the base OID, we've reached the end of the subtree.
107
+ if !strings.HasPrefix(nextOID, baseOID) {
108
+ return tableRows, nil
109
+ }
110
+
111
+ metricType := pdu.Type
112
+ value := fmt.Sprintf("%v", pdu.Value)
113
+
114
+ tableRows[nextOID] = processedMetric{
115
+ oid: nextOID,
116
+ value: value,
117
+ metricType: metricType,
118
+ }
119
+
120
+ currentOID = nextOID
121
+ }
122
+}
123
+
124
+func (c *Collector) makeChartsFromMetricMap(mx map[string]int64, metricMap map[string]processedMetric) {
125
+ seen := make(map[string]bool)
126
+
127
+ for _, metric := range metricMap {
128
+ if metric.tableName == "" {
129
+ switch s := metric.value.(type) {
130
+ case int:
131
+ name := metric.name
132
+ if name == "" {
133
+ continue
134
+ }
135
+
136
+ seen[name] = true
137
+
138
+ if !c.seenMetrics[name] {
139
+ c.seenMetrics[name] = true
140
+ c.addSNMPChart(metric)
141
+ }
142
+
143
+ mx[metric.name] = int64(s)
144
+ }
145
+ }
146
+
147
+ }
148
+ for name := range c.seenMetrics {
149
+ if !seen[name] {
150
+ delete(c.seenMetrics, name)
151
+ c.removeSNMPChart(name)
152
+ }
153
+ }
154
+}
155
+
156
+func mergeProcessedMetricMaps(m1 map[string]processedMetric, m2 map[string]processedMetric) map[string]processedMetric {
157
+ merged := make(map[string]processedMetric)
158
+ for k, v := range m1 {
159
+ merged[k] = v
160
+ }
161
+ for key, value := range m2 {
162
+ merged[key] = value
163
+ }
164
+ return merged
165
+}
src/go/plugin/go.d/collector/snmp/collector.go
+3
@@ -12,6 +12,7 @@ import (
12
"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/discovery/sd/discoverer/snmpsd"
13
"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module"
14
"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/vnodes"
15
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/snmp/ddsnmp"
16
17
"github.com/gosnmp/gosnmp"
18
)
@@ -85,6 +86,8 @@ type Collector struct {
86
sysInfo *snmpsd.SysInfo
87
88
customOids []string
89
+
90
+ snmpProfiles []*ddsnmp.Profile
91
}
92
93
func (c *Collector) Configuration() any {
src/go/plugin/go.d/collector/snmp/command_func.go
deleted
-42
@@ -1,42 +0,0 @@
1
-package snmp
2
-
3
-import (
4
- "fmt"
5
- "log"
6
- "strings"
7
-)
8
-
9
-func (c *Collector) walkOIDTree(baseOID string) (map[string]processedMetric, error) {
10
- tableRows := make(map[string]processedMetric)
11
-
12
- currentOID := baseOID
13
- for {
14
- result, err := c.snmpClient.GetNext([]string{currentOID})
15
- if err != nil {
16
- return tableRows, fmt.Errorf("snmpgetnext failed: %v", err)
17
- }
18
- if len(result.Variables) == 0 {
19
- log.Println("No OID returned, ending walk.")
20
- return tableRows, nil
21
- }
22
- pdu := result.Variables[0]
23
-
24
- nextOID := strings.Replace(pdu.Name, ".", "", 1) //remove dot at the start of the OID
25
-
26
- // If the next OID does not start with the base OID, we've reached the end of the subtree.
27
- if !strings.HasPrefix(nextOID, baseOID) {
28
- return tableRows, nil
29
- }
30
-
31
- metricType := pdu.Type
32
- value := fmt.Sprintf("%v", pdu.Value)
33
-
34
- tableRows[nextOID] = processedMetric{
35
- oid: nextOID,
36
- value: value,
37
- metricType: metricType,
38
- }
39
-
40
- currentOID = nextOID
41
- }
42
-}
src/go/plugin/go.d/collector/snmp/helpers.go
deleted
-73
@@ -1,73 +0,0 @@
1
-package snmp
2
-
3
-func sliceToStrings(items []interface{}) []string {
4
- var strs []string
5
- for _, v := range items {
6
- s, ok := v.(string)
7
- if !ok {
8
- // Handle error if an element is not a string.
9
- continue
10
- }
11
- strs = append(strs, s)
12
- }
13
- return strs
14
-}
15
-
16
-// func sliceToTableMetricTags(items []interface{}) []TableMetricTag {
17
-// var metricTag []TableMetricTag
18
-// for _, v := range items {
19
-// s, ok := v.(TableMetricTag)
20
-// if !ok {
21
-// // Handle error if an element is not a string.
22
-// continue
23
-// }
24
-// metricTag = append(metricTag, s)
25
-// }
26
-// return metricTag
27
-// }
28
-
29
-func mergeTableBatches(target tableBatches, source tableBatches) tableBatches {
30
- merged := tableBatches{}
31
-
32
- // Extend batches in `target` with OIDs from `source` that share the same key.
33
- for key, batch := range target {
34
-
35
- if srcBatch, ok := source[key]; ok {
36
- mergedOids := append(batch.oids, srcBatch.oids...)
37
- merged[key] = tableBatch{
38
- tableOID: batch.tableOID,
39
- oids: mergedOids,
40
- }
41
- }
42
- }
43
-
44
- for key := range source {
45
- if _, ok := target[key]; !ok {
46
- merged[key] = source[key]
47
- }
48
- }
49
-
50
- return merged
51
-}
52
-
53
-func mergeStringMaps(m1 map[string]string, m2 map[string]string) map[string]string {
54
- merged := make(map[string]string)
55
- for k, v := range m1 {
56
- merged[k] = v
57
- }
58
- for key, value := range m2 {
59
- merged[key] = value
60
- }
61
- return merged
62
-}
63
-
64
-func mergeProcessedMetricMaps(m1 map[string]processedMetric, m2 map[string]processedMetric) map[string]processedMetric {
65
- merged := make(map[string]processedMetric)
66
- for k, v := range m1 {
67
- merged[k] = v
68
- }
69
- for key, value := range m2 {
70
- merged[key] = value
71
- }
72
- return merged
73
-}
src/go/plugin/go.d/collector/snmp/parse_profiles.go
renamed
+108
-28
@@ -8,6 +8,99 @@ import (
8
"github.com/netdata/netdata/go/plugins/plugin/go.d/collector/snmp/ddsnmp/ddprofiledefinition"
9
)
10
11
+type (
12
+ parsedResult struct {
13
+ OIDs []string
14
+ nextOIDs []string
15
+ bulkOIDs []string
16
+ parsedMetrics []parsedMetric
17
+ }
18
+ parsedMetric any
19
+)
20
+
21
+type (
22
+ tableBatches map[tableBatchKey]tableBatch
23
+ tableBatchKey struct {
24
+ mib string
25
+ table string
26
+ }
27
+ tableBatch struct {
28
+ tableOID string
29
+ oids []string
30
+ }
31
+)
32
+
33
+type indexTag struct {
34
+ parsedMetricTag parsedMetricTag
35
+ index int
36
+}
37
+
38
+type columnTag struct {
39
+ parsedMetricTag parsedMetricTag
40
+ column string
41
+ indexSlices []indexSlice
42
+}
43
+
44
+type indexMapping struct {
45
+ tag string
46
+ index int
47
+ mapping map[int]string
48
+}
49
+
50
+type parsedSymbol struct {
51
+ name string
52
+ oid string
53
+ extractValuePattern *regexp.Regexp
54
+ oidsToResolve map[string]string
55
+}
56
+
57
+type parsedSymbolMetric struct {
58
+ name string
59
+ tags []string
60
+ forcedType string
61
+ enforceScalar bool
62
+ options map[string]string
63
+ extractValuePattern *regexp.Regexp
64
+ baseoid string //TODO consider changing this to OID, it will not have nested OIDs as it is a symbol
65
+ unit string
66
+ description string
67
+}
68
+
69
+type parsedTableMetric struct {
70
+ name string
71
+ indexTags []indexTag
72
+ columnTags []columnTag
73
+ forcedType string
74
+ options map[string]string
75
+ extractValuePattern *regexp.Regexp
76
+ rowOID string
77
+ tableName string
78
+ tableOID string
79
+}
80
+
81
+// union of two above
82
+
83
+type parsedMetricTag struct {
84
+ name string
85
+
86
+ tags []string
87
+ pattern *regexp.Regexp
88
+ // symbol Symbol not used yet
89
+}
90
+
91
+type metricParseResult struct {
92
+ oidsToFetch []string
93
+ oidsToResolve map[string]string
94
+ indexMappings []indexMapping
95
+ tableBatches tableBatches
96
+ parsedMetrics []parsedMetric
97
+}
98
+
99
+type indexSlice struct {
100
+ Start int
101
+ End int
102
+}
103
+
104
func parseMetrics(metrics []ddprofiledefinition.MetricsConfig) (parsedResult, error) {
105
var (
106
OIDs, nextOIDs, bulkOIDs []string
@@ -93,16 +186,17 @@ func parseMetric(metric ddprofiledefinition.MetricsConfig) (metricParseResult, e
186
// TODO investigate if this exists in the yamls
187
// return (parseOIDMetric(oidMetric{name: metric.Name, oid: metric.OID, metricTags: castedStringMetricTags, forcedType: string(metric.MetricType), options: metric.Options})), nil
188
return metricParseResult{}, nil
96
-
97
- } else if len(metric.MIB) == 0 {
189
+ }
190
+ if len(metric.MIB) == 0 {
191
return metricParseResult{}, fmt.Errorf("unsupported metric {%v}", metric)
99
- } else if metric.Symbol != (ddprofiledefinition.SymbolConfig{}) {
192
+ }
193
+ if metric.Symbol != (ddprofiledefinition.SymbolConfig{}) {
194
// Single Metric
101
- return (parseSymbolMetric(metric.Symbol, metric.MIB)) // TODO metric tags might be needed here.
195
+ return parseSymbolMetric(metric.Symbol, metric.MIB) // TODO metric tags might be needed here.
196
//Can't support tables at the moment
103
- } else {
104
- return metricParseResult{}, nil
197
}
198
+ return metricParseResult{}, nil
199
+
200
}
201
202
// TODO error outs on functions
@@ -169,28 +263,17 @@ func parseSymbol(symbol interface{}) (parsedSymbol, error) {
263
264
switch s := symbol.(type) {
265
case ddprofiledefinition.SymbolConfig:
172
- oid := s.OID
173
- name := s.Name
266
+ ps := parsedSymbol{
267
+ name: s.Name,
268
+ oid: s.OID,
269
+ oidsToResolve: map[string]string{s.Name: s.OID},
270
+ }
271
if s.ExtractValue != "" {
175
- extractValuePattern, err := regexp.Compile(s.ExtractValue)
176
- if err != nil {
177
-
178
- return parsedSymbol{}, err
272
+ if v, err := regexp.Compile(s.ExtractValue); err != nil {
273
+ ps.extractValuePattern = v
274
}
180
- return parsedSymbol{
181
- name,
182
- oid,
183
- extractValuePattern,
184
- map[string]string{name: oid},
185
- }, nil
186
- } else {
187
- return parsedSymbol{
188
- name,
189
- oid,
190
- nil,
191
- map[string]string{name: oid},
192
- }, nil
275
}
276
+ return ps, nil
277
case string:
278
return parsedSymbol{}, errors.New("string only symbol, can't support yet")
279
case map[string]interface{}:
@@ -198,7 +281,6 @@ func parseSymbol(symbol interface{}) (parsedSymbol, error) {
281
name, okName := s["name"].(string)
282
283
if !okOID || !okName {
201
-
284
return parsedSymbol{}, fmt.Errorf("invalid symbol format: %+v", s)
285
}
286
@@ -208,9 +290,7 @@ func parseSymbol(symbol interface{}) (parsedSymbol, error) {
290
extractValuePattern: nil,
291
oidsToResolve: map[string]string{name: oid},
292
}, nil
211
-
293
default:
294
return parsedSymbol{}, fmt.Errorf("unsupported symbol type: %T", symbol)
295
}
215
-
296
}
src/go/plugin/go.d/collector/snmp/profile.go
deleted
-88
@@ -1,88 +0,0 @@
1
-package snmp
2
-
3
-import (
4
- "fmt"
5
-
6
- "github.com/gosnmp/gosnmp"
7
-
8
- "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/snmp/ddsnmp"
9
-)
10
-
11
-func (s *SysObjectIDs) UnmarshalYAML(unmarshal func(any) error) error {
12
- var single string
13
- if err := unmarshal(&single); err == nil {
14
- *s = []string{single}
15
- return nil
16
- }
17
-
18
- var multiple []string
19
- if err := unmarshal(&multiple); err == nil {
20
- *s = multiple
21
- return nil
22
- }
23
-
24
- return fmt.Errorf("invalid sysobjectid format")
25
-}
26
-
27
-func (c *Collector) parseMetricsFromProfiles(matchingProfiles []*ddsnmp.Profile) (map[string]processedMetric, error) {
28
- metricMap := map[string]processedMetric{}
29
- for _, profile := range matchingProfiles {
30
- profileDef := profile.Definition
31
- results, err := parseMetrics(profileDef.Metrics)
32
- if err != nil {
33
- return nil, err
34
- }
35
-
36
- for _, oid := range results.OIDs {
37
- response, err := c.snmpClient.Get([]string{oid})
38
- if err != nil {
39
- return nil, err
40
- }
41
- if (response != &gosnmp.SnmpPacket{}) {
42
- for _, metric := range results.parsedMetrics {
43
- switch s := metric.(type) {
44
- case parsedSymbolMetric:
45
- // find a matching metric
46
- if s.baseoid == oid {
47
- metricName := s.name
48
- metricType := response.Variables[0].Type
49
- metricValue := response.Variables[0].Value
50
- metricUnit := s.unit
51
- metricDescription := s.description
52
-
53
- metricMap[oid] = processedMetric{oid: oid, name: metricName, value: metricValue, metricType: metricType, unit: metricUnit, description: metricDescription}
54
- }
55
- }
56
- }
57
-
58
- }
59
- }
60
-
61
- for _, oid := range results.nextOIDs {
62
- if len(oid) < 1 {
63
- continue
64
- }
65
- if tableRows, err := c.walkOIDTree(oid); err != nil {
66
- return nil, fmt.Errorf("error walking OID tree: %v, oid %s", err, oid)
67
- } else {
68
- for _, metric := range results.parsedMetrics {
69
- switch s := metric.(type) {
70
- case parsedTableMetric:
71
- // find a matching metric
72
- if s.rowOID == oid {
73
- for key, value := range tableRows {
74
- value.name = s.name
75
- value.tableName = s.tableName
76
- tableRows[key] = value
77
- }
78
- metricMap = mergeProcessedMetricMaps(metricMap, tableRows)
79
- }
80
- }
81
- }
82
- }
83
-
84
- }
85
-
86
- }
87
- return metricMap, nil
88
-}
src/go/plugin/go.d/collector/snmp/types.go
deleted
-155
@@ -1,155 +0,0 @@
1
-package snmp
2
-
3
-import (
4
- "regexp"
5
-
6
- "github.com/gosnmp/gosnmp"
7
-)
8
-
9
-type snmpPDU struct {
10
- value interface{}
11
- oid string
12
- metricType gosnmp.Asn1BER
13
-}
14
-
15
-type SysObjectIDs []string
16
-
17
-type parsedResult struct {
18
- OIDs []string
19
- nextOIDs []string
20
- bulkOIDs []string
21
- parsedMetrics []parsedMetric
22
-}
23
-
24
-type tableBatchKey struct {
25
- mib string
26
- table string
27
-}
28
-
29
-type tableBatch struct {
30
- tableOID string
31
- oids []string
32
-}
33
-
34
-type tableBatches map[tableBatchKey]tableBatch
35
-
36
-type indexTag struct {
37
- parsedMetricTag parsedMetricTag
38
- index int
39
-}
40
-
41
-type columnTag struct {
42
- parsedMetricTag parsedMetricTag
43
- column string
44
- indexSlices []IndexSlice
45
-}
46
-
47
-type indexMapping struct {
48
- tag string
49
- index int
50
- mapping map[int]string
51
-}
52
-
53
-type parsedSymbol struct {
54
- name string
55
- oid string
56
- extractValuePattern *regexp.Regexp
57
- oidsToResolve map[string]string
58
-}
59
-
60
-type parsedColumnMetricTag struct {
61
- oidsToResolve map[string]string
62
- tableBatches tableBatches
63
- columnTags []columnTag
64
-}
65
-type parsedIndexMetricTag struct {
66
- indexTags []indexTag
67
- indexMappings map[int]map[string]string
68
-}
69
-
70
-type parsedTableMetricTag struct {
71
- oidsToResolve map[string]string
72
- tableBatches tableBatches
73
- columnTags []columnTag
74
- indexTags []indexTag
75
- indexMappings map[int]map[int]string
76
-}
77
-
78
-type parsedSymbolMetric struct {
79
- name string
80
- tags []string
81
- forcedType string
82
- enforceScalar bool
83
- options map[string]string
84
- extractValuePattern *regexp.Regexp
85
- baseoid string //TODO consider changing this to OID, it will not have nested OIDs as it is a symbol
86
- unit string
87
- description string
88
-}
89
-
90
-type parsedTableMetric struct {
91
- name string
92
- indexTags []indexTag
93
- columnTags []columnTag
94
- forcedType string
95
- options map[string]string
96
- extractValuePattern *regexp.Regexp
97
- rowOID string
98
- tableName string
99
- tableOID string
100
-}
101
-
102
-// union of two above
103
-type parsedMetric any
104
-
105
-// Not supported yet
106
-/*type parsedSimpleMetricTag struct {
107
- name string
108
- }
109
-
110
-type parsedMatchMetricTag struct {
111
-tags []string
112
-symbol Symbol
113
-pattern *regexp.Regexp
114
-}
115
-
116
- type symbolTag struct {
117
- parsedMetricTag parsedMetricTag
118
- symbol string
119
- }
120
-
121
- type parsedSymbolTagsResult struct {
122
- oids []string
123
- parsedSymbolTags []symbolTag
124
- }
125
-*/
126
-type parsedMetricTag struct {
127
- name string
128
-
129
- tags []string
130
- pattern *regexp.Regexp
131
- // symbol Symbol not used yet
132
-}
133
-
134
-type metricParseResult struct {
135
- oidsToFetch []string
136
- oidsToResolve map[string]string
137
- indexMappings []indexMapping
138
- tableBatches tableBatches
139
- parsedMetrics []parsedMetric
140
-}
141
-
142
-type IndexSlice struct {
143
- Start int
144
- End int
145
-}
146
-
147
-type processedMetric struct {
148
- oid string
149
- name string
150
- value interface{}
151
- metricType gosnmp.Asn1BER
152
- tableName string
153
- unit string
154
- description string
155
-}