Stateless prototype - enable metrics collection (#442)

This commit is contained in:
Alex Sharov 2020-04-13 01:36:14 +07:00 committed by GitHub
parent fb08514b9b
commit 9e65f886ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 124 additions and 69 deletions

View File

@ -4,27 +4,24 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"os/signal"
"runtime/pprof"
"syscall"
"github.com/ledgerwatch/turbo-geth/cmd/utils"
"github.com/ledgerwatch/turbo-geth/core"
"github.com/ledgerwatch/turbo-geth/internal/debug"
"github.com/ledgerwatch/turbo-geth/log"
"github.com/spf13/cobra"
)
var (
cpuprofile string
cpuProfileFile io.WriteCloser
genesisPath string
genesis *core.Genesis
genesisPath string
genesis *core.Genesis
)
func init() {
rootCmd.PersistentFlags().StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile `file`")
utils.CobraFlags(rootCmd, append(debug.Flags, utils.MetricsEnabledFlag, utils.MetricsEnabledExpensiveFlag))
rootCmd.PersistentFlags().StringVar(&genesisPath, "genesis", "", "path to genesis.json file")
}
@ -50,15 +47,17 @@ var rootCmd = &cobra.Command{
Use: "state",
Short: "state is a utility for Stateless ethereum clients",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if err := debug.SetupCobra(cmd); err != nil {
panic(err)
}
genesis = core.DefaultGenesisBlock()
if genesisPath != "" {
genesis = genesisFromFile(genesisPath)
}
startProfilingIfNeeded()
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
stopProfilingIfNeeded()
debug.Exit()
},
}
@ -82,29 +81,3 @@ func Execute() {
os.Exit(1)
}
}
func startProfilingIfNeeded() {
if cpuprofile != "" {
fmt.Println("starting CPU profiling")
cpuProfileFile, err := os.Create(cpuprofile)
if err != nil {
log.Error("could not create CPU profile", "error", err)
return
}
if err := pprof.StartCPUProfile(cpuProfileFile); err != nil {
log.Error("could not start CPU profile", "error", err)
return
}
}
}
func stopProfilingIfNeeded() {
if cpuprofile != "" {
fmt.Println("stopping CPU profiling")
pprof.StopCPUProfile()
}
if cpuProfileFile != nil {
cpuProfileFile.Close()
}
}

View File

@ -53,7 +53,6 @@ var statelessCmd = &cobra.Command{
Use: "stateless",
Short: "Stateless Ethereum prototype",
RunE: func(cmd *cobra.Command, args []string) error {
createDb := func(path string) (ethdb.Database, error) {
return ethdb.NewBoltDatabase(path)
}

View File

@ -1,38 +1,9 @@
package main
import (
"io"
"os"
"github.com/ledgerwatch/turbo-geth/cmd/state/commands"
"github.com/ledgerwatch/turbo-geth/log"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
"net/http"
//nolint:gosec
_ "net/http/pprof"
)
func main() {
var (
ostream log.Handler
glogger *log.GlogHandler
)
usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb"
output := io.Writer(os.Stderr)
if usecolor {
output = colorable.NewColorableStderr()
}
ostream = log.StreamHandler(output, log.TerminalFormat(usecolor))
glogger = log.NewGlogHandler(ostream)
log.Root().SetHandler(glogger)
glogger.Verbosity(log.LvlInfo)
go func() {
log.Info("HTTP", "error", http.ListenAndServe("localhost:6060", nil))
}()
commands.Execute()
}

View File

@ -32,6 +32,7 @@ import (
"text/template"
"time"
pcsclite "github.com/gballet/go-libpcsclite"
"github.com/ledgerwatch/turbo-geth/accounts"
"github.com/ledgerwatch/turbo-geth/accounts/keystore"
"github.com/ledgerwatch/turbo-geth/common"
@ -61,8 +62,7 @@ import (
"github.com/ledgerwatch/turbo-geth/p2p/netutil"
"github.com/ledgerwatch/turbo-geth/params"
"github.com/ledgerwatch/turbo-geth/rpc"
pcsclite "github.com/gballet/go-libpcsclite"
"github.com/spf13/cobra"
"github.com/urfave/cli"
)
@ -1794,3 +1794,19 @@ func MigrateFlags(action func(ctx *cli.Context) error) func(*cli.Context) error
return action(ctx)
}
}
func CobraFlags(cmd *cobra.Command, urfaveCliFlags []cli.Flag) {
flags := cmd.PersistentFlags()
for _, flag := range urfaveCliFlags {
switch f := flag.(type) {
case cli.IntFlag:
flags.Int(f.Name, f.Value, f.Usage)
case cli.StringFlag:
flags.String(f.Name, f.Value, f.Usage)
case cli.BoolFlag:
flags.Bool(f.Name, false, f.Usage)
default:
panic(fmt.Errorf("unexpected type: %T", flag))
}
}
}

View File

@ -25,13 +25,15 @@ import (
"os/signal"
"runtime"
"syscall"
"time"
"github.com/fjl/memsize/memsizeui"
"github.com/ledgerwatch/turbo-geth/log"
"github.com/ledgerwatch/turbo-geth/metrics"
"github.com/ledgerwatch/turbo-geth/metrics/exp"
"github.com/fjl/memsize/memsizeui"
colorable "github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
"github.com/spf13/cobra"
"github.com/urfave/cli"
)
@ -112,6 +114,100 @@ func init() {
glogger = log.NewGlogHandler(ostream)
}
func SetupCobra(cmd *cobra.Command) error {
flags := cmd.Flags()
dbg, err := flags.GetBool(debugFlag.Name)
if err != nil {
return err
}
lvl, err := flags.GetInt(verbosityFlag.Name)
if err != nil {
return err
}
vmodule, err := flags.GetString(vmoduleFlag.Name)
if err != nil {
return err
}
backtrace, err := flags.GetString(backtraceAtFlag.Name)
if err != nil {
return err
}
// logging
log.PrintOrigins(dbg)
glogger.Verbosity(log.Lvl(lvl))
err = glogger.Vmodule(vmodule)
if err != nil {
return err
}
err = glogger.BacktraceAt(backtrace)
if err != nil {
return err
}
log.Root().SetHandler(glogger)
memprofilerate, err := flags.GetInt(memprofilerateFlag.Name)
if err != nil {
return err
}
blockprofilerate, err := flags.GetInt(blockprofilerateFlag.Name)
if err != nil {
return err
}
traceFile, err := flags.GetString(traceFlag.Name)
if err != nil {
return err
}
cpuFile, err := flags.GetString(cpuprofileFlag.Name)
if err != nil {
return err
}
// profiling, tracing
runtime.MemProfileRate = memprofilerate
Handler.SetBlockProfileRate(blockprofilerate)
if traceFile != "" {
if err2 := Handler.StartGoTrace(traceFile); err2 != nil {
return err2
}
}
if cpuFile != "" {
if err2 := Handler.StartCPUProfile(cpuFile); err2 != nil {
return err2
}
}
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
<-c
Exit()
}()
pprof, err := flags.GetBool(pprofFlag.Name)
if err != nil {
return err
}
pprofAddr, err := flags.GetString(pprofAddrFlag.Name)
if err != nil {
return err
}
pprofPort, err := flags.GetInt(pprofPortFlag.Name)
if err != nil {
return err
}
// pprof server
if pprof {
StartPProf(fmt.Sprintf("%s:%d", pprofAddr, pprofPort))
}
// Start system runtime metrics collection
go metrics.CollectProcessMetrics(3 * time.Second)
return nil
}
// Setup initializes profiling and logging based on the CLI flags.
// It should be called as early as possible in the program.
func Setup(ctx *cli.Context) error {