Skip to content

Commit 2d420fb

Browse files
authored
feat: Optimize locking for SNMP MIBs loading. (#10206)
1 parent d4475b7 commit 2d420fb

2 files changed

Lines changed: 47 additions & 10 deletions

File tree

internal/snmp/translate.go

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,43 @@ import (
1616
// or gosmi will fail without saying why
1717
var m sync.Mutex
1818
var once sync.Once
19+
var cache = make(map[string]bool)
1920

20-
func LoadMibsFromPath(paths []string, log telegraf.Logger) error {
21+
func appendPath(path string) {
22+
m.Lock()
23+
defer m.Unlock()
24+
25+
gosmi.AppendPath(path)
26+
}
27+
28+
func loadModule(path string) error {
2129
m.Lock()
2230
defer m.Unlock()
31+
32+
_, err := gosmi.LoadModule(path)
33+
return err
34+
}
35+
36+
func ClearCache() {
37+
cache = make(map[string]bool)
38+
}
39+
40+
func LoadMibsFromPath(paths []string, log telegraf.Logger) error {
2341
once.Do(gosmi.Init)
24-
var folders []string
42+
2543
for _, mibPath := range paths {
26-
gosmi.AppendPath(mibPath)
44+
folders := []string{}
45+
46+
// Check if we loaded that path already and skip it if so
47+
m.Lock()
48+
cached := cache[mibPath]
49+
cache[mibPath] = true
50+
m.Unlock()
51+
if cached {
52+
continue
53+
}
54+
55+
appendPath(mibPath)
2756
folders = append(folders, mibPath)
2857
err := filepath.Walk(mibPath, func(path string, info os.FileInfo, err error) error {
2958
// symlinks are files so we need to double check if any of them are folders
@@ -38,26 +67,25 @@ func LoadMibsFromPath(paths []string, log telegraf.Logger) error {
3867
return nil
3968
})
4069
if err != nil {
41-
return fmt.Errorf("Filepath could not be walked %v", err)
70+
return fmt.Errorf("Filepath could not be walked: %v", err)
4271
}
72+
4373
for _, folder := range folders {
4474
err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
4575
// checks if file or directory
4676
if info.IsDir() {
47-
gosmi.AppendPath(path)
77+
appendPath(path)
4878
} else if info.Mode()&os.ModeSymlink == 0 {
49-
_, err := gosmi.LoadModule(info.Name())
50-
if err != nil {
51-
log.Warnf("Module could not be loaded %v", err)
79+
if err := loadModule(info.Name()); err != nil {
80+
log.Warn(err)
5281
}
5382
}
5483
return nil
5584
})
5685
if err != nil {
57-
return fmt.Errorf("Filepath could not be walked %v", err)
86+
return fmt.Errorf("Filepath could not be walked: %v", err)
5887
}
5988
}
60-
folders = []string{}
6189
}
6290
return nil
6391
}

plugins/inputs/snmp/snmp_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,3 +1295,12 @@ func TestTableJoinNoIndexAsTag_walk(t *testing.T) {
12951295
require.Contains(t, tb.Rows, rtr2)
12961296
require.Contains(t, tb.Rows, rtr3)
12971297
}
1298+
1299+
func BenchmarkMibLoading(b *testing.B) {
1300+
log := testutil.Logger{}
1301+
path := []string{"testdata"}
1302+
for i := 0; i < b.N; i++ {
1303+
err := snmp.LoadMibsFromPath(path, log)
1304+
require.NoError(b, err)
1305+
}
1306+
}

0 commit comments

Comments
 (0)