From 9e65f886eae15fab064a4581c94c5abf331af870 Mon Sep 17 00:00:00 2001
From: Alex Sharov <AskAlexSharov@gmail.com>
Date: Mon, 13 Apr 2020 01:36:14 +0700
Subject: [PATCH] Stateless prototype - enable metrics collection (#442)
---
cmd/state/commands/root.go | 45 +++------------
cmd/state/commands/stateless.go | 1 -
cmd/state/main.go | 29 ----------
cmd/utils/flags.go | 20 ++++++-
internal/debug/flags.go | 98 ++++++++++++++++++++++++++++++++-
5 files changed, 124 insertions(+), 69 deletions(-)
diff --git a/cmd/state/commands/root.go b/cmd/state/commands/root.go
index 28ec17062b..71ae187fa3 100644
--- a/cmd/state/commands/root.go
+++ b/cmd/state/commands/root.go
@@ -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()
- }
-}
diff --git a/cmd/state/commands/stateless.go b/cmd/state/commands/stateless.go
index 55b8feb53f..3e078f769d 100644
--- a/cmd/state/commands/stateless.go
+++ b/cmd/state/commands/stateless.go
@@ -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)
}
diff --git a/cmd/state/main.go b/cmd/state/main.go
index 0aa86c9fb4..75de60a7f8 100644
--- a/cmd/state/main.go
+++ b/cmd/state/main.go
@@ -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()
}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index ef951d9907..6e7cb74395 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -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))
+ }
+ }
+}
diff --git a/internal/debug/flags.go b/internal/debug/flags.go
index ec3ae2e422..c51d72ce22 100644
--- a/internal/debug/flags.go
+++ b/internal/debug/flags.go
@@ -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 {
--
GitLab