improve(go.d/snmp): add profile device meta to vnode labels (#20718)
Ilya Mashchenko committed
Jul 22, 2025 at 18:03 UTC
440f7a9afc51ad4ab09c6d9afed1a22e4465f9e8
3 files changed
+46
-17
src/go/plugin/go.d/collector/snmp/collect.go
+31
-11
@@ -17,6 +17,7 @@ import (
17
"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/discovery/sd/discoverer/snmpsd"
18
"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/vnodes"
19
"github.com/netdata/netdata/go/plugins/plugin/go.d/collector/snmp/ddsnmp"
20
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector"
21
)
22
23
func (c *Collector) collect() (map[string]int64, error) {
@@ -26,19 +27,28 @@ func (c *Collector) collect() (map[string]int64, error) {
27
return nil, err
28
}
29
29
- c.sysInfo = si
30
+ if c.DisableLegacyCollection || c.EnableProfiles {
31
+ c.snmpProfiles = c.setupProfiles(si.SysObjectID)
32
+ }
33
+
34
+ if c.ddSnmpColl == nil {
35
+ c.ddSnmpColl = ddsnmpcollector.New(c.snmpClient, c.snmpProfiles, c.Logger)
36
+ c.ddSnmpColl.DoTableMetrics = c.EnableProfilesTableMetrics
37
+ }
38
39
if c.CreateVnode {
32
- c.vnode = c.setupVnode(si)
40
+ deviceMeta, err := c.ddSnmpColl.CollectDeviceMetadata()
41
+ if err != nil {
42
+ return nil, err
43
+ }
44
+ c.vnode = c.setupVnode(si, deviceMeta)
45
}
46
47
+ c.sysInfo = si
48
+
49
if !c.DisableLegacyCollection {
50
c.addSysUptimeChart()
51
}
38
-
39
- if c.DisableLegacyCollection || c.EnableProfiles {
40
- c.snmpProfiles = c.setupProfiles()
41
- }
52
}
53
54
mx := make(map[string]int64)
@@ -93,7 +103,7 @@ func (c *Collector) walkAll(rootOid string) ([]gosnmp.SnmpPDU, error) {
103
return c.snmpClient.BulkWalkAll(rootOid)
104
}
105
96
-func (c *Collector) setupVnode(si *snmpsd.SysInfo) *vnodes.VirtualNode {
106
+func (c *Collector) setupVnode(si *snmpsd.SysInfo, deviceMeta map[string]map[string]string) *vnodes.VirtualNode {
107
if c.Vnode.GUID == "" {
108
c.Vnode.GUID = uuid.NewSHA1(uuid.NameSpaceDNS, []byte(c.Hostname)).String()
109
}
@@ -120,6 +130,14 @@ func (c *Collector) setupVnode(si *snmpsd.SysInfo) *vnodes.VirtualNode {
130
// FIXME: vendor should be obtained from sysDescr, org should be used as a fallback
131
labels["vendor"] = si.Organization
132
133
+ for _, meta := range deviceMeta {
134
+ for k, v := range meta {
135
+ if _, ok := labels[k]; !ok {
136
+ labels[k] = v
137
+ }
138
+ }
139
+ }
140
+
141
return &vnodes.VirtualNode{
142
GUID: c.Vnode.GUID,
143
Hostname: c.Vnode.Hostname,
@@ -127,9 +145,10 @@ func (c *Collector) setupVnode(si *snmpsd.SysInfo) *vnodes.VirtualNode {
145
}
146
}
147
130
-func (c *Collector) setupProfiles() []*ddsnmp.Profile {
131
- snmpProfiles := ddsnmp.FindProfiles(c.sysInfo.SysObjectID)
148
+func (c *Collector) setupProfiles(sysObjectID string) []*ddsnmp.Profile {
149
+ snmpProfiles := ddsnmp.FindProfiles(sysObjectID)
150
var profInfo []string
151
+
152
for _, prof := range snmpProfiles {
153
if logger.Level.Enabled(slog.LevelDebug) {
154
profInfo = append(profInfo, prof.SourceTree())
@@ -138,8 +157,9 @@ func (c *Collector) setupProfiles() []*ddsnmp.Profile {
157
profInfo = append(profInfo, name)
158
}
159
}
141
- c.Infof("device matched %d profile(s): %s (sysObjectID: %s)",
142
- len(snmpProfiles), strings.Join(profInfo, ", "), c.sysInfo.SysObjectID)
160
+
161
+ c.Infof("device matched %d profile(s): %s (sysObjectID: %s)", len(snmpProfiles), strings.Join(profInfo, ", "), sysObjectID)
162
+
163
return snmpProfiles
164
}
165
src/go/plugin/go.d/collector/snmp/collect_profiles.go
+1
-6
@@ -8,18 +8,13 @@ import (
8
"strings"
9
10
"github.com/netdata/netdata/go/plugins/plugin/go.d/collector/snmp/ddsnmp"
11
- "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector"
11
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/metrix"
12
)
13
14
func (c *Collector) collectProfiles(mx map[string]int64) error {
16
- if len(c.snmpProfiles) == 0 {
15
+ if len(c.snmpProfiles) == 0 || c.ddSnmpColl == nil {
16
return nil
17
}
19
- if c.ddSnmpColl == nil {
20
- c.ddSnmpColl = ddsnmpcollector.New(c.snmpClient, c.snmpProfiles, c.Logger)
21
- c.ddSnmpColl.DoTableMetrics = c.EnableProfilesTableMetrics
22
- }
18
19
pms, err := c.ddSnmpColl.Collect()
20
if err != nil {
src/go/plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector/collector.go
+14
@@ -64,6 +64,20 @@ type (
64
}
65
)
66
67
+func (c *Collector) CollectDeviceMetadata() (map[string]map[string]string, error) {
68
+ meta := make(map[string]map[string]string)
69
+
70
+ for _, prof := range c.profiles {
71
+ dm, err := c.deviceMetadataCollector.Collect(prof.profile)
72
+ if err != nil {
73
+ return nil, err
74
+ }
75
+ meta[prof.profile.SourceFile] = dm
76
+ }
77
+
78
+ return meta, nil
79
+}
80
+
81
func (c *Collector) Collect() ([]*ddsnmp.ProfileMetrics, error) {
82
var metrics []*ddsnmp.ProfileMetrics
83
var errs []error