feat: Optimize locking for SNMP MIBs loading. (#10206)

This commit is contained in:
Sven Rebhan 2021-12-07 23:05:33 +01:00 committed by GitHub
parent d4475b7d08
commit 2d420fbd35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 10 deletions

View File

@ -16,14 +16,43 @@ import (
// or gosmi will fail without saying why // or gosmi will fail without saying why
var m sync.Mutex var m sync.Mutex
var once sync.Once var once sync.Once
var cache = make(map[string]bool)
func LoadMibsFromPath(paths []string, log telegraf.Logger) error { func appendPath(path string) {
m.Lock() m.Lock()
defer m.Unlock() 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) once.Do(gosmi.Init)
var folders []string
for _, mibPath := range paths { 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) folders = append(folders, mibPath)
err := filepath.Walk(mibPath, func(path string, info os.FileInfo, err error) error { 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 // 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 {
return nil return nil
}) })
if err != 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 { for _, folder := range folders {
err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error { err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
// checks if file or directory // checks if file or directory
if info.IsDir() { if info.IsDir() {
gosmi.AppendPath(path) appendPath(path)
} else if info.Mode()&os.ModeSymlink == 0 { } else if info.Mode()&os.ModeSymlink == 0 {
_, err := gosmi.LoadModule(info.Name()) if err := loadModule(info.Name()); err != nil {
if err != nil { log.Warn(err)
log.Warnf("Module could not be loaded %v", err)
} }
} }
return nil return nil
}) })
if err != 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 return nil
} }

View File

@ -1295,3 +1295,12 @@ func TestTableJoinNoIndexAsTag_walk(t *testing.T) {
require.Contains(t, tb.Rows, rtr2) require.Contains(t, tb.Rows, rtr2)
require.Contains(t, tb.Rows, rtr3) 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)
}
}