diff options
Diffstat (limited to 'src/go/plugin/go.d/agent/setup.go')
-rw-r--r-- | src/go/plugin/go.d/agent/setup.go | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/go/plugin/go.d/agent/setup.go b/src/go/plugin/go.d/agent/setup.go new file mode 100644 index 000000000..12da59380 --- /dev/null +++ b/src/go/plugin/go.d/agent/setup.go @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package agent + +import ( + "io" + "os" + "strings" + + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/confgroup" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/discovery" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/discovery/dummy" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/discovery/file" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/discovery/sd" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/hostinfo" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/vnodes" + + "gopkg.in/yaml.v2" +) + +func (a *Agent) loadPluginConfig() config { + a.Info("loading config file") + + if len(a.ConfDir) == 0 { + a.Info("config dir not provided, will use defaults") + return defaultConfig() + } + + cfgPath := a.Name + ".conf" + a.Debugf("looking for '%s' in %v", cfgPath, a.ConfDir) + + path, err := a.ConfDir.Find(cfgPath) + if err != nil || path == "" { + a.Warning("couldn't find config, will use defaults") + return defaultConfig() + } + a.Infof("found '%s", path) + + cfg := defaultConfig() + if err := loadYAML(&cfg, path); err != nil { + a.Warningf("couldn't load config '%s': %v, will use defaults", path, err) + return defaultConfig() + } + a.Info("config successfully loaded") + return cfg +} + +func (a *Agent) loadEnabledModules(cfg config) module.Registry { + a.Info("loading modules") + + all := a.RunModule == "all" || a.RunModule == "" + enabled := module.Registry{} + + for name, creator := range a.ModuleRegistry { + if !all && a.RunModule != name { + continue + } + if all { + // Known issue: go.d/logind high CPU usage on Alma Linux8 (https://github.com/netdata/netdata/issues/15930) + if !cfg.isExplicitlyEnabled(name) && (creator.Disabled || name == "logind" && hostinfo.SystemdVersion == 239) { + a.Infof("'%s' module disabled by default, should be explicitly enabled in the config", name) + continue + } + if !cfg.isImplicitlyEnabled(name) { + a.Infof("'%s' module disabled in the config file", name) + continue + } + } + enabled[name] = creator + } + + a.Infof("enabled/registered modules: %d/%d", len(enabled), len(a.ModuleRegistry)) + + return enabled +} + +func (a *Agent) buildDiscoveryConf(enabled module.Registry) discovery.Config { + a.Info("building discovery config") + + reg := confgroup.Registry{} + for name, creator := range enabled { + reg.Register(name, confgroup.Default{ + MinUpdateEvery: a.MinUpdateEvery, + UpdateEvery: creator.UpdateEvery, + AutoDetectionRetry: creator.AutoDetectionRetry, + Priority: creator.Priority, + }) + } + + var readPaths, dummyPaths []string + + if len(a.ModulesConfDir) == 0 { + if hostinfo.IsInsideK8sCluster() { + return discovery.Config{Registry: reg} + } + a.Info("modules conf dir not provided, will use default config for all enabled modules") + for name := range enabled { + dummyPaths = append(dummyPaths, name) + } + return discovery.Config{ + Registry: reg, + Dummy: dummy.Config{Names: dummyPaths}, + } + } + + for name := range enabled { + // TODO: properly handle module renaming + // We need to announce this change in Netdata v1.39.0 release notes and then remove this workaround. + // This is just a quick fix for wmi=>windows. We need to prefer user wmi.conf over windows.conf + // 2nd part of this fix is in /agent/job/discovery/file/parse.go parseStaticFormat() + if name == "windows" { + cfgName := "wmi.conf" + a.Debugf("looking for '%s' in %v", cfgName, a.ModulesConfDir) + + path, err := a.ModulesConfDir.Find(cfgName) + + if err == nil && strings.Contains(path, "etc/netdata") { + a.Infof("found '%s", path) + readPaths = append(readPaths, path) + continue + } + } + + cfgName := name + ".conf" + a.Debugf("looking for '%s' in %v", cfgName, a.ModulesConfDir) + + path, err := a.ModulesConfDir.Find(cfgName) + if hostinfo.IsInsideK8sCluster() { + if err != nil { + a.Infof("not found '%s', won't use default (reading stock configs is disabled in k8s)", cfgName) + continue + } else if isStockConfig(path) { + a.Infof("found '%s', but won't load it (reading stock configs is disabled in k8s)", cfgName) + continue + } + } + if err != nil { + a.Infof("couldn't find '%s' module config, will use default config", name) + dummyPaths = append(dummyPaths, name) + } else { + a.Debugf("found '%s", path) + readPaths = append(readPaths, path) + } + } + + a.Infof("dummy/read/watch paths: %d/%d/%d", len(dummyPaths), len(readPaths), len(a.ModulesSDConfPath)) + + return discovery.Config{ + Registry: reg, + File: file.Config{ + Read: readPaths, + Watch: a.ModulesSDConfPath, + }, + Dummy: dummy.Config{ + Names: dummyPaths, + }, + SD: sd.Config{ + ConfDir: a.ModulesConfSDDir, + }, + } +} + +func (a *Agent) setupVnodeRegistry() *vnodes.Vnodes { + a.Debugf("looking for 'vnodes/' in %v", a.VnodesConfDir) + + if len(a.VnodesConfDir) == 0 { + return nil + } + + dirPath, err := a.VnodesConfDir.Find("vnodes/") + if err != nil || dirPath == "" { + return nil + } + + reg := vnodes.New(dirPath) + a.Infof("found '%s' (%d vhosts)", dirPath, reg.Len()) + + return reg +} + +func loadYAML(conf any, path string) error { + f, err := os.Open(path) + if err != nil { + return err + } + defer func() { _ = f.Close() }() + + if err = yaml.NewDecoder(f).Decode(conf); err != nil { + if err == io.EOF { + return nil + } + return err + } + return nil +} + +var ( + envNDStockConfigDir = os.Getenv("NETDATA_STOCK_CONFIG_DIR") +) + +func isStockConfig(path string) bool { + if envNDStockConfigDir == "" { + return false + } + return strings.HasPrefix(path, envNDStockConfigDir) +} |