improvement(go.d/ddsnmp): use dev type and vendor from meta for family (#20439)
Ilya Mashchenko committed
Jun 8, 2025 at 11:18 UTC
1f6b0ce7568544bf547a47d46ad266f3dcf5d8f4
2 files changed
+42
-3
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/collector.go
+40
-1
@@ -8,6 +8,7 @@ import (
8
"log/slog"
9
"maps"
10
"slices"
11
+ "strings"
12
13
"github.com/gosnmp/gosnmp"
14
@@ -82,6 +83,28 @@ func (c *Collector) Collect() ([]*ProfileMetrics, error) {
83
c.log.Debugf("collecting metrics: %v", errors.Join(errs...))
84
}
85
86
+ // Find device vendor and type from any profile that has them.
87
+ // Multiple profiles can be loaded for a single device (e.g., base profiles, generic MIB profiles),
88
+ // but only device-specific profiles contain vendor/type information.
89
+ // We need to apply vendor/type to ALL metrics across ALL profiles to ensure consistent
90
+ // metric family naming (e.g., "interface/stats" → "router/cisco/interface/stats").
91
+ for _, ps := range c.profiles {
92
+ if !ps.initialized {
93
+ continue
94
+ }
95
+ if res, ok := ps.profile.Definition.Metadata["device"]; ok {
96
+ if dt, dv := res.Fields["type"].Value, res.Fields["vendor"].Value; dt != "" && dv != "" {
97
+ for _, pm := range metrics {
98
+ for i := range pm.Metrics {
99
+ m := &pm.Metrics[i]
100
+ m.Family = processMetricFamily(m.Family, dt, dv)
101
+ }
102
+ }
103
+ break
104
+ }
105
+ }
106
+ }
107
+
108
return metrics, nil
109
}
110
@@ -116,7 +139,6 @@ func (c *Collector) collectProfile(ps *profileState) (*ProfileMetrics, error) {
139
DeviceMetadata: maps.Clone(ps.deviceMetadata),
140
Metrics: metrics,
141
}, nil
119
-
142
}
143
144
func (c *Collector) snmpGet(oids []string) (map[string]gosnmp.SnmpPDU, error) {
@@ -137,3 +159,20 @@ func (c *Collector) snmpGet(oids []string) (map[string]gosnmp.SnmpPDU, error) {
159
160
return pdus, nil
161
}
162
+
163
+func processMetricFamily(family, devType, vendor string) string {
164
+ prefix := strings.TrimPrefix(devType+"s/"+vendor, "s/")
165
+ if prefix == "" {
166
+ return family
167
+ }
168
+ if family == "" {
169
+ return prefix
170
+ }
171
+
172
+ parts := strings.Split(family, "/")
173
+ parts = slices.DeleteFunc(parts, func(s string) bool {
174
+ return strings.EqualFold(s, devType) || strings.EqualFold(s, devType+"s") || strings.EqualFold(s, vendor)
175
+ })
176
+
177
+ return strings.TrimSuffix(prefix+"/"+strings.Join(parts, "/"), "/")
178
+}
src/go/plugin/go.d/config/go.d/snmp.profiles/default/mikrotik-router.yaml
+2
-2
@@ -5,9 +5,9 @@ metadata:
5
device:
6
fields:
7
vendor:
8
- value: "mikrotik"
8
+ value: "MikroTik"
9
type:
10
- value: "router"
10
+ value: "Router"
11
sysobjectid:
12
- 1.3.6.1.4.1.14988.1.*
13
metrics: