feat(go.d/snmp profile): add fallback support for duplicate metric tags (#20508)
* feat(go.d/snmp profile): add fallback support for duplicate metric tags * use function * rename * fix duplicate * rename func
Ilya Mashchenko committed
Jun 17, 2025 at 20:08 UTC
7c6d9e8a96d029faf517d3981f4c44c596a565e9
5 files changed
+32
-20
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/collect_device_meta.go
+2
-2
@@ -67,7 +67,7 @@ func (c *Collector) collectDeviceMetadata(prof *ddsnmp.Profile) (map[string]stri
67
errs = append(errs, fmt.Errorf("failed to process meta device tag value for '%s': %v", name, err))
68
continue
69
}
70
- tags[name] = v
70
+ mergeTagsWithEmptyFallback(tags, map[string]string{name: v})
71
case len(field.Symbols) > 0:
72
for _, sym := range field.Symbols {
73
v, err := processSymbolTagValue(sym, pdus)
@@ -75,7 +75,7 @@ func (c *Collector) collectDeviceMetadata(prof *ddsnmp.Profile) (map[string]stri
75
errs = append(errs, fmt.Errorf("failed to process meta device tag value for '%s': %v", name, err))
76
continue
77
}
78
- tags[name] = v
78
+ mergeTagsWithEmptyFallback(tags, map[string]string{name: v})
79
}
80
}
81
}
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/collect_global_tags.go
+6
-7
@@ -5,7 +5,6 @@ package ddsnmpcollector
5
import (
6
"errors"
7
"fmt"
8
- "maps"
8
"slices"
9
"strings"
10
@@ -40,30 +39,30 @@ func (c *Collector) collectGlobalTags(prof *ddsnmp.Profile) (map[string]string,
39
return nil, err
40
}
41
43
- tags := make(map[string]string)
42
+ globalTags := make(map[string]string)
43
var errs []error
44
45
for _, tag := range prof.Definition.StaticTags {
46
parts := strings.SplitN(tag, ":", 2)
47
if len(parts) == 2 {
49
- tags[parts[0]] = parts[1]
48
+ globalTags[parts[0]] = parts[1]
49
}
50
}
51
52
for _, cfg := range prof.Definition.MetricTags {
54
- v, err := processMetricTagValue(cfg, pdus)
53
+ tagValues, err := processMetricTagValue(cfg, pdus)
54
if err != nil {
55
errs = append(errs, fmt.Errorf("failed to process tag value for '%s/%s': %v", cfg.Tag, cfg.Symbol.Name, err))
56
continue
57
}
59
- maps.Copy(tags, v)
58
+ mergeTagsWithEmptyFallback(globalTags, tagValues)
59
}
60
62
- if len(errs) > 0 && len(tags) == 0 {
61
+ if len(errs) > 0 && len(globalTags) == 0 {
62
return nil, fmt.Errorf("failed to process any global tags: %v", errors.Join(errs...))
63
}
64
66
- return tags, nil
65
+ return globalTags, nil
66
}
67
68
func processMetricTagValue(cfg ddprofiledefinition.MetricTagConfig, pdus map[string]gosnmp.SnmpPDU) (map[string]string, error) {
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/collect_table.go
+4
-8
@@ -209,10 +209,8 @@ func (c *Collector) processTableData(cfg ddprofiledefinition.MetricsConfig, pdus
209
continue
210
}
211
212
- for k, v := range tags {
213
- rowTags[k] = v
214
- tagCache[index][k] = v
215
- }
212
+ mergeTagsWithEmptyFallback(rowTags, tags)
213
+ mergeTagsWithEmptyFallback(tagCache[index], tags)
214
}
215
}
216
@@ -268,10 +266,8 @@ func (c *Collector) processTableData(cfg ddprofiledefinition.MetricsConfig, pdus
266
continue
267
}
268
271
- for k, v := range tags {
272
- rowTags[k] = v
273
- tagCache[index][k] = v
274
- }
269
+ mergeTagsWithEmptyFallback(rowTags, tags)
270
+ mergeTagsWithEmptyFallback(tagCache[index], tags)
271
}
272
273
// Process index-based tags
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/utils.go
+8
@@ -252,3 +252,11 @@ func isMappingKeysNumeric(mapping map[string]string) bool {
252
}
253
return true
254
}
255
+
256
+func mergeTagsWithEmptyFallback(dest, src map[string]string) {
257
+ for k, v := range src {
258
+ if existing, ok := dest[k]; !ok || existing == "" {
259
+ dest[k] = v
260
+ }
261
+ }
262
+}
src/go/plugin/go.d/config/go.d/snmp.profiles/default/_generic-if.yaml
+12
-3
@@ -64,11 +64,15 @@ metrics:
64
family: Interfaces/Speed
65
unit: "bit/s"
66
metric_tags:
67
- - symbol:
67
+ - tag: interface
68
+ table: ifXTable
69
+ symbol:
70
OID: 1.3.6.1.2.1.31.1.1.1.1
71
name: ifName
70
- table: ifXTable
71
- tag: interface
72
+ - tag: interface
73
+ symbol:
74
+ OID: 1.3.6.1.2.1.2.2.1.2
75
+ name: ifDescr
76
- tag: if_type
77
symbol:
78
OID: 1.3.6.1.2.1.2.2.1.3
@@ -131,6 +135,11 @@ metrics:
135
symbol:
136
OID: 1.3.6.1.2.1.31.1.1.1.1
137
name: ifName
138
+ - tag: interface
139
+ table: ifTable
140
+ symbol:
141
+ OID: 1.3.6.1.2.1.2.2.1.2
142
+ name: ifDescr
143
- tag: if_type
144
table: ifTable
145
symbol: