github.com/prysmaticlabs/prysm@v1.4.4/cmd/client-stats/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 runtimeDebug "runtime/debug" 7 "time" 8 9 joonix "github.com/joonix/log" 10 "github.com/prysmaticlabs/prysm/cmd/client-stats/flags" 11 "github.com/prysmaticlabs/prysm/shared/clientstats" 12 "github.com/prysmaticlabs/prysm/shared/cmd" 13 "github.com/prysmaticlabs/prysm/shared/journald" 14 "github.com/prysmaticlabs/prysm/shared/logutil" 15 "github.com/prysmaticlabs/prysm/shared/version" 16 "github.com/sirupsen/logrus" 17 "github.com/urfave/cli/v2" 18 prefixed "github.com/x-cray/logrus-prefixed-formatter" 19 ) 20 21 var appFlags = []cli.Flag{ 22 cmd.VerbosityFlag, 23 cmd.LogFormat, 24 cmd.LogFileName, 25 cmd.ConfigFileFlag, 26 flags.BeaconnodeMetricsURLFlag, 27 flags.ValidatorMetricsURLFlag, 28 flags.ClientStatsAPIURLFlag, 29 flags.ScrapeIntervalFlag, 30 } 31 32 func main() { 33 app := cli.App{} 34 app.Name = "client-stats" 35 app.Usage = "daemon to scrape client-stats from prometheus and ship to a remote endpoint" 36 app.Action = run 37 app.Version = version.Version() 38 39 app.Flags = appFlags 40 41 // logging/config setup cargo-culted from beaconchain 42 app.Before = func(ctx *cli.Context) error { 43 // Load flags from config file, if specified. 44 if err := cmd.LoadFlagsFromConfig(ctx, app.Flags); err != nil { 45 return err 46 } 47 48 verbosity := ctx.String(cmd.VerbosityFlag.Name) 49 level, err := logrus.ParseLevel(verbosity) 50 if err != nil { 51 return err 52 } 53 logrus.SetLevel(level) 54 55 format := ctx.String(cmd.LogFormat.Name) 56 switch format { 57 case "text": 58 formatter := new(prefixed.TextFormatter) 59 formatter.TimestampFormat = "2006-01-02 15:04:05" 60 formatter.FullTimestamp = true 61 // If persistent log files are written - we disable the log messages coloring because 62 // the colors are ANSI codes and seen as gibberish in the log files. 63 formatter.DisableColors = ctx.String(cmd.LogFileName.Name) != "" 64 logrus.SetFormatter(formatter) 65 case "fluentd": 66 f := joonix.NewFormatter() 67 if err := joonix.DisableTimestampFormat(f); err != nil { 68 panic(err) 69 } 70 logrus.SetFormatter(f) 71 case "json": 72 logrus.SetFormatter(&logrus.JSONFormatter{}) 73 case "journald": 74 if err := journald.Enable(); err != nil { 75 return err 76 } 77 default: 78 return fmt.Errorf("unknown log format %s", format) 79 } 80 81 logFileName := ctx.String(cmd.LogFileName.Name) 82 if logFileName != "" { 83 if err := logutil.ConfigurePersistentLogging(logFileName); err != nil { 84 log.WithError(err).Error("Failed to configuring logging to disk.") 85 } 86 } 87 return cmd.ValidateNoArgs(ctx) 88 } 89 90 defer func() { 91 if x := recover(); x != nil { 92 log.Errorf("Runtime panic: %v\n%v", x, string(runtimeDebug.Stack())) 93 panic(x) 94 } 95 }() 96 97 if err := app.Run(os.Args); err != nil { 98 log.Error(err.Error()) 99 } 100 } 101 102 func run(ctx *cli.Context) error { 103 var upd clientstats.Updater 104 if ctx.IsSet(flags.ClientStatsAPIURLFlag.Name) { 105 u := ctx.String(flags.ClientStatsAPIURLFlag.Name) 106 upd = clientstats.NewClientStatsHTTPPostUpdater(u) 107 } else { 108 log.Warn("No --clientstats-api-url flag set, writing to stdout as default metrics sink.") 109 upd = clientstats.NewGenericClientStatsUpdater(os.Stdout) 110 } 111 112 scrapers := make([]clientstats.Scraper, 0) 113 if ctx.IsSet(flags.BeaconnodeMetricsURLFlag.Name) { 114 u := ctx.String(flags.BeaconnodeMetricsURLFlag.Name) 115 scrapers = append(scrapers, clientstats.NewBeaconNodeScraper(u)) 116 } 117 if ctx.IsSet(flags.ValidatorMetricsURLFlag.Name) { 118 u := ctx.String(flags.ValidatorMetricsURLFlag.Name) 119 scrapers = append(scrapers, clientstats.NewValidatorScraper(u)) 120 } 121 122 ticker := time.NewTicker(ctx.Duration(flags.ScrapeIntervalFlag.Name)) 123 for { 124 select { 125 case <-ticker.C: 126 for _, s := range scrapers { 127 r, err := s.Scrape() 128 if err != nil { 129 log.Errorf("Scraper error: %s", err) 130 continue 131 } 132 err = upd.Update(r) 133 if err != nil { 134 log.Errorf("client-stats collector error: %s", err) 135 continue 136 } 137 } 138 case <-ctx.Done(): 139 ticker.Stop() 140 return nil 141 } 142 } 143 }