diff --git a/configmap/loglevel_change_test.go b/configmap/loglevel_change_test.go index 4e8a658..366f7ea 100644 --- a/configmap/loglevel_change_test.go +++ b/configmap/loglevel_change_test.go @@ -36,13 +36,20 @@ func TestDynamicLogLevel(t *testing.T) { if err = os.Mkdir(pDir, 0o755); err != nil { t.Fatalf("unable to make %v: %v", pDir, err) } + fName := path.Join(pDir, "extra_flag") + if err = os.WriteFile(fName, []byte("ignored"), 0o644); err != nil { + t.Fatalf("unable to write %v: %v", fName, err) + } var u *configmap.Updater log.SetLogLevel(log.Debug) if u, err = configmap.Setup(flag.CommandLine, pDir); err != nil { t.Fatalf("unexpected error setting up config watch: %v", err) } defer u.Stop() - fName := path.Join(pDir, "loglevel") + if u.Warnings() != 1 { + t.Errorf("Expected exactly 1 warning (extra flag), got %d", u.Warnings()) + } + fName = path.Join(pDir, "loglevel") // Test also the new normalization (space trimmimg and captitalization) if err = os.WriteFile(fName, []byte(" InFO\n\n"), 0o644); err != nil { t.Fatalf("unable to write %v: %v", fName, err) diff --git a/configmap/updater.go b/configmap/updater.go index 28011d9..76cf152 100644 --- a/configmap/updater.go +++ b/configmap/updater.go @@ -12,6 +12,7 @@ import ( "os" "path" "strings" + "sync/atomic" "fortio.org/dflag" "fortio.org/dflag/dynloglevel" @@ -38,6 +39,7 @@ type Updater struct { watcher *fsnotify.Watcher flagSet *flag.FlagSet done chan bool + warnings atomic.Int32 // Count of unknown flags that have been logged (increases at each iteration). } // Setup is a combination/shortcut for New+Initialize+Start. @@ -124,9 +126,13 @@ func (u *Updater) readAll(dynamicOnly bool) error { continue } fullPath := path.Join(u.dirPath, f.Name()) + log.S(log.Debug, "checking flag", log.Str("flag", f.Name()), log.Str("path", fullPath)) if err := u.readFlagFile(fullPath, dynamicOnly); err != nil { if errors.Is(err, errFlagNotDynamic) && dynamicOnly { // ignore + } else if errors.Is(err, errFlagNotFound) { + log.S(log.Warning, "config map for unknown flag", log.Str("flag", f.Name()), log.Str("path", fullPath)) + u.warnings.Add(1) } else { errorStrings = append(errorStrings, fmt.Sprintf("flag %v: %v", f.Name(), err.Error())) } @@ -139,6 +145,11 @@ func (u *Updater) readAll(dynamicOnly bool) error { return nil } +// Return the warnings count. +func (u *Updater) Warnings() int { + return int(u.warnings.Load()) +} + func (u *Updater) readFlagFile(fullPath string, dynamicOnly bool) error { flagName := path.Base(fullPath) flag := u.flagSet.Lookup(flagName) diff --git a/go.mod b/go.mod index dc96a2d..8f8f9c8 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( fortio.org/log v1.11.0 fortio.org/sets v1.0.3 github.com/fsnotify/fsnotify v1.6.0 - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 + golang.org/x/exp v0.0.0-20231006140011-7918f672742d ) -require golang.org/x/sys v0.4.0 // indirect +require golang.org/x/sys v0.13.0 // indirect diff --git a/go.sum b/go.sum index 925d6a6..91a8259 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ fortio.org/sets v1.0.3 h1:HzewdGjH69YmyW06yzplL35lGr+X4OcqQt0qS6jbaO4= fortio.org/sets v1.0.3/go.mod h1:QZVj0r6KP/ZD9ebySW9SgxVNy/NjghUfyHW9NN+WU+4= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=