如何结合使用 Cobra 和 Klog?

huangapple go评论76阅读模式
英文:

How to combine cobra and klog

问题

我有一个项目需要使用cobraklog来生成可执行文件并打印日志并保存。

首先,我测试了使用以下的klog可以同时将日志输出到终端和文件

package main
import (
	"flag"
	"k8s.io/klog"
)
func init() {
	var fs flag.FlagSet
	klog.InitFlags(&fs)
	fs.Set("logtostderr", "false")
	fs.Set("log_file_max_size", "100")
	fs.Set("log_file", "/home/test/workspace/klogfile/test.log")
	fs.Set("alsologtostderr", "true")
}
func main() {
	defer klog.Flush()
	klog.Info("info")
	klog.Warning("warning")
	klog.Error("error")
}

文件/home/test/workspace/klogfile/test.log的内容如下:

Log file created at: 2023/04/06 16:46:07
Running on machine: s52
Binary: Built with gc go1.16.12 for linux/amd64
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
I0406 16:46:07.751183   13512 main.go:20] info
W0406 16:46:07.751594   13512 main.go:21] warning
E0406 16:46:07.751629   13512 main.go:22] error

然后我尝试基于k8s风格将其添加到cobra中:

package main
import (
	"flag"
	"github.com/spf13/cobra"
	"k8s.io/klog"
)
var (
	str = "hello world"
)
func NewCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "echo",
		Short: "use klog with cobra",
		Long:  "Use klog together with cobra.",
		Run: func(cmd *cobra.Command, args []string) {
			Run()
		},
	}
	klog.InitFlags(flag.CommandLine)
	cmd.Flags().AddGoFlagSet(flag.CommandLine)
	cmd.Flags().SortFlags = false
	cmd.Flags().StringVar(&str, "str", str, "string to print")
	return cmd
}
func Run() {
	defer klog.Flush()
	klog.Infof("Running, str:%s", str)
}

func main() {
	if err := NewCommand().Execute(); err != nil {
		klog.Fatalf("root cmd execute failed, err=%v", err)
	}
}

我可以通过--help打印出所需的日志选项,但是当我覆盖它们以实现上面示例中的保存到文件时,只有输出被输出到终端而不是文件

# go run main2.go --logtostderr false --log_file_max_size "100" --alsologtostderr true --log_file "/home/test/workspace/klogfile/test2.log"
I0406 16:52:57.479455   15217 cobra_klog.go:34] Running, str:hello world

请问我在哪里缺少必要的代码,如果是的话,请告诉我如何修改,谢谢!

英文:

I have a project that needs to use cobra and klog to generate executable and print logs and keep.

Firstly, I tested that using the following klog can output the log to the terminal and file at the same time.

package main
import (
	"flag"
	"k8s.io/klog"
)
func init() {
	var fs flag.FlagSet
	klog.InitFlags(&fs)
	fs.Set("logtostderr", "false")
	fs.Set("log_file_max_size", "100")
	fs.Set("log_file", "/home/test/workspace/klogfile/test.log")
	fs.Set("alsologtostderr", "true")
}
func main() {
	defer klog.Flush()
	klog.Info("info")
	klog.Warning("warning")
	klog.Error("error")
}

The content of file /home/test/workspace/klogfile/test.log is as follow

Log file created at: 2023/04/06 16:46:07
Running on machine: s52
Binary: Built with gc go1.16.12 for linux/amd64
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
I0406 16:46:07.751183   13512 main.go:20] info
W0406 16:46:07.751594   13512 main.go:21] warning
E0406 16:46:07.751629   13512 main.go:22] error

Then I try to add it to cobra based on k8s style

package main
import (
	"flag"
	"github.com/spf13/cobra"
	"k8s.io/klog"
)
var (
	str = "hello world"
)
func NewCommand() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "echo",
		Short: "use klog with cobra",
		Long:  "Use klog together with cobra.",
		Run: func(cmd *cobra.Command, args []string) {
			Run()
		},
	}
	klog.InitFlags(flag.CommandLine)
	cmd.Flags().AddGoFlagSet(flag.CommandLine)
	cmd.Flags().SortFlags = false
	cmd.Flags().StringVar(&str, "str", str, "string to print")
	return cmd
}
func Run() {
	defer klog.Flush()
	klog.Infof("Running, str:%s", str)
}

func main() {
	if err := NewCommand().Execute(); err != nil {
		klog.Fatalf("root cmd execute failed, err=%v", err)
	}
}

I can print out the required log options through --help, but when I override them to achieve the save to file in the above example, only the output is output to the terminal and not to the file

# go run main2.go --logtostderr false --log_file_max_size "100" --alsologtostderr true --log_file "/home/test/workspace/klogfile/test2.log"
I0406 16:52:57.479455   15217 cobra_klog.go:34] Running, str:hello world

May I ask where I am missing the necessary code, if so, please let me know how to modify it, thank you!

答案1

得分: 1

你的代码没有问题。唯一的问题是你必须使用-flag=false的形式来关闭布尔标志(参见命令行标志语法)。

尝试使用以下命令(将--logtostderr false替换为--logtostderr=false):

go run main2.go --logtostderr=false --log_file_max_size "100" --alsologtostderr=true --log_file "/home/test/workspace/klogfile/test2.log"

顺便说一下,我认为--log_file_max_size "100"可以简化为--log_file_max_size 100

更新:

为了减少klog的暴露标志:

 package main
 
 import (
    "flag"
    "github.com/spf13/cobra"
    "k8s.io/klog"
 )
 
 var (
    str     = "hello world"
+   logFile string
 )
 
 func NewCommand() *cobra.Command {
+   var fs flag.FlagSet
+   klog.InitFlags(&fs)

    cmd := &cobra.Command{
        Use:   "echo",
        Short: "use klog with cobra",
        Long:  "Use klog together with cobra.",
        Run: func(cmd *cobra.Command, args []string) {
+           fs.Set("logtostderr", "false")
+           fs.Set("log_file", logFile)

            Run()
        },
    }
-   klog.InitFlags(flag.CommandLine)
-   cmd.Flags().AddGoFlagSet(flag.CommandLine)
    cmd.Flags().SortFlags = false
    cmd.Flags().StringVar(&str, "str", str, "string to print")
+   cmd.Flags().StringVar(&logFile, "log_file", "", "If non-empty, use this log file")
    return cmd
 }
 func Run() {
    defer klog.Flush()
    klog.Infof("Running, str:%s", str)
 }
 
 func main() {
    if err := NewCommand().Execute(); err != nil {
        klog.Fatalf("root cmd execute failed, err=%v", err)
    }
 }

希望对你有帮助!

英文:

There is nothing wrong in your code. The only issue is that you must use the -flag=false form to turn off a boolean flag (see Command line flag syntax).

Try this command (repalce --logtostderr false with --logtostderr=false):

go run main2.go --logtostderr=false --log_file_max_size "100" --alsologtostderr true --log_file "/home/test/workspace/klogfile/test2.log"

BTW, I think --log_file_max_size "100" could be simplified to --log_file_max_size 100.


Update:

To reduce the exposed flags of klog:

 package main
 
 import (
    "flag"
    "github.com/spf13/cobra"
    "k8s.io/klog"
 )
 
 var (
    str     = "hello world"
+   logFile string
 )
 
 func NewCommand() *cobra.Command {
+   var fs flag.FlagSet
+   klog.InitFlags(&fs)

    cmd := &cobra.Command{
        Use:   "echo",
        Short: "use klog with cobra",
        Long:  "Use klog together with cobra.",
        Run: func(cmd *cobra.Command, args []string) {
+           fs.Set("logtostderr", "false")
+           fs.Set("log_file", logFile)

            Run()
        },
    }
-   klog.InitFlags(flag.CommandLine)
-   cmd.Flags().AddGoFlagSet(flag.CommandLine)
    cmd.Flags().SortFlags = false
    cmd.Flags().StringVar(&str, "str", str, "string to print")
+   cmd.Flags().StringVar(&logFile, "log_file", "", "If non-empty, use this log file")
    return cmd
 }
 func Run() {
    defer klog.Flush()
    klog.Infof("Running, str:%s", str)
 }
 
 func main() {
    if err := NewCommand().Execute(); err != nil {
        klog.Fatalf("root cmd execute failed, err=%v", err)
    }
 }

huangapple
  • 本文由 发表于 2023年4月6日 17:08:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75947754.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定