Skip to content

Commit

Permalink
feat: Optimize locking for SNMP MIBs loading. (influxdata#10206)
Browse files Browse the repository at this point in the history
  • Loading branch information
srebhan authored Dec 7, 2021
1 parent d4475b7 commit 2d420fb
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 10 deletions.
48 changes: 38 additions & 10 deletions internal/snmp/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,43 @@ import (
// or gosmi will fail without saying why
var m sync.Mutex
var once sync.Once
var cache = make(map[string]bool)

func LoadMibsFromPath(paths []string, log telegraf.Logger) error {
func appendPath(path string) {
m.Lock()
defer m.Unlock()

gosmi.AppendPath(path)
}

func loadModule(path string) error {
m.Lock()
defer m.Unlock()

_, err := gosmi.LoadModule(path)
return err
}

func ClearCache() {
cache = make(map[string]bool)
}

func LoadMibsFromPath(paths []string, log telegraf.Logger) error {
once.Do(gosmi.Init)
var folders []string

for _, mibPath := range paths {
gosmi.AppendPath(mibPath)
folders := []string{}

// Check if we loaded that path already and skip it if so
m.Lock()
cached := cache[mibPath]
cache[mibPath] = true
m.Unlock()
if cached {
continue
}

appendPath(mibPath)
folders = append(folders, mibPath)
err := filepath.Walk(mibPath, func(path string, info os.FileInfo, err error) error {
// symlinks are files so we need to double check if any of them are folders
Expand All @@ -38,26 +67,25 @@ func LoadMibsFromPath(paths []string, log telegraf.Logger) error {
return nil
})
if err != nil {
return fmt.Errorf("Filepath could not be walked %v", err)
return fmt.Errorf("Filepath could not be walked: %v", err)
}

for _, folder := range folders {
err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
// checks if file or directory
if info.IsDir() {
gosmi.AppendPath(path)
appendPath(path)
} else if info.Mode()&os.ModeSymlink == 0 {
_, err := gosmi.LoadModule(info.Name())
if err != nil {
log.Warnf("Module could not be loaded %v", err)
if err := loadModule(info.Name()); err != nil {
log.Warn(err)
}
}
return nil
})
if err != nil {
return fmt.Errorf("Filepath could not be walked %v", err)
return fmt.Errorf("Filepath could not be walked: %v", err)
}
}
folders = []string{}
}
return nil
}
Expand Down
9 changes: 9 additions & 0 deletions plugins/inputs/snmp/snmp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1295,3 +1295,12 @@ func TestTableJoinNoIndexAsTag_walk(t *testing.T) {
require.Contains(t, tb.Rows, rtr2)
require.Contains(t, tb.Rows, rtr3)
}

func BenchmarkMibLoading(b *testing.B) {
log := testutil.Logger{}
path := []string{"testdata"}
for i := 0; i < b.N; i++ {
err := snmp.LoadMibsFromPath(path, log)
require.NoError(b, err)
}
}

0 comments on commit 2d420fb

Please sign in to comment.