@cryptotaxi247 / netdata-1 / commits / 1f6b0ce75

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: