go.d snmp: add config options to filter interfaces by name and type (#18023)
Ilya Mashchenko committed
Jun 27, 2024 at 14:25 UTC
0458b23782189f5ee9bcddb2b17869be30db8527
8 files changed
+95
-12
src/go/collectors/go.d.plugin/modules/snmp/collect.go
+6
-1
@@ -106,7 +106,7 @@ func (s *SNMP) collectNetworkInterfaces(mx map[string]int64) error {
106
i.updated = false
107
}
108
109
- pdus := make([]gosnmp.SnmpPDU, 0, len(ifMibXTable)+len(ifMibXTable))
109
+ pdus := make([]gosnmp.SnmpPDU, 0, len(ifMibTable)+len(ifMibXTable))
110
pdus = append(pdus, ifMibTable...)
111
pdus = append(pdus, ifMibXTable...)
112
@@ -208,6 +208,11 @@ func (s *SNMP) collectNetworkInterfaces(mx map[string]int64) error {
208
continue
209
}
210
211
+ typeStr := ifTypeMapping[iface.ifType]
212
+ if s.netIfaceFilterByName.MatchString(iface.ifName) || s.netIfaceFilterByType.MatchString(typeStr) {
213
+ continue
214
+ }
215
+
216
if !iface.updated {
217
delete(s.netInterfaces, iface.idx)
218
if iface.hasCharts {
src/go/collectors/go.d.plugin/modules/snmp/config.go
+11
-6
@@ -4,12 +4,17 @@ package snmp
4
5
type (
6
Config struct {
7
- UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
8
- Hostname string `yaml:"hostname" json:"hostname"`
9
- Community string `yaml:"community,omitempty" json:"community"`
10
- User User `yaml:"user,omitempty" json:"user"`
11
- Options Options `yaml:"options,omitempty" json:"options"`
12
- ChartsInput []ChartConfig `yaml:"charts,omitempty" json:"charts"`
7
+ UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
8
+ Hostname string `yaml:"hostname" json:"hostname"`
9
+ Community string `yaml:"community,omitempty" json:"community"`
10
+ User User `yaml:"user,omitempty" json:"user"`
11
+ Options Options `yaml:"options,omitempty" json:"options"`
12
+ ChartsInput []ChartConfig `yaml:"charts,omitempty" json:"charts"`
13
+ NetworkInterfaceFilter NetworkInterfaceFilter `yaml:"network_interface_filter,omitempty" json:"network_interface_filter"`
14
+ }
15
+ NetworkInterfaceFilter struct {
16
+ ByName string `yaml:"by_name,omitempty" json:"by_name"`
17
+ ByType string `yaml:"by_type,omitempty" json:"by_type"`
18
}
19
User struct {
20
Name string `yaml:"name,omitempty" json:"name"`
src/go/collectors/go.d.plugin/modules/snmp/config_schema.json
+25
-1
@@ -21,6 +21,26 @@
21
"type": "string",
22
"default": "public"
23
},
24
+ "network_interface_filter": {
25
+ "title": "Network interface filter",
26
+ "description": "Configuration for filtering specific network interfaces. If left empty, no interfaces will be filtered. You can filter interfaces by name or type using [simple patterns](/src/libnetdata/simple_pattern/README.md#simple-patterns).",
27
+ "type": [
28
+ "object",
29
+ "null"
30
+ ],
31
+ "properties": {
32
+ "by_name": {
33
+ "title": "By Name",
34
+ "description": "Specify the interface name or a pattern to match against the [ifName](https://cric.grenoble.cnrs.fr/Administrateurs/Outils/MIBS/?oid=1.3.6.1.2.1.31.1.1.1.1) label.",
35
+ "type": "string"
36
+ },
37
+ "by_type": {
38
+ "title": "By Type",
39
+ "description": "Specify the interface type or a pattern to match against the [ifType](https://cric.grenoble.cnrs.fr/Administrateurs/Outils/MIBS/?oid=1.3.6.1.2.1.2.2.1.3) label.",
40
+ "type": "string"
41
+ }
42
+ }
43
+ },
44
"options": {
45
"title": "Options",
46
"description": "Configuration options for SNMP monitoring.",
@@ -301,6 +321,9 @@
321
"uiOptions": {
322
"fullPage": true
323
},
324
+ "network_interface_filter": {
325
+ "ui:collapsible": true
326
+ },
327
"options": {
328
"version": {
329
"ui:widget": "radio",
@@ -369,8 +392,9 @@
392
]
393
},
394
{
372
- "title": "Conn Options",
395
+ "title": "Options",
396
"fields": [
397
+ "network_interface_filter",
398
"options"
399
]
400
},
src/go/collectors/go.d.plugin/modules/snmp/init.go
+24
@@ -8,6 +8,8 @@ import (
8
"strings"
9
"time"
10
11
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/matcher"
12
+
13
"github.com/gosnmp/gosnmp"
14
)
15
@@ -61,6 +63,28 @@ func (s *SNMP) initSNMPClient() (gosnmp.Handler, error) {
63
return client, nil
64
}
65
66
+func (s *SNMP) initNetIfaceFilters() (matcher.Matcher, matcher.Matcher, error) {
67
+ byName, byType := matcher.FALSE(), matcher.FALSE()
68
+
69
+ if v := s.NetworkInterfaceFilter.ByName; v != "" {
70
+ m, err := matcher.NewSimplePatternsMatcher(v)
71
+ if err != nil {
72
+ return nil, nil, err
73
+ }
74
+ byName = m
75
+ }
76
+
77
+ if v := s.NetworkInterfaceFilter.ByType; v != "" {
78
+ m, err := matcher.NewSimplePatternsMatcher(v)
79
+ if err != nil {
80
+ return nil, nil, err
81
+ }
82
+ byType = m
83
+ }
84
+
85
+ return byName, byType, nil
86
+}
87
+
88
func (s *SNMP) initOIDs() (oids []string) {
89
for _, c := range *s.charts {
90
for _, d := range c.Dims {
src/go/collectors/go.d.plugin/modules/snmp/metadata.yaml
+10
-4
@@ -51,11 +51,9 @@ modules:
51
description: ""
52
performance_impact:
53
description: |
54
- **Performance Considerations**:
54
+ **Device limitations**: Many SNMP switches and routers have limited processing power. They might not be able to report data as frequently as desired. You can monitor response times using go.d.plugin in debug mode to identify potential bottlenecks.
55
56
- - **Device limitations**: Many SNMP switches and routers have limited processing power. They might not be able to report data as frequently as desired. You can monitor response times using go.d.plugin in debug mode to identify potential bottlenecks.
57
-
58
- - **Concurrent access**: If multiple collectors or tools access the same SNMP device simultaneously, data points might be skipped. This is a limitation of the device itself, not this collector. To mitigate this, consider increasing the collection interval (update_every) to reduce the frequency of requests.
56
+ **Concurrent access**: If multiple collectors or tools access the same SNMP device simultaneously, data points might be skipped. This is a limitation of the device itself, not this collector. To mitigate this, consider increasing the collection interval (update_every) to reduce the frequency of requests.
57
setup:
58
prerequisites:
59
list: []
@@ -109,6 +107,14 @@ modules:
107
description: Maximum number of OIDs allowed in a single GET request.
108
default_value: 60
109
required: false
110
+ - name: network_interface_filter.by_name
111
+ description: "Filter interfaces by their names using [simple patterns](/src/libnetdata/simple_pattern/README.md#simple-patterns)."
112
+ default_value: ""
113
+ required: false
114
+ - name: network_interface_filter.by_type
115
+ description: "Filter interfaces by their types using [simple patterns](/src/libnetdata/simple_pattern/README.md#simple-patterns)."
116
+ default_value: ""
117
+ required: false
118
- name: user.name
119
description: SNMPv3 user name.
120
default_value: ""
src/go/collectors/go.d.plugin/modules/snmp/snmp.go
+12
@@ -6,6 +6,7 @@ import (
6
_ "embed"
7
"errors"
8
"github.com/netdata/netdata/go/go.d.plugin/agent/module"
9
+ "github.com/netdata/netdata/go/go.d.plugin/pkg/matcher"
10
11
"github.com/gosnmp/gosnmp"
12
)
@@ -59,6 +60,9 @@ type SNMP struct {
60
newSnmpClient func() gosnmp.Handler
61
snmpClient gosnmp.Handler
62
63
+ netIfaceFilterByName matcher.Matcher
64
+ netIfaceFilterByType matcher.Matcher
65
+
66
collectIfMib bool
67
netInterfaces map[string]*netInterface
68
sysName string
@@ -90,6 +94,14 @@ func (s *SNMP) Init() error {
94
}
95
s.snmpClient = snmpClient
96
97
+ byName, byType, err := s.initNetIfaceFilters()
98
+ if err != nil {
99
+ s.Errorf("failed to initialize network interface filters: %v", err)
100
+ return err
101
+ }
102
+ s.netIfaceFilterByName = byName
103
+ s.netIfaceFilterByType = byType
104
+
105
charts, err := newUserInputCharts(s.ChartsInput)
106
if err != nil {
107
s.Errorf("failed to create user charts: %v", err)
src/go/collectors/go.d.plugin/modules/snmp/testdata/config.json
+4
@@ -2,6 +2,10 @@
2
"update_every": 123,
3
"hostname": "ok",
4
"community": "ok",
5
+ "network_interface_filter": {
6
+ "by_name": "ok",
7
+ "by_type": "ok"
8
+ },
9
"user": {
10
"name": "ok",
11
"level": "ok",
src/go/collectors/go.d.plugin/modules/snmp/testdata/config.yaml
+3
@@ -1,6 +1,9 @@
1
update_every: 123
2
hostname: "ok"
3
community: "ok"
4
+network_interface_filter:
5
+ by_name: "ok"
6
+ by_type: "ok"
7
user:
8
name: "ok"
9
level: "ok"