@cryptotaxi247 / netdata / commits / 7c6d9e8a9

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: