Skip to content

Commit

Permalink
cmd/relay: bind debug and monitoring address separately
Browse files Browse the repository at this point in the history
Same principle as #2808.

Refactor the binding functions to be usable across multiple commands.
  • Loading branch information
gsora committed Jan 24, 2024
1 parent 84b9457 commit eae73f0
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 24 deletions.
13 changes: 13 additions & 0 deletions cmd/debug_tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright © 2022-2023 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1

package cmd

import (
"github.com/spf13/cobra"
)

// bindDebugMonitoringFlags binds Prometheus monitoring and debug address CLI flags.
func bindDebugMonitoringFlags(cmd *cobra.Command, monitorAddr, debugAddr *string, defaultMonitorAddr string) {
cmd.Flags().StringVar(monitorAddr, "monitoring-address", defaultMonitorAddr, "Listening address (ip and port) for the monitoring API (prometheus).")
cmd.Flags().StringVar(debugAddr, "debug-address", "", "Listening address (ip and port) for the pprof and QBFT debug API.")
}
110 changes: 110 additions & 0 deletions cmd/debug_tools_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright © 2022-2023 Obol Labs Inc. Licensed under the terms of a Business Source License 1.1

package cmd

import (
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/require"

"github.com/obolnetwork/charon/app"
)

func genTestCmd(t *testing.T, f func(config app.Config)) *cobra.Command {
t.Helper()

var conf app.Config

cmd := &cobra.Command{
Use: "test",
Short: "test",
}

cmd.Run = func(cmd *cobra.Command, args []string) {
f(conf)
}

bindDebugMonitoringFlags(cmd, &conf.MonitoringAddr, &conf.DebugAddr, "")

return cmd
}

func Test_bindDebugMonitoringFlags(t *testing.T) {
cmd := &cobra.Command{
Use: "testcmd",
}

t.Run("both present", func(t *testing.T) {
var (
mAddr = "127.0.0.1:9999"
dAddr = "127.0.0.1:8888"
)

cmd.ResetCommands()

testCmd := genTestCmd(t, func(config app.Config) {
require.Equal(t, mAddr, config.MonitoringAddr)
require.Equal(t, dAddr, config.DebugAddr)
})

cmd.AddCommand(testCmd)

cmd.SetArgs([]string{
"test",
"--monitoring-address",
mAddr,
"--debug-address",
dAddr,
})

require.NoError(t, cmd.Execute())
})

t.Run("only monitor", func(t *testing.T) {
var (
mAddr = "127.0.0.1:9999"
dAddr = ""
)
cmd.ResetCommands()

testCmd := genTestCmd(t, func(config app.Config) {
require.Equal(t, mAddr, config.MonitoringAddr)
require.Equal(t, dAddr, config.DebugAddr)
})

cmd.AddCommand(testCmd)

cmd.SetArgs([]string{
"test",
"--monitoring-address",
mAddr,
})

require.NoError(t, cmd.Execute())
})

t.Run("only debug", func(t *testing.T) {
var (
mAddr = ""
dAddr = "127.0.0.1:8888"
)

cmd.ResetCommands()

testCmd := genTestCmd(t, func(config app.Config) {
require.Equal(t, mAddr, config.MonitoringAddr)
require.Equal(t, dAddr, config.DebugAddr)
})

cmd.AddCommand(testCmd)

cmd.SetArgs([]string{
"test",
"--debug-address",
dAddr,
})

require.NoError(t, cmd.Execute())
})
}
2 changes: 1 addition & 1 deletion cmd/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func newRelayCmd(runFunc func(context.Context, relay.Config) error) *cobra.Comma

bindDataDirFlag(cmd.Flags(), &config.DataDir)
bindRelayFlag(cmd, &config)
bindDebugMonitoringFlags(cmd, &config.MonitoringAddr, &config.DebugAddr, "")

Check warning on line 37 in cmd/relay.go

View check run for this annotation

Codecov / codecov/patch

cmd/relay.go#L37

Added line #L37 was not covered by tests
bindP2PFlags(cmd, &config.P2PConfig)
bindLogFlags(cmd.Flags(), &config.LogConfig)
bindLokiFlags(cmd.Flags(), &config.LogConfig)
Expand All @@ -43,7 +44,6 @@ func newRelayCmd(runFunc func(context.Context, relay.Config) error) *cobra.Comma

func bindRelayFlag(cmd *cobra.Command, config *relay.Config) {
cmd.Flags().StringVar(&config.HTTPAddr, "http-address", "127.0.0.1:3640", "Listening address (ip and port) for the relay http server serving runtime ENR.")
cmd.Flags().StringVar(&config.MonitoringAddr, "monitoring-address", "127.0.0.1:3620", "Listening address (ip and port) for the prometheus and pprof monitoring http server.")
cmd.Flags().BoolVar(&config.AutoP2PKey, "auto-p2pkey", true, "Automatically create a p2pkey (secp256k1 private key used for p2p authentication and ENR) if none found in data directory.")
cmd.Flags().StringVar(&config.RelayLogLevel, "p2p-relay-loglevel", "", "Libp2p circuit relay log level. E.g., debug, info, warn, error.")

Expand Down
53 changes: 32 additions & 21 deletions cmd/relay/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Config struct {
DataDir string
HTTPAddr string
MonitoringAddr string
DebugAddr string
P2PConfig p2p.Config
LogConfig log.Config
AutoP2PKey bool
Expand Down Expand Up @@ -86,7 +87,7 @@ func Run(ctx context.Context, config Config) error {
}

// Start serving HTTP: ENR and monitoring.
serverErr := make(chan error, 2) // Buffer for 2 servers.
serverErr := make(chan error, 3) // Buffer for 3 servers.
go func() {
if config.HTTPAddr == "" {
return
Expand All @@ -99,27 +100,37 @@ func Run(ctx context.Context, config Config) error {
serverErr <- server.ListenAndServe()
}()

go func() {
if config.MonitoringAddr == "" {
return
}
if config.MonitoringAddr != "" {
go func() {
// Serve prometheus metrics wrapped with relay identifiers.
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.InstrumentMetricHandler(
promRegistry, promhttp.HandlerFor(promRegistry, promhttp.HandlerOpts{}),
))

log.Info(ctx, "Monitoring server started", z.Str("address", config.MonitoringAddr))
server := http.Server{Addr: config.MonitoringAddr, Handler: mux, ReadHeaderTimeout: time.Second}
serverErr <- server.ListenAndServe()
}()

Check warning on line 114 in cmd/relay/relay.go

View check run for this annotation

Codecov / codecov/patch

cmd/relay/relay.go#L104-L114

Added lines #L104 - L114 were not covered by tests
}

// Serve prometheus metrics wrapped with relay identifiers.
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.InstrumentMetricHandler(
promRegistry, promhttp.HandlerFor(promRegistry, promhttp.HandlerOpts{}),
))

// Copied from net/http/pprof/pprof.go
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)

server := http.Server{Addr: config.MonitoringAddr, Handler: mux, ReadHeaderTimeout: time.Second}
serverErr <- server.ListenAndServe()
}()
if config.DebugAddr != "" {
go func() {
debugMux := http.NewServeMux()

// Copied from net/http/pprof/pprof.go
debugMux.HandleFunc("/debug/pprof/", pprof.Index)
debugMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
debugMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
debugMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
debugMux.HandleFunc("/debug/pprof/trace", pprof.Trace)

log.Info(ctx, "Debug server started", z.Str("address", config.DebugAddr))

server := http.Server{Addr: config.DebugAddr, Handler: debugMux, ReadHeaderTimeout: time.Second}
serverErr <- server.ListenAndServe()
}()

Check warning on line 132 in cmd/relay/relay.go

View check run for this annotation

Codecov / codecov/patch

cmd/relay/relay.go#L118-L132

Added lines #L118 - L132 were not covered by tests
}

log.Info(ctx, "Relay started",
z.Str("peer_name", p2p.PeerName(tcpNode.ID())),
Expand Down
3 changes: 1 addition & 2 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func newRunCmd(runFunc func(context.Context, app.Config) error, unsafe bool) *co

bindPrivKeyFlag(cmd, &conf.PrivKeyFile, &conf.PrivKeyLocking)
bindRunFlags(cmd, &conf)
bindDebugMonitoringFlags(cmd, &conf.MonitoringAddr, &conf.DebugAddr, "127.0.0.1:3620")
bindNoVerifyFlag(cmd.Flags(), &conf.NoVerify)
bindP2PFlags(cmd, &conf.P2P)
bindLogFlags(cmd.Flags(), &conf.Log)
Expand All @@ -70,8 +71,6 @@ func bindRunFlags(cmd *cobra.Command, config *app.Config) {
cmd.Flags().StringVar(&config.ManifestFile, "manifest-file", ".charon/cluster-manifest.pb", "The path to the cluster manifest file. If both cluster manifest and cluster lock files are provided, the cluster manifest file takes precedence.")
cmd.Flags().StringSliceVar(&config.BeaconNodeAddrs, "beacon-node-endpoints", nil, "Comma separated list of one or more beacon node endpoint URLs.")
cmd.Flags().StringVar(&config.ValidatorAPIAddr, "validator-api-address", "127.0.0.1:3600", "Listening address (ip and port) for validator-facing traffic proxying the beacon-node API.")
cmd.Flags().StringVar(&config.MonitoringAddr, "monitoring-address", "127.0.0.1:3620", "Listening address (ip and port) for the monitoring API (prometheus).")
cmd.Flags().StringVar(&config.DebugAddr, "debug-address", "", "Listening address (ip and port) for the pprof and QBFT debug API.")
cmd.Flags().StringVar(&config.JaegerAddr, "jaeger-address", "", "Listening address for jaeger tracing.")
cmd.Flags().StringVar(&config.JaegerService, "jaeger-service", "charon", "Service name used for jaeger tracing.")
cmd.Flags().BoolVar(&config.SimnetBMock, "simnet-beacon-mock", false, "Enables an internal mock beacon node for running a simnet.")
Expand Down

0 comments on commit eae73f0

Please sign in to comment.