diff --git a/cmd/state/commands/root.go b/cmd/state/commands/root.go
index 28ec17062b4065d8772301928a5ed7e15a00b4a3..71ae187fa3669c05b34ef8cf96316c95593eb498 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 55b8feb53fef0ce1055222dfc661109c228a4c76..3e078f769d4f24798d0c57d5a4b0192db3bd7073 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 0aa86c9fb48ca2000314e62cb65bdc1f7aa8c1ca..75de60a7f87748dd98cafa75405609dac30a41f1 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 ef951d99076c3e5d8f295007eb3dc006adb627ee..6e7cb7439508995478c9313bfce8e3dc3c9c0056 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 ec3ae2e422b6c64a5d78d64eeaa983cf92975faa..c51d72ce22bb63a3a244776cc9b6d4dc2799f4e6 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 {