From 59480533d3c2df6377d5fd5b41a5997619042ad2 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sat, 17 Feb 2024 13:45:05 +0100 Subject: [PATCH] refactor cli to use cobra. --- app/config/cli.go | 7 ++- cmd/thalos/main.go | 96 ++++++++++++------------------------- cmd/thalos/server.go | 55 +++++++++++++-------- cmd/tools/bench.go | 64 ++++++++++++------------- cmd/tools/flags.go | 37 -------------- cmd/tools/main.go | 62 ++++++++++++++++++------ cmd/tools/mock_publisher.go | 59 +++++++++++------------ cmd/tools/redis-acl.go | 78 +++++++++++------------------- cmd/tools/validate.go | 48 ++++++++++--------- go.mod | 7 ++- go.sum | 12 ++--- 11 files changed, 236 insertions(+), 289 deletions(-) delete mode 100644 cmd/tools/flags.go diff --git a/app/config/cli.go b/app/config/cli.go index 8fa44bc..d5bb6ed 100644 --- a/app/config/cli.go +++ b/app/config/cli.go @@ -3,16 +3,15 @@ package config import ( "path" - "github.com/urfave/cli/v2" + "github.com/spf13/pflag" ) // Read cli flag values into the config -func (cfg *Config) ReadCliFlags(ctx *cli.Context) error { - logFile := ctx.Path("log") +func (cfg *Config) ReadCliFlags(flags *pflag.FlagSet) error { + logFile, _ := flags.GetString("log") if len(logFile) > 0 { cfg.Log.Directory = path.Dir(logFile) cfg.Log.Filename = path.Base(logFile) } - return nil } diff --git a/cmd/thalos/main.go b/cmd/thalos/main.go index 7b749ce..994cdd2 100644 --- a/cmd/thalos/main.go +++ b/cmd/thalos/main.go @@ -1,80 +1,44 @@ package main import ( - "fmt" - "os" - log "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var VersionString string = "dev" -func main() { - cli.AppHelpTemplate = `Usage: {{.HelpName}} [options] +var rootCmd *cobra.Command - {{range .VisibleFlags}}{{.}} - {{end}}` - - cli.HelpFlag = &cli.BoolFlag{ - Name: "help", - Aliases: []string{"h"}, - Usage: "display this help text", - DisableDefaultText: true, - } - - cli.VersionPrinter = func(cCtx *cli.Context) { - fmt.Printf("Version %s\n", VersionString) - } - - cli.VersionFlag = &cli.BoolFlag{ - Name: "version", - Aliases: []string{"v"}, - Usage: "display the version", - DisableDefaultText: true, - } - - app := &cli.App{ - Version: VersionString, - Args: true, - UseShortOptionHandling: true, - HideHelpCommand: true, - Flags: []cli.Flag{ - &cli.PathFlag{ - Name: "config", - Aliases: []string{"c"}, - Value: "./config.yml", - Usage: "Config `file` to read", - TakesFile: true, - }, - &cli.StringFlag{ - Name: "level", - Aliases: []string{"L"}, - Usage: "Log level to use", - Value: "info", - }, - &cli.PathFlag{ - Name: "log", - Aliases: []string{"l"}, - Usage: "Path to log `file`", - TakesFile: true, - }, - &cli.BoolFlag{ - Name: "n", - Usage: "Force the application to take start block from config/api", - DisableDefaultText: true, - }, - &cli.StringFlag{ - Name: "pid", - Aliases: []string{"p"}, - Usage: "`file` to save process id to", - TakesFile: true, - }, +func init() { + rootCmd = &cobra.Command{ + Use: "thalos-server", + FParseErrWhitelist: cobra.FParseErrWhitelist{ + UnknownFlags: true, }, - Action: serverCmd, + Version: VersionString, + Run: serverCmd, } - if err := app.Run(os.Args); err != nil { - log.WithError(err).Fatal("Application error") + rootCmd.SetHelpTemplate( + `{{ .Use | trimTrailingWhitespaces}} v{{.Version}} + +{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}} +`) + rootCmd.SetVersionTemplate(`{{with .Name}}{{printf "%s " .}}{{end}}{{printf "v%s" .Version}}` + "\n") + + flags := pflag.FlagSet{} + flags.StringP("config", "c", "./config.yml", "Config file to read") + flags.StringP("level", "L", "info", "Log level to use") + flags.StringP("log", "l", "", "Path to log file (default: print to stdout/stderr)") + flags.StringP("pid", "p", "", "Where to write process id") + flags.BoolP("no-state-cache", "n", false, "Force the application to take start block from config/api") + + rootCmd.PersistentFlags().AddFlagSet(&flags) +} + +func main() { + if err := rootCmd.Execute(); err != nil { + log.Fatal(err) } } diff --git a/cmd/thalos/server.go b/cmd/thalos/server.go index e348cb9..bae8a48 100644 --- a/cmd/thalos/server.go +++ b/cmd/thalos/server.go @@ -29,7 +29,8 @@ import ( "github.com/nikoksr/notify/service/telegram" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + "github.com/spf13/cobra" + "github.com/spf13/pflag" ) // --------------------------- @@ -222,44 +223,52 @@ func stateSaver(state app.State) error { return cache.Set(ctx, "state", state, 0) } -func ReadConfig(cfg *config.Config, ctx *cli.Context) error { +func ReadConfig(cfg *config.Config, flags *pflag.FlagSet) error { + filename, err := flags.GetString("config") + if err != nil { + return err + } + // Read file first. - if err := cfg.ReadFile(ctx.Path("config")); err != nil { + if err := cfg.ReadFile(filename); err != nil { return err } // Then override any cli flags - if err := cfg.ReadCliFlags(ctx); err != nil { + if err := cfg.ReadCliFlags(flags); err != nil { return err } return nil } -func serverCmd(ctx *cli.Context) error { +func serverCmd(cmd *cobra.Command, args []string) { var err error var chainInfo *eos.InfoResp exit = make(chan bool) - skip_currentblock_cache := ctx.Bool("n") + skip_currentblock_cache, _ := cmd.Flags().GetBool("no-state-cache") // Write PID file - pidFile := ctx.String("pid") - if len(pidFile) > 0 { + pidFile, err := cmd.Flags().GetString("pid") + if err != nil { log.WithField("file", pidFile).Info("Writing pid to file") if err = pid.Save(pidFile); err != nil { - return fmt.Errorf("pid: %s", err) + log.WithError(err).Fatal("Failed to write pid") + return } } // Parse config conf = config.New() - if err = ReadConfig(&conf, ctx); err != nil { - return fmt.Errorf("config: %s", err) + if err = ReadConfig(&conf, cmd.Flags()); err != nil { + log.WithError(err).Fatal("Failed to read config") + return } - lvl, err := log.ParseLevel(ctx.String("level")) + flagLevel, _ := cmd.Flags().GetString("level") + lvl, err := log.ParseLevel(flagLevel) if err == nil { log.WithField("value", lvl).Info("Setting log level") log.SetLevel(lvl) @@ -268,13 +277,17 @@ func serverCmd(ctx *cli.Context) error { } if len(conf.Log.Filename) > 0 { + fmt.Println(conf.Log.Filename) + stdWriter, err := NewRotatingFileFromConfig(conf.Log, "info") if err != nil { - return fmt.Errorf("log: %s", err) + log.WithError(err).Fatal("Failed to set standard log file") + return } errWriter, err := NewRotatingFileFromConfig(conf.Log, "error") if err != nil { - return fmt.Errorf("log: %s", err) + log.WithError(err).Fatal("Failed to set error log file") + return } log.WithFields(log.Fields{ @@ -295,7 +308,8 @@ func serverCmd(ctx *cli.Context) error { telegram, err := telegram.New(conf.Telegram.Id) if err != nil { - return fmt.Errorf("telegram: %s", err) + log.WithError(err).Fatal("Failed to initialize telegram notifier") + return } telegram.AddReceivers(conf.Telegram.Channel) @@ -314,7 +328,8 @@ func serverCmd(ctx *cli.Context) error { err = rdb.Ping(context.Background()).Err() if err != nil { - return fmt.Errorf("redis: %s", err) + log.WithError(err).Fatal("Failed to connect to redis") + return } // Setup cache storage @@ -331,7 +346,8 @@ func serverCmd(ctx *cli.Context) error { eosClient := eos.New(conf.Api) chainInfo, err = eosClient.GetInfo(context.Background()) if err != nil { - return fmt.Errorf("eosapi: %s", err) + log.WithError(err).Fatal("Failed to call eos api") + return } shClient = shipclient.NewStream(func(s *shipclient.Stream) { @@ -343,7 +359,8 @@ func serverCmd(ctx *cli.Context) error { // Get codec codec, err := message.GetCodec(conf.MessageCodec) if err != nil { - return fmt.Errorf("codec: %s", err) + log.WithError(err).Fatal("Failed to initialze codec") + return } chain_id := getChain(chainInfo.ChainID.String()) @@ -365,6 +382,4 @@ func serverCmd(ctx *cli.Context) error { // Close the processor properly processor.Close() - - return nil } diff --git a/cmd/tools/bench.go b/cmd/tools/bench.go index 31149f9..31af016 100644 --- a/cmd/tools/bench.go +++ b/cmd/tools/bench.go @@ -7,7 +7,7 @@ import ( "os/signal" "time" - "github.com/urfave/cli/v2" + "github.com/spf13/cobra" "github.com/eosswedenorg/thalos/api" "github.com/eosswedenorg/thalos/api/message" @@ -18,44 +18,38 @@ import ( log "github.com/sirupsen/logrus" ) -var benchCmd = &cli.Command{ - Name: "bench", - Usage: "Run a benchmark against a thalos node", - Flags: []cli.Flag{ - redisUrlFlag, - redisUserFlag, - redisPasswordFlag, - redisDbFlag, - prefixFlag, - chainIdFlag, - &cli.DurationFlag{ - Name: "interval", - Aliases: []string{"i"}, - Value: time.Minute, - Usage: "How often the benchmark results should be displayed.", - }, - }, - Action: func(ctx *cli.Context) error { +var benchCmd = &cobra.Command{ + Use: "bench", + Short: "Run a benchmark against a thalos node", + Run: func(cmd *cobra.Command, args []string) { var counter int = 0 - interval := ctx.Duration("interval") + interval, _ := cmd.Flags().GetDuration("interval") + + url, _ := cmd.Flags().GetString("redis-url") + user, _ := cmd.Flags().GetString("redis-user") + pw, _ := cmd.Flags().GetString("redis-pw") + prefix, _ := cmd.Flags().GetString("prefix") + chain_id, _ := cmd.Flags().GetString("chain_id") + db, _ := cmd.Flags().GetInt("redis-db") log.WithFields(log.Fields{ - "url": ctx.String("redis-url"), - "prefix": ctx.String("prefix"), - "chain_id": ctx.String("chain_id"), - "database": ctx.Int("redis-db"), + "url": url, + "prefix": prefix, + "chain_id": chain_id, + "database": db, }).Info("Connecting to redis") // Create redis client rdb := redis.NewClient(&redis.Options{ - Addr: ctx.String("redis-url"), - Username: ctx.String("redis-user"), - Password: ctx.String("redis-pw"), - DB: ctx.Int("redis-db"), + Addr: url, + Username: user, + Password: pw, + DB: db, }) if err := rdb.Ping(context.Background()).Err(); err != nil { - return err + log.WithError(err).Fatal("Failed to connect to redis") + return } log.Println("Connected to redis") @@ -65,20 +59,22 @@ var benchCmd = &cli.Command{ }).Info("Starting benchmark") sub := api_redis.NewSubscriber(context.Background(), rdb, api_redis.Namespace{ - Prefix: ctx.String("prefix"), - ChainID: ctx.String("chain_id"), + Prefix: prefix, + ChainID: chain_id, }) codec, err := message.GetCodec("json") if err != nil { - return err + log.WithError(err).Fatal("Failed to get codec") + return } client := api.NewClient(sub, codec.Decoder) // Subscribe to all actions if err = client.Subscribe(api.ActionChannel{}.Channel()); err != nil { - return err + log.WithError(err).Fatal("Failed to subscribe to channels") + return } go func() { @@ -102,7 +98,7 @@ var benchCmd = &cli.Command{ case <-sig: fmt.Println("Got interrupt") client.Close() - return nil + return case now := <-time.After(interval): elapsed := now.Sub(t) t = now diff --git a/cmd/tools/flags.go b/cmd/tools/flags.go deleted file mode 100644 index 24c0ee5..0000000 --- a/cmd/tools/flags.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "github.com/urfave/cli/v2" -) - -var redisUrlFlag = &cli.StringFlag{ - Name: "redis-url", - Value: "127.0.0.1:6379", - Usage: "host:port to the redis server", -} - -var redisUserFlag = &cli.StringFlag{ - Name: "redis-user", - Usage: "User to use when authenticating to the server", -} - -var redisPasswordFlag = &cli.StringFlag{ - Name: "redis-pw", - Usage: "Password to use when authenticating to the server", -} - -var redisDbFlag = &cli.IntFlag{ - Name: "redis-db", - Value: 0, - Usage: "What redis database we should connect to.", -} - -var prefixFlag = &cli.StringFlag{ - Name: "prefix", - Value: "ship", -} - -var chainIdFlag = &cli.StringFlag{ - Name: "chain_id", - Value: "1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4", -} diff --git a/cmd/tools/main.go b/cmd/tools/main.go index 4670591..aac073e 100644 --- a/cmd/tools/main.go +++ b/cmd/tools/main.go @@ -1,29 +1,63 @@ package main import ( - "os" - - "github.com/urfave/cli/v2" + "time" _ "github.com/eosswedenorg/thalos/app/log" log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var VersionString string = "dev" -func main() { - app := &cli.App{ - Usage: "Collection of tools for dealing with the thalos application", - Version: VersionString, - Commands: []*cli.Command{ - validateCmd, - benchCmd, - RedisACLCmd, - MockPublisherCmd, +var rootCmd *cobra.Command + +func init() { + redisFlags := pflag.FlagSet{} + redisFlags.String("redis-url", "127.0.0.1:6379", "host:port to the redis server") + redisFlags.String("redis-user", "", "User to use when authenticating to the server") + redisFlags.String("redis-pw", "", "Password to use when authenticating to the server") + redisFlags.Int("redis-db", 0, "What redis database we should connect to.") + redisFlags.String("prefix", "ship", "redis prefix") + redisFlags.String("chain_id", "1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4", "chain id") + + rootCmd = &cobra.Command{ + Use: "thalos-tools", + Short: "Collection of tools for dealing with the thalos application", + FParseErrWhitelist: cobra.FParseErrWhitelist{ + UnknownFlags: true, }, + Version: VersionString, } - if err := app.Run(os.Args); err != nil { - log.WithError(err).Fatal("Application error") + benchCmd.Flags().AddFlagSet(&redisFlags) + benchCmd.Flags().DurationP("interval", "i", time.Minute, "How often the benchmark results should be displayed.") + + validateCmd.Flags().AddFlagSet(&redisFlags) + + MockPublisherCmd.Flags().AddFlagSet(&redisFlags) + MockPublisherCmd.Flags().String("codec", "json", "codec to use") + + RedisACLCmd.Flags().String("default-pw", "", "Password to use for the default account, if not provided a random one will be generated") + RedisACLCmd.Flags().String("client", "thalos-client", "Thalos client account name") + RedisACLCmd.Flags().String("client-pw", "", "Password to use for the thalos client account, if not provided a random one will be generated") + RedisACLCmd.Flags().String("server", "thalos", "Thalos account name") + RedisACLCmd.Flags().String("server-pw", "", "Password to use for the thalos server account, if not provided a random one will be generated") + RedisACLCmd.Flags().String("prefix", "ship", "Redis key prefix") + RedisACLCmd.Flags().Bool("cleartext", false, "If passwords should be hashed or left in cleartext.") + RedisACLCmd.Flags().String("file", "", "Where the config should be written to (default: standard out)") + + rootCmd.AddCommand( + validateCmd, + benchCmd, + RedisACLCmd, + MockPublisherCmd, + ) +} + +func main() { + if err := rootCmd.Execute(); err != nil { + log.Fatal(err) } } diff --git a/cmd/tools/mock_publisher.go b/cmd/tools/mock_publisher.go index 7d69e1a..a45b280 100644 --- a/cmd/tools/mock_publisher.go +++ b/cmd/tools/mock_publisher.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/urfave/cli/v2" + "github.com/spf13/cobra" "github.com/eosswedenorg/thalos/api" "github.com/eosswedenorg/thalos/api/message" @@ -16,45 +16,43 @@ import ( log "github.com/sirupsen/logrus" ) -var MockPublisherCmd = &cli.Command{ - Name: "mock_publisher", - Usage: "Run a publisher that mocks messages to a redis server. tries to send as many messages as possible", - Flags: []cli.Flag{ - redisUrlFlag, - redisUserFlag, - redisPasswordFlag, - redisDbFlag, - prefixFlag, - chainIdFlag, - &cli.StringFlag{ - Name: "codec", - Value: "json", - }, - }, - Action: func(ctx *cli.Context) error { +var MockPublisherCmd = &cobra.Command{ + Use: "mock_publisher", + Short: "Run a publisher that mocks messages to a redis server. tries to send as many messages as possible", + Run: func(cmd *cobra.Command, args []string) { + url, _ := cmd.Flags().GetString("redis-url") + user, _ := cmd.Flags().GetString("redis-user") + pw, _ := cmd.Flags().GetString("redis-pw") + prefix, _ := cmd.Flags().GetString("prefix") + chain_id, _ := cmd.Flags().GetString("chain_id") + db, _ := cmd.Flags().GetInt("redis-db") + // Create redis client rdb := redis.NewClient(&redis.Options{ - Addr: ctx.String("redis-url"), - Username: ctx.String("redis-user"), - Password: ctx.String("redis-pw"), - DB: ctx.Int("redis-db"), + Addr: url, + Username: user, + Password: pw, + DB: db, }) - codec, err := message.GetCodec(ctx.String("codec")) + codecArg, _ := cmd.Flags().GetString("codec") + + codec, err := message.GetCodec(codecArg) if err != nil { - return err + log.WithError(err).Fatal("Failed to get codec") + return } log.WithFields(log.Fields{ - "url": ctx.String("redis-url"), - "prefix": ctx.String("prefix"), - "chain_id": ctx.String("chain_id"), - "database": ctx.Int("redis-db"), + "url": url, + "prefix": prefix, + "chain_id": chain_id, + "database": db, }).Info("Starting mock publisher") ns := api_redis.Namespace{ - Prefix: ctx.String("prefix"), - ChainID: ctx.String("chain_id"), + Prefix: prefix, + ChainID: chain_id, } publisher := redis_driver.NewPublisher(context.Background(), rdb, ns) @@ -104,7 +102,8 @@ var MockPublisherCmd = &cli.Command{ payload, err := codec.Encoder(msg) if err != nil { - return err + log.WithError(err).Fatal("Failed to encode message") + return } channel := api.ActionChannel{}.Channel() diff --git a/cmd/tools/redis-acl.go b/cmd/tools/redis-acl.go index 4f2f2aa..25307b1 100644 --- a/cmd/tools/redis-acl.go +++ b/cmd/tools/redis-acl.go @@ -10,7 +10,8 @@ import ( "text/template" "time" - "github.com/urfave/cli/v2" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" ) var rnd *rand.Rand @@ -90,60 +91,30 @@ user {{.client}} on {{.clientpw}} resetchannels &{{.prefix}}::* -@all +subscribe }) } -var RedisACLCmd = &cli.Command{ - Name: "redis-acl", - Usage: "create a users.acl file", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "default-pw", - Usage: "Password to use for the default account, if not provided a random one will be generated", - }, - &cli.StringFlag{ - Name: "client", - Value: "thalos-client", - Usage: "Thalos client account name", - }, - &cli.StringFlag{ - Name: "client-pw", - Usage: "Password to use for the thalos client account, if not provided a random one will be generated", - }, - &cli.StringFlag{ - Name: "server", - Value: "thalos", - Usage: "Thalos account name", - }, - &cli.StringFlag{ - Name: "server-pw", - Usage: "Password to use for the thalos server account, if not provided a random one will be generated", - }, - &cli.StringFlag{ - Name: "prefix", - Value: "ship", - Usage: "Redis key prefix", - }, - &cli.BoolFlag{ - Name: "cleartext", - Usage: "If passwords should be hashed or left in cleartext.", - }, - &cli.StringFlag{ - Name: "file", - DefaultText: "Standard out", - Usage: "Where the config should be written to", - }, - }, - Action: func(ctx *cli.Context) error { +var RedisACLCmd = &cobra.Command{ + Use: "redis-acl", + Short: "create a users.acl file", + Run: func(cmd *cobra.Command, args []string) { var err error var out *os.File = os.Stdout rnd = rand.New(rand.NewSource(time.Now().UnixNano())) - defaultUser := NewUser("default", ctx.String("default-pw")) - serverUser := NewUser(ctx.String("server"), ctx.String("server-pw")) - clientUser := NewUser(ctx.String("client"), ctx.String("client-pw")) + flagDefUserPw, _ := cmd.Flags().GetString("default-pw") + flagServer, _ := cmd.Flags().GetString("server") + flagServerPw, _ := cmd.Flags().GetString("server-pw") + flagClient, _ := cmd.Flags().GetString("client") + flagClientPw, _ := cmd.Flags().GetString("client-pw") + flagPrefix, _ := cmd.Flags().GetString("prefix") + + defaultUser := NewUser("default", flagDefUserPw) + serverUser := NewUser(flagServer, flagServerPw) + clientUser := NewUser(flagClient, flagClientPw) atleastOneGeneratedPw := defaultUser.Generated || serverUser.Generated || clientUser.Generated - if !ctx.Bool("cleartext") { + cleartext, _ := cmd.Flags().GetBool("cleartext") + if !cleartext { if atleastOneGeneratedPw { println("Passwords") } @@ -157,17 +128,22 @@ var RedisACLCmd = &cli.Command{ clientUser.Hash() } - filename := ctx.String("file") + filename, _ := cmd.Flags().GetString("file") if len(filename) > 0 { out, err = os.Create(filename) if err != nil { - return err + log.WithError(err).Fatal("Failed to create output file") + return } defer out.Close() - } else if !ctx.Bool("cleartext") && atleastOneGeneratedPw { + } else if !cleartext && atleastOneGeneratedPw { fmt.Println() } - return writeTemplate(out, defaultUser, serverUser, clientUser, ctx.String("prefix")) + err = writeTemplate(out, defaultUser, serverUser, clientUser, flagPrefix) + if err != nil { + log.WithError(err).Fatal("Failed to writte config") + return + } }, } diff --git a/cmd/tools/validate.go b/cmd/tools/validate.go index 96645e5..a0de15d 100644 --- a/cmd/tools/validate.go +++ b/cmd/tools/validate.go @@ -7,7 +7,7 @@ import ( "os/signal" "time" - "github.com/urfave/cli/v2" + "github.com/spf13/cobra" "github.com/eosswedenorg/thalos/api" "github.com/eosswedenorg/thalos/api/message" @@ -18,33 +18,33 @@ import ( log "github.com/sirupsen/logrus" ) -var validateCmd = &cli.Command{ - Name: "validate", - Usage: "Validate a thalos server by following action traces and makes sure that blocks arrive in order.", - Flags: []cli.Flag{ - redisUrlFlag, - redisDbFlag, - prefixFlag, - chainIdFlag, - }, - Action: func(ctx *cli.Context) error { +var validateCmd = &cobra.Command{ + Use: "validate", + Short: "Validate a thalos server by following action traces and makes sure that blocks arrive in order.", + Run: func(cmd *cobra.Command, args []string) { status_duration := time.Second * 10 + url, _ := cmd.Flags().GetString("redis-url") + prefix, _ := cmd.Flags().GetString("prefix") + chain_id, _ := cmd.Flags().GetString("chain_id") + db, _ := cmd.Flags().GetInt("redis-db") + log.WithFields(log.Fields{ - "url": ctx.String("redis-url"), - "prefix": ctx.String("prefix"), - "chain_id": ctx.String("chain_id"), - "database": ctx.Int("redis-db"), + "url": url, + "prefix": prefix, + "chain_id": chain_id, + "database": db, }).Info("Connecting to redis") // Create redis client rdb := redis.NewClient(&redis.Options{ - Addr: ctx.String("redis-url"), - DB: ctx.Int("redis-db"), + Addr: url, + DB: db, }) if err := rdb.Ping(context.Background()).Err(); err != nil { - return err + log.WithError(err).Fatal("Failed to connect to redis") + return } log.Println("Connected to redis") @@ -52,20 +52,22 @@ var validateCmd = &cli.Command{ log.Info("Starting validation, following the stream") sub := api_redis.NewSubscriber(context.Background(), rdb, api_redis.Namespace{ - Prefix: ctx.String("prefix"), - ChainID: ctx.String("chain_id"), + Prefix: prefix, + ChainID: chain_id, }) codec, err := message.GetCodec("json") if err != nil { - return err + log.WithError(err).Fatal("Failed to get codec") + return } client := api.NewClient(sub, codec.Decoder) // Subscribe to all actions if err = client.Subscribe(api.ActionChannel{}.Channel()); err != nil { - return err + log.WithError(err).Fatal("Failed to subscribe to channels") + return } block_num := uint32(0) @@ -102,7 +104,7 @@ var validateCmd = &cli.Command{ case <-sig: fmt.Println("Got interrupt") client.Close() - return nil + return case <-timer.C: log.WithField("duration", timeout). Warn("Did not get any messages during the defined duration") diff --git a/go.mod b/go.mod index 9079d42..1c28f41 100644 --- a/go.mod +++ b/go.mod @@ -14,21 +14,22 @@ require ( github.com/nikoksr/notify v0.41.0 github.com/redis/go-redis/v9 v9.4.0 github.com/sirupsen/logrus v1.9.3 + github.com/spf13/cobra v1.8.0 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 - github.com/urfave/cli/v2 v2.27.1 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/blendle/zapdriver v1.3.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/eosswedenorg-go/jsontime v0.0.0-20230509125027-08422d6236c7 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible // indirect github.com/gorilla/websocket v1.5.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.6 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -39,7 +40,6 @@ require ( github.com/onsi/gomega v1.31.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect github.com/technoweenie/multipartstreamer v1.0.1 // indirect github.com/tidwall/gjson v1.17.0 // indirect @@ -49,7 +49,6 @@ require ( github.com/vmihailenco/go-tinylfu v0.2.2 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect go.uber.org/goleak v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect diff --git a/go.sum b/go.sum index 7003b7b..1998506 100644 --- a/go.sum +++ b/go.sum @@ -13,7 +13,6 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -65,6 +64,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -131,10 +132,13 @@ github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0 github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 h1:RN5mrigyirb8anBEtdjtHFIufXdacyTi6i4KBfeNXeo= github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -162,8 +166,6 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= -github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/vmihailenco/go-tinylfu v0.2.2 h1:H1eiG6HM36iniK6+21n9LLpzx1G9R3DJa2UjUjbynsI= github.com/vmihailenco/go-tinylfu v0.2.2/go.mod h1:CutYi2Q9puTxfcolkliPq4npPuofg9N9t8JVrjzwa3Q= github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= @@ -171,8 +173,6 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= -github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=