Skip to content

Commit dde11d6

Browse files
committed
metrics: peek into toml to decide enabling
1 parent f6971a7 commit dde11d6

File tree

2 files changed

+47
-22
lines changed

2 files changed

+47
-22
lines changed

cmd/geth/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ func loadBaseConfig(ctx *cli.Context) gethConfig {
151151
// Load config file.
152152
if file := ctx.String(configFileFlag.Name); file != "" {
153153
if err := loadConfig(file, &cfg); err != nil {
154-
utils.Fatalf("%v", err)
154+
utils.Fatalf("failed to load config: %v", err)
155155
}
156156
}
157157

metrics/metrics.go

+46-21
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
package metrics
77

88
import (
9+
"flag"
10+
"io"
911
"os"
1012
"runtime/metrics"
1113
"runtime/pprof"
1214
"strconv"
13-
"strings"
1415
"syscall"
1516
"time"
1617

17-
"github.com/ethereum/go-ethereum/log"
18+
"github.com/naoina/toml"
1819
)
1920

2021
// Enabled is checked by the constructor functions for all of the
@@ -24,34 +25,58 @@ import (
2425
// for less cluttered pprof profiles.
2526
var Enabled = false
2627

27-
// enablerFlags is the CLI flag names to use to enable metrics collections.
28-
var enablerFlags = []string{"metrics"}
29-
30-
// enablerEnvVars is the env var names to use to enable metrics collections.
31-
var enablerEnvVars = []string{"GETH_METRICS"}
32-
3328
// init enables or disables the metrics system. Since we need this to run before
3429
// any other code gets to create meters and timers, we'll actually do an ugly hack
3530
// and peek into the command line args for the metrics flag.
3631
func init() {
37-
for _, enabler := range enablerEnvVars {
38-
if val, found := syscall.Getenv(enabler); found && !Enabled {
39-
if enable, _ := strconv.ParseBool(val); enable { // ignore error, flag parser will choke on it later
40-
log.Info("Enabling metrics collection")
41-
Enabled = true
42-
}
32+
if val, found := syscall.Getenv("GETH_METRICS"); found && !Enabled {
33+
if enable, _ := strconv.ParseBool(val); enable { // ignore error, flag parser will choke on it later
34+
Enabled = true
4335
}
4436
}
45-
for _, arg := range os.Args {
46-
flag := strings.TrimLeft(arg, "-")
4737

48-
for _, enabler := range enablerFlags {
49-
if !Enabled && flag == enabler {
50-
log.Info("Enabling metrics collection")
51-
Enabled = true
52-
}
38+
fs := flag.NewFlagSet("", flag.ContinueOnError)
39+
fs.SetOutput(io.Discard)
40+
fs.Bool("metrics", false, "")
41+
fs.String("config", "", "")
42+
43+
// The flag package will quit parsing immediately if it encounters a flag that
44+
// it was not declared to it ahead of time. We could be fancy and try to look
45+
// through the args and find the ones we care about, but then we'd need to
46+
// handle the various ways that flags can be defined -- which was the point of
47+
// using flags package in the first place! So instead, let's chop off the
48+
// first element in the args list each time a parse fails. This way we will
49+
// eventually parse every arg and get the ones we care about.
50+
for i := range os.Args[1:] {
51+
if err := fs.Parse(os.Args[i+1:]); err == nil {
52+
break
5353
}
5454
}
55+
56+
// Now visit the flags we defined which are present in the args and see if we
57+
// should enable metrics.
58+
fs.Visit(func(f *flag.Flag) {
59+
switch f.Name {
60+
case "metrics":
61+
Enabled = true
62+
case "config":
63+
data, err := os.ReadFile(f.Value.String())
64+
if err != nil {
65+
return
66+
}
67+
var cfg map[string]map[string]any
68+
if err := toml.Unmarshal(data, &cfg); err != nil {
69+
return
70+
}
71+
// A config file is definitely being used and was parsed correct. Let's
72+
// try to peek inside and see if metrics are listed as enabled.
73+
if m, ok := cfg["Metrics"]; ok {
74+
if v, ok := m["Enabled"].(bool); ok && v {
75+
Enabled = true
76+
}
77+
}
78+
}
79+
})
5580
}
5681

5782
var threadCreateProfile = pprof.Lookup("threadcreate")

0 commit comments

Comments
 (0)