mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-04-19 03:01:06 -04:00
**What type of PR is this?** Feature **What does this PR do? Why is it needed?** This PR adds a `--log.vmodule` flag to the beacon-chain and validator apps, that allows setting a different verbosity for every* package. *: not every package, but most packages. (all packages that define their logger variable with a `package` field) Combined with the `--verbosity` flag this allows users to control exactly what they see. This affects both the terminal and the log file (`--log-file`), but not the ephemeral debug log file. example usage: ``` ./beacon-chain --log.vmodule=beacon-chain/p2p=info,beacon-chain/sync=error,beacon-chain/sync/initial-sync=debug ``` There are improvements to be done later, like accepting just the package name instead of the full path, etc.
150 lines
4.2 KiB
Go
150 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
runtimeDebug "runtime/debug"
|
|
"time"
|
|
|
|
"github.com/OffchainLabs/prysm/v7/cmd"
|
|
"github.com/OffchainLabs/prysm/v7/cmd/client-stats/flags"
|
|
"github.com/OffchainLabs/prysm/v7/io/logs"
|
|
"github.com/OffchainLabs/prysm/v7/monitoring/clientstats"
|
|
"github.com/OffchainLabs/prysm/v7/monitoring/journald"
|
|
prefixed "github.com/OffchainLabs/prysm/v7/runtime/logging/logrus-prefixed-formatter"
|
|
"github.com/OffchainLabs/prysm/v7/runtime/version"
|
|
joonix "github.com/joonix/log"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
var appFlags = []cli.Flag{
|
|
cmd.VerbosityFlag,
|
|
cmd.LogFormat,
|
|
cmd.LogFileName,
|
|
cmd.ConfigFileFlag,
|
|
flags.BeaconnodeMetricsURLFlag,
|
|
flags.ValidatorMetricsURLFlag,
|
|
flags.ClientStatsAPIURLFlag,
|
|
flags.ScrapeIntervalFlag,
|
|
}
|
|
|
|
func init() {
|
|
appFlags = cmd.WrapFlags(appFlags)
|
|
}
|
|
|
|
func main() {
|
|
app := cli.App{}
|
|
app.Name = "client-stats"
|
|
app.Usage = "daemon to scrape client-stats from prometheus and ship to a remote endpoint"
|
|
app.Action = run
|
|
app.Version = version.Version()
|
|
|
|
app.Flags = appFlags
|
|
|
|
// logging/config setup cargo-culted from beaconchain
|
|
app.Before = func(ctx *cli.Context) error {
|
|
// Load flags from config file, if specified.
|
|
if err := cmd.LoadFlagsFromConfig(ctx, app.Flags); err != nil {
|
|
return err
|
|
}
|
|
|
|
verbosity := ctx.String(cmd.VerbosityFlag.Name)
|
|
level, err := logrus.ParseLevel(verbosity)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logrus.SetLevel(level)
|
|
|
|
format := ctx.String(cmd.LogFormat.Name)
|
|
switch format {
|
|
case "text":
|
|
formatter := new(prefixed.TextFormatter)
|
|
formatter.TimestampFormat = "2006-01-02 15:04:05.00"
|
|
formatter.FullTimestamp = true
|
|
// If persistent log files are written - we disable the log messages coloring because
|
|
// the colors are ANSI codes and seen as gibberish in the log files.
|
|
formatter.DisableColors = ctx.String(cmd.LogFileName.Name) != ""
|
|
logrus.SetFormatter(formatter)
|
|
case "fluentd":
|
|
f := joonix.NewFormatter()
|
|
if err := joonix.DisableTimestampFormat(f); err != nil {
|
|
panic(err) // lint:nopanic -- This shouldn't happen, but crashing immediately at startup is OK.
|
|
}
|
|
logrus.SetFormatter(f)
|
|
case "json":
|
|
logrus.SetFormatter(&logrus.JSONFormatter{
|
|
TimestampFormat: "2006-01-02 15:04:05.00",
|
|
})
|
|
case "journald":
|
|
if err := journald.Enable(); err != nil {
|
|
return err
|
|
}
|
|
default:
|
|
return fmt.Errorf("unknown log format %s", format)
|
|
}
|
|
|
|
logFileName := ctx.String(cmd.LogFileName.Name)
|
|
if logFileName != "" {
|
|
if err := logs.ConfigurePersistentLogging(logFileName, format, level, map[string]logrus.Level{}); err != nil {
|
|
log.WithError(err).Error("Failed to configuring logging to disk.")
|
|
}
|
|
}
|
|
return cmd.ValidateNoArgs(ctx)
|
|
}
|
|
|
|
defer func() {
|
|
if x := recover(); x != nil {
|
|
log.Errorf("Runtime panic: %v\n%v", x, string(runtimeDebug.Stack()))
|
|
panic(x) // lint:nopanic -- This is just resurfacing the original panic.
|
|
}
|
|
}()
|
|
|
|
if err := app.Run(os.Args); err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
}
|
|
|
|
func run(ctx *cli.Context) error {
|
|
var upd clientstats.Updater
|
|
if ctx.IsSet(flags.ClientStatsAPIURLFlag.Name) {
|
|
u := ctx.String(flags.ClientStatsAPIURLFlag.Name)
|
|
upd = clientstats.NewClientStatsHTTPPostUpdater(u)
|
|
} else {
|
|
log.Warn("No --clientstats-api-url flag set, writing to stdout as default metrics sink.")
|
|
upd = clientstats.NewGenericClientStatsUpdater(os.Stdout)
|
|
}
|
|
|
|
scrapers := make([]clientstats.Scraper, 0)
|
|
if ctx.IsSet(flags.BeaconnodeMetricsURLFlag.Name) {
|
|
u := ctx.String(flags.BeaconnodeMetricsURLFlag.Name)
|
|
scrapers = append(scrapers, clientstats.NewBeaconNodeScraper(u))
|
|
}
|
|
if ctx.IsSet(flags.ValidatorMetricsURLFlag.Name) {
|
|
u := ctx.String(flags.ValidatorMetricsURLFlag.Name)
|
|
scrapers = append(scrapers, clientstats.NewValidatorScraper(u))
|
|
}
|
|
|
|
ticker := time.NewTicker(ctx.Duration(flags.ScrapeIntervalFlag.Name))
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
for _, s := range scrapers {
|
|
r, err := s.Scrape()
|
|
if err != nil {
|
|
log.WithError(err).Error("Scraper error")
|
|
continue
|
|
}
|
|
err = upd.Update(r)
|
|
if err != nil {
|
|
log.WithError(err).Error("Client stats collector error")
|
|
continue
|
|
}
|
|
}
|
|
case <-ctx.Done():
|
|
ticker.Stop()
|
|
return nil
|
|
}
|
|
}
|
|
}
|