feat: Optimize locking for SNMP MIBs loading. (#10206)
This commit is contained in:
parent
d4475b7d08
commit
2d420fbd35
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue