If you have been programming with golang, you’ve probably heard of cobra. I use it extensively at work and also in my personal projects.
Recently though, I’ve been using glog more and more. And I quite like it. The thing is, it has a couple of flag definitions in its init()
function using golang’s builtin flag
library. And I wanted to include those flags into cobra’s flag definitions. This is how I did it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
goflag "flag" | |
"github.com/golang/glog" | |
"github.com/spf13/cobra" | |
flag "github.com/spf13/pflag" | |
) | |
var ( | |
rootCmd = &cobra.Command{ | |
Long: "Use glog with cobra.", | |
Run: echo, | |
} | |
str string | |
) | |
func init() { | |
rootCmd.PersistentFlags().StringVar(&str, "echo", "hello", "echo string") | |
flag.CommandLine.AddGoFlagSet(goflag.CommandLine) | |
} | |
func echo(cmd *cobra.Command, args []string) { | |
goflag.Parse() | |
glog.Info("echo (info): ", str) | |
glog.Warning("echo (warn): ", str) | |
glog.Error("echo (error): ", str) | |
} | |
func main() { | |
err := rootCmd.Execute() | |
if err != nil { | |
glog.Error(err) | |
} | |
} |
Generated help information will now look something like this.
# run the help command
$ ./cobraglog -h
Use glog with cobra.
Usage:
[flags]
Flags:
--alsologtostderr log to standard error as well as files
--echo string echo string (default "hello")
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--logtostderr log to standard error instead of files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
-v, --v Level log level for V logs
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
-h, --help help for this command
Note that our cobra-defined flag --echo
is also there. The rest are defined by glog internally. Finally, run the application.
# run the binary, providing the logtostderr flag defined by glog
$ ./cobraglog --logtostderr
I1129 13:49:34.166660 2138 main.go:28] echo (info): hello
W1129 13:49:34.166718 2138 main.go:29] echo (warn): hello
E1129 13:49:34.166722 2138 main.go:30] echo (error): hello
Here’s another example using subcommands.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
goflag "flag" | |
"github.com/golang/glog" | |
"github.com/spf13/cobra" | |
flag "github.com/spf13/pflag" | |
) | |
var ( | |
rootCmd = &cobra.Command{ | |
Long: "Use glog with cobra.", | |
PersistentPreRun: func(cmd *cobra.Command, args []string) { | |
// For cobra + glog flags. Available to all subcommands. | |
goflag.Parse() | |
}, | |
} | |
s1 string | |
s2 string | |
) | |
func init() { | |
rootCmd.AddCommand( | |
subCmd1(), | |
subCmd2(), | |
) | |
flag.CommandLine.AddGoFlagSet(goflag.CommandLine) | |
} | |
func subCmd1() *cobra.Command { | |
c := &cobra.Command{ | |
Use: "sub1", | |
Short: "test subcmd1", | |
Long: "Test sub command 1.", | |
Run: func(cmd *cobra.Command, args []string) { | |
glog.Infof("hello %v from subCmd1", s1) | |
}, | |
} | |
c.Flags().SortFlags = false | |
c.Flags().StringVar(&s1, "target", "world", "say hello to") | |
return c | |
} | |
func subCmd2() *cobra.Command { | |
c := &cobra.Command{ | |
Use: "sub2", | |
Short: "test subcmd2", | |
Long: "Test sub command 2.", | |
Run: func(cmd *cobra.Command, args []string) { | |
glog.Infof("hello %v from subCmd2", s2) | |
}, | |
} | |
c.Flags().SortFlags = false | |
c.Flags().StringVar(&s2, "target", "parallel world", "say hello to") | |
return c | |
} | |
func main() { | |
err := rootCmd.Execute() | |
if err != nil { | |
glog.Error(err) | |
} | |
} |