summaryrefslogtreecommitdiffstats
path: root/src/go/cmd/godplugin/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/go/cmd/godplugin/main.go')
-rw-r--r--src/go/cmd/godplugin/main.go203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/go/cmd/godplugin/main.go b/src/go/cmd/godplugin/main.go
new file mode 100644
index 00000000..cae9fa1b
--- /dev/null
+++ b/src/go/cmd/godplugin/main.go
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package main
+
+import (
+ "errors"
+ "fmt"
+ "io/fs"
+ "log/slog"
+ "os"
+ "os/user"
+ "path/filepath"
+ "strings"
+
+ "github.com/netdata/netdata/go/plugins/logger"
+ "github.com/netdata/netdata/go/plugins/pkg/buildinfo"
+ "github.com/netdata/netdata/go/plugins/pkg/executable"
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/agent"
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/cli"
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/multipath"
+
+ "github.com/jessevdk/go-flags"
+ "golang.org/x/net/http/httpproxy"
+
+ _ "github.com/netdata/netdata/go/plugins/plugin/go.d/modules"
+)
+
+var (
+ cygwinBasePath = os.Getenv("NETDATA_CYGWIN_BASE_PATH")
+
+ name = "go.d"
+ userDir = os.Getenv("NETDATA_USER_CONFIG_DIR")
+ stockDir = os.Getenv("NETDATA_STOCK_CONFIG_DIR")
+ varLibDir = os.Getenv("NETDATA_LIB_DIR")
+ lockDir = os.Getenv("NETDATA_LOCK_DIR")
+ watchPath = os.Getenv("NETDATA_PLUGINS_GOD_WATCH_PATH")
+ envLogLevel = os.Getenv("NETDATA_LOG_LEVEL")
+)
+
+func init() {
+ userDir = handleDirOnWin(userDir)
+ stockDir = handleDirOnWin(stockDir)
+ varLibDir = handleDirOnWin(varLibDir)
+ lockDir = handleDirOnWin(lockDir)
+ watchPath = handleDirOnWin(watchPath)
+}
+
+func confDir(opts *cli.Option) multipath.MultiPath {
+ if len(opts.ConfDir) > 0 {
+ return opts.ConfDir
+ }
+
+ if userDir != "" || stockDir != "" {
+ return multipath.New(userDir, stockDir)
+ }
+
+ var dirs []string
+
+ dirs = append(dirs, filepath.Join(executable.Directory, "/../../../../etc/netdata"))
+
+ for _, dir := range []string{
+ handleDirOnWin("/etc/netdata"),
+ handleDirOnWin("/opt/netdata/etc/netdata"),
+ } {
+ if isDirExists(dir) {
+ dirs = append(dirs, dir)
+ break
+ }
+ }
+
+ dirs = append(dirs, filepath.Join(executable.Directory, "/../../../../usr/lib/netdata/conf.d"))
+
+ for _, dir := range []string{
+ handleDirOnWin("/usr/lib/netdata/conf.d"),
+ handleDirOnWin("/opt/netdata/usr/lib/netdata/conf.d"),
+ } {
+ if isDirExists(dir) {
+ dirs = append(dirs, dir)
+ break
+ }
+ }
+
+ return multipath.New(dirs...)
+}
+
+func modulesConfDir(opts *cli.Option) (mpath multipath.MultiPath) {
+ if len(opts.ConfDir) > 0 {
+ return opts.ConfDir
+ }
+
+ dirs := confDir(opts)
+ for _, dir := range dirs {
+ mpath = append(mpath, filepath.Join(dir, name))
+ }
+
+ return multipath.New(mpath...)
+}
+
+func modulesConfSDDir(confDir multipath.MultiPath) (mpath multipath.MultiPath) {
+ for _, v := range confDir {
+ mpath = append(mpath, filepath.Join(v, "sd"))
+ }
+ return mpath
+}
+
+func watchPaths(opts *cli.Option) []string {
+ if watchPath == "" {
+ return opts.WatchPath
+ }
+ return append(opts.WatchPath, watchPath)
+}
+
+func stateFile() string {
+ if varLibDir == "" {
+ return ""
+ }
+ return filepath.Join(varLibDir, "god-jobs-statuses.json")
+}
+
+func init() {
+ // https://github.com/netdata/netdata/issues/8949#issuecomment-638294959
+ if v := os.Getenv("TZ"); strings.HasPrefix(v, ":") {
+ _ = os.Unsetenv("TZ")
+ }
+}
+
+func main() {
+ opts := parseCLI()
+
+ if opts.Version {
+ fmt.Printf("go.d.plugin, version: %s\n", buildinfo.Version)
+ return
+ }
+
+ if envLogLevel != "" {
+ logger.Level.SetByName(envLogLevel)
+ }
+
+ if opts.Debug {
+ logger.Level.Set(slog.LevelDebug)
+ }
+
+ dir := modulesConfDir(opts)
+
+ a := agent.New(agent.Config{
+ Name: name,
+ ConfDir: confDir(opts),
+ ModulesConfDir: dir,
+ ModulesConfSDDir: modulesConfSDDir(dir),
+ ModulesConfWatchPath: watchPaths(opts),
+ VnodesConfDir: confDir(opts),
+ StateFile: stateFile(),
+ LockDir: lockDir,
+ RunModule: opts.Module,
+ MinUpdateEvery: opts.UpdateEvery,
+ })
+
+ a.Debugf("plugin: name=%s, version=%s", a.Name, buildinfo.Version)
+ if u, err := user.Current(); err == nil {
+ a.Debugf("current user: name=%s, uid=%s", u.Username, u.Uid)
+ }
+
+ cfg := httpproxy.FromEnvironment()
+ a.Infof("env HTTP_PROXY '%s', HTTPS_PROXY '%s'", cfg.HTTPProxy, cfg.HTTPSProxy)
+
+ a.Run()
+}
+
+func parseCLI() *cli.Option {
+ opt, err := cli.Parse(os.Args)
+ if err != nil {
+ var flagsErr *flags.Error
+ if errors.As(err, &flagsErr) && errors.Is(flagsErr.Type, flags.ErrHelp) {
+ os.Exit(0)
+ } else {
+ os.Exit(1)
+ }
+ }
+ return opt
+}
+
+func isDirExists(dir string) bool {
+ fi, err := os.Stat(dir)
+ if err == nil {
+ return fi.Mode().IsDir()
+ }
+ return !errors.Is(err, fs.ErrNotExist)
+}
+
+func handleDirOnWin(path string) string {
+ base := cygwinBasePath
+
+ // TODO: temp workaround for debug mode
+ if base == "" && strings.HasPrefix(executable.Directory, "C:\\msys64") {
+ base = "C:\\msys64"
+ }
+
+ if base == "" || !strings.HasPrefix(path, "/") {
+ return path
+ }
+
+ return filepath.Join(base, path)
+}