diff --git a/internal/kloglevel/kloglevel.go b/internal/kloglevel/kloglevel.go new file mode 100644 index 000000000..3a3e91ea8 --- /dev/null +++ b/internal/kloglevel/kloglevel.go @@ -0,0 +1,77 @@ +/* + * Copyright 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kloglevel + +import ( + "flag" + "fmt" + + "k8s.io/klog/v2" +) + +func Get() (klog.Level, error) { + level := getKLogLevel() + if level == nil { + return 0, fmt.Errorf("cannot get the log level programmatically") + } + return *level, nil +} + +func Set(v klog.Level) error { + verbosity := fmt.Sprintf("%v", v) + + if level := getKLogLevel(); level != nil { + return level.Set(verbosity) + } + + // if modifying the flag value (which is recommended by klog) fails, then fallback to modifying + // the internal state of klog using the empty new level. + var newLevel klog.Level + if err := newLevel.Set(verbosity); err != nil { + return fmt.Errorf("failed set klog.logging.verbosity %s: %v", verbosity, err) + } + + return nil +} + +func getKLogLevel() *klog.Level { + var level *klog.Level + + // First, if the '-v' was specified in command line, attempt to acquire the level pointer from it. + if f := flag.CommandLine.Lookup("v"); f != nil { + if flagValue, ok := f.Value.(*klog.Level); ok { + level = flagValue + } + } + + if level != nil { + return level + } + + // Second, if the '-v' was not set but is still present in flags defined for the command, attempt to acquire it + // by visiting all flags. + flag.VisitAll(func(f *flag.Flag) { + if level != nil { + return + } + if levelFlag, ok := f.Value.(*klog.Level); ok { + level = levelFlag + } + }) + + return level +} diff --git a/main.go b/main.go index 6ae67f978..ba3520f8b 100644 --- a/main.go +++ b/main.go @@ -56,6 +56,7 @@ import ( nropv1alpha1 "github.com/openshift-kni/numaresources-operator/api/numaresourcesoperator/v1alpha1" "github.com/openshift-kni/numaresources-operator/controllers" "github.com/openshift-kni/numaresources-operator/internal/api/features" + intkloglevel "github.com/openshift-kni/numaresources-operator/internal/kloglevel" "github.com/openshift-kni/numaresources-operator/pkg/hash" "github.com/openshift-kni/numaresources-operator/pkg/images" "github.com/openshift-kni/numaresources-operator/pkg/numaresourcesscheduler/controlplane" @@ -179,8 +180,13 @@ func main() { os.Exit(manageIntrospection()) } - klogV := getKlogLevel() - config := textlogger.NewConfig(textlogger.Verbosity(klogV)) + klogV, err := intkloglevel.Get() + if err != nil { + klog.V(1).ErrorS(err, "setting up the logger") + os.Exit(1) + } + + config := textlogger.NewConfig(textlogger.Verbosity(int(klogV))) ctrl.SetLogger(textlogger.NewLogger(config)) klog.InfoS("starting", "program", version.ProgramName(), "version", version.Get(), "gitcommit", version.GetGitCommit(), "golang", runtime.Version(), "vl", klogV, "auxv", config.Verbosity().String()) @@ -467,15 +473,3 @@ func webhookTLSOpts(enableHTTP2 bool) []func(config *tls.Config) { return []func(config *tls.Config){disableHTTP2} } - -// getKlogLevel reconstructs the klog verb level, because -// the klog package doesn't give a clean easy way to access -// the setting, so we have to jumps through some hoops. -func getKlogLevel() int { - for j := 1; j < 15; j++ { - if !klog.V(klog.Level(j)).Enabled() { - return j - 1 - } - } - return 0 -} diff --git a/tools/nrtcacheck/nrtcacheck.go b/tools/nrtcacheck/nrtcacheck.go index c0d85d31e..6af2bba44 100644 --- a/tools/nrtcacheck/nrtcacheck.go +++ b/tools/nrtcacheck/nrtcacheck.go @@ -48,6 +48,7 @@ import ( rteupdate "github.com/openshift-kni/numaresources-operator/pkg/objectupdate/rte" "github.com/openshift-kni/numaresources-operator/pkg/version" + intkloglevel "github.com/openshift-kni/numaresources-operator/internal/kloglevel" "github.com/openshift-kni/numaresources-operator/internal/podlist" "github.com/openshift-kni/numaresources-operator/internal/schedcache" ) @@ -83,7 +84,13 @@ func main() { os.Exit(0) } - logCfg := textlogger.NewConfig(textlogger.Verbosity(getKlogLevel())) + lev, err := intkloglevel.Get() + if err != nil { + klog.V(1).ErrorS(err, "setting up the logger") + os.Exit(1) + } + + logCfg := textlogger.NewConfig(textlogger.Verbosity(int(lev))) cli, err := NewClientWithScheme(scheme) if err != nil { @@ -254,15 +261,3 @@ func NewClientWithScheme(scheme *k8sruntime.Scheme) (client.Client, error) { } return client.New(cfg, client.Options{Scheme: scheme}) } - -// getKlogLevel reconstructs the klog verb level, because -// the klog package doesn't give a clean easy way to access -// the setting, so we have to jumps through some hoops. -func getKlogLevel() int { - for j := 1; j < 15; j++ { - if !klog.V(klog.Level(j)).Enabled() { - return j - 1 - } - } - return 0 -}