go.d snmp: adjust max repetitions automatically (#18274)
Ilya Mashchenko committed
Aug 7, 2024 at 20:29 UTC
0709a8f1718cd3a8f89c55f548a816340679efd4
3 files changed
+62
-5
src/go/plugin/go.d/modules/snmp/collect.go
+53
-5
@@ -82,6 +82,26 @@ func (s *SNMP) collectSysUptime(mx map[string]int64) error {
82
}
83
84
func (s *SNMP) collectNetworkInterfaces(mx map[string]int64) error {
85
+ if s.checkMaxReps {
86
+ ok, err := s.adjustMaxRepetitions()
87
+ if err != nil {
88
+ return err
89
+ }
90
+
91
+ s.checkMaxReps = false
92
+
93
+ if !ok {
94
+ s.collectIfMib = false
95
+
96
+ if len(s.oids) == 0 {
97
+ return errors.New("no IF-MIB data returned")
98
+ }
99
+
100
+ s.Warning("no IF-MIB data returned")
101
+ return nil
102
+ }
103
+ }
104
+
105
ifMibTable, err := s.walkAll(rootOidIfMibIfTable)
106
if err != nil {
107
return err
@@ -93,11 +113,7 @@ func (s *SNMP) collectNetworkInterfaces(mx map[string]int64) error {
113
}
114
115
if len(ifMibTable) == 0 && len(ifMibXTable) == 0 {
96
- if len(s.oids) == 0 {
97
- return errors.New("no IF-MIB data returned, try decreasing 'max_repetitions'")
98
- }
99
-
100
- s.Warningf("no IF-MIB data returned, try decreasing 'max_repetitions' (current: %d)", s.snmpClient.MaxRepetitions())
116
+ s.Warning("no IF-MIB data returned")
117
s.collectIfMib = false
118
return nil
119
}
@@ -264,6 +280,38 @@ func (s *SNMP) collectNetworkInterfaces(mx map[string]int64) error {
280
return nil
281
}
282
283
+func (s *SNMP) adjustMaxRepetitions() (bool, error) {
284
+ orig := s.Config.Options.MaxRepetitions
285
+ maxReps := s.Config.Options.MaxRepetitions
286
+
287
+ for {
288
+ v, err := s.walkAll(oidIfIndex)
289
+ if err != nil {
290
+ return false, err
291
+ }
292
+
293
+ if len(v) > 0 {
294
+ if orig != maxReps {
295
+ s.Infof("changed 'max_repetitions' %d => %d", orig, maxReps)
296
+ }
297
+ return true, nil
298
+ }
299
+
300
+ if maxReps > 5 {
301
+ maxReps = max(5, maxReps-5)
302
+ } else {
303
+ maxReps--
304
+ }
305
+
306
+ if maxReps <= 0 {
307
+ return false, nil
308
+ }
309
+
310
+ s.Debugf("no IF-MIB data returned, trying to decrese 'max_repetitions' to %d", maxReps)
311
+ s.snmpClient.SetMaxRepetitions(uint32(maxReps))
312
+ }
313
+}
314
+
315
func (s *SNMP) walkAll(rootOid string) ([]gosnmp.SnmpPDU, error) {
316
if s.snmpClient.Version() == gosnmp.Version1 {
317
return s.snmpClient.WalkAll(rootOid)
src/go/plugin/go.d/modules/snmp/snmp.go
+3
@@ -5,6 +5,7 @@ package snmp
5
import (
6
_ "embed"
7
"errors"
8
+
9
"github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module"
10
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/matcher"
11
@@ -46,6 +47,7 @@ func New() *SNMP {
47
48
newSnmpClient: gosnmp.NewHandler,
49
50
+ checkMaxReps: true,
51
collectIfMib: true,
52
netInterfaces: make(map[string]*netInterface),
53
}
@@ -63,6 +65,7 @@ type SNMP struct {
65
netIfaceFilterByName matcher.Matcher
66
netIfaceFilterByType matcher.Matcher
67
68
+ checkMaxReps bool
69
collectIfMib bool
70
netInterfaces map[string]*netInterface
71
sysName string
src/go/plugin/go.d/modules/snmp/snmp_test.go
+6
@@ -594,6 +594,12 @@ func setMockClientSysExpect(m *snmpmock.MockHandler) {
594
}
595
596
func setMockClientIfMibExpect(m *snmpmock.MockHandler) {
597
+ m.EXPECT().WalkAll(oidIfIndex).Return([]gosnmp.SnmpPDU{
598
+ {Name: oidIfIndex + ".1", Value: 1, Type: gosnmp.Integer},
599
+ {Name: oidIfIndex + ".2", Value: 2, Type: gosnmp.Integer},
600
+ {Name: oidIfIndex + ".17", Value: 17, Type: gosnmp.Integer},
601
+ {Name: oidIfIndex + ".18", Value: 18, Type: gosnmp.Integer},
602
+ }, nil).MinTimes(1)
603
m.EXPECT().WalkAll(rootOidIfMibIfTable).Return([]gosnmp.SnmpPDU{
604
{Name: oidIfIndex + ".1", Value: 1, Type: gosnmp.Integer},
605
{Name: oidIfIndex + ".2", Value: 2, Type: gosnmp.Integer},