forked from cerc-io/plugeth
cmd/geth: allow configuring metrics HTTP server on separate endpoint (#21290)
Exposing /debug/metrics and /debug/metrics/prometheus was dependent on --pprof, which also exposes other HTTP APIs. This change makes it possible to run the metrics server on an independent endpoint without enabling pprof.
This commit is contained in:
parent
61270e5e1c
commit
490b380a04
@ -85,6 +85,8 @@ The dumpgenesis command dumps the genesis block configuration in JSON format to
|
|||||||
utils.CacheGCFlag,
|
utils.CacheGCFlag,
|
||||||
utils.MetricsEnabledFlag,
|
utils.MetricsEnabledFlag,
|
||||||
utils.MetricsEnabledExpensiveFlag,
|
utils.MetricsEnabledExpensiveFlag,
|
||||||
|
utils.MetricsHTTPFlag,
|
||||||
|
utils.MetricsPortFlag,
|
||||||
utils.MetricsEnableInfluxDBFlag,
|
utils.MetricsEnableInfluxDBFlag,
|
||||||
utils.MetricsInfluxDBEndpointFlag,
|
utils.MetricsInfluxDBEndpointFlag,
|
||||||
utils.MetricsInfluxDBDatabaseFlag,
|
utils.MetricsInfluxDBDatabaseFlag,
|
||||||
|
@ -199,6 +199,8 @@ var (
|
|||||||
metricsFlags = []cli.Flag{
|
metricsFlags = []cli.Flag{
|
||||||
utils.MetricsEnabledFlag,
|
utils.MetricsEnabledFlag,
|
||||||
utils.MetricsEnabledExpensiveFlag,
|
utils.MetricsEnabledExpensiveFlag,
|
||||||
|
utils.MetricsHTTPFlag,
|
||||||
|
utils.MetricsPortFlag,
|
||||||
utils.MetricsEnableInfluxDBFlag,
|
utils.MetricsEnableInfluxDBFlag,
|
||||||
utils.MetricsInfluxDBEndpointFlag,
|
utils.MetricsInfluxDBEndpointFlag,
|
||||||
utils.MetricsInfluxDBDatabaseFlag,
|
utils.MetricsInfluxDBDatabaseFlag,
|
||||||
|
@ -51,6 +51,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/les"
|
"github.com/ethereum/go-ethereum/les"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
"github.com/ethereum/go-ethereum/metrics/exp"
|
||||||
"github.com/ethereum/go-ethereum/metrics/influxdb"
|
"github.com/ethereum/go-ethereum/metrics/influxdb"
|
||||||
"github.com/ethereum/go-ethereum/miner"
|
"github.com/ethereum/go-ethereum/miner"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
@ -689,6 +690,21 @@ var (
|
|||||||
Name: "metrics.expensive",
|
Name: "metrics.expensive",
|
||||||
Usage: "Enable expensive metrics collection and reporting",
|
Usage: "Enable expensive metrics collection and reporting",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MetricsHTTPFlag defines the endpoint for a stand-alone metrics HTTP endpoint.
|
||||||
|
// Since the pprof service enables sensitive/vulnerable behavior, this allows a user
|
||||||
|
// to enable a public-OK metrics endpoint without having to worry about ALSO exposing
|
||||||
|
// other profiling behavior or information.
|
||||||
|
MetricsHTTPFlag = cli.StringFlag{
|
||||||
|
Name: "metrics.addr",
|
||||||
|
Usage: "Enable stand-alone metrics HTTP server listening interface",
|
||||||
|
Value: "127.0.0.1",
|
||||||
|
}
|
||||||
|
MetricsPortFlag = cli.IntFlag{
|
||||||
|
Name: "metrics.port",
|
||||||
|
Usage: "Metrics HTTP server listening port",
|
||||||
|
Value: 6060,
|
||||||
|
}
|
||||||
MetricsEnableInfluxDBFlag = cli.BoolFlag{
|
MetricsEnableInfluxDBFlag = cli.BoolFlag{
|
||||||
Name: "metrics.influxdb",
|
Name: "metrics.influxdb",
|
||||||
Usage: "Enable metrics export/push to an external InfluxDB database",
|
Usage: "Enable metrics export/push to an external InfluxDB database",
|
||||||
@ -1734,6 +1750,7 @@ func RegisterGraphQLService(stack *node.Node, endpoint string, cors, vhosts []st
|
|||||||
func SetupMetrics(ctx *cli.Context) {
|
func SetupMetrics(ctx *cli.Context) {
|
||||||
if metrics.Enabled {
|
if metrics.Enabled {
|
||||||
log.Info("Enabling metrics collection")
|
log.Info("Enabling metrics collection")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
|
enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name)
|
||||||
endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
|
endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name)
|
||||||
@ -1749,6 +1766,12 @@ func SetupMetrics(ctx *cli.Context) {
|
|||||||
|
|
||||||
go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
|
go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.GlobalIsSet(MetricsHTTPFlag.Name) {
|
||||||
|
address := fmt.Sprintf("%s:%d", ctx.GlobalString(MetricsHTTPFlag.Name), ctx.GlobalInt(MetricsPortFlag.Name))
|
||||||
|
log.Info("Enabling stand-alone metrics HTTP endpoint", "address", address)
|
||||||
|
exp.Setup(address)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,15 +195,19 @@ func Setup(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
address := fmt.Sprintf("%s:%d", listenHost, port)
|
address := fmt.Sprintf("%s:%d", listenHost, port)
|
||||||
StartPProf(address)
|
// This context value ("metrics.addr") represents the utils.MetricsHTTPFlag.Name.
|
||||||
|
// It cannot be imported because it will cause a cyclical dependency.
|
||||||
|
StartPProf(address, !ctx.GlobalIsSet("metrics.addr"))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartPProf(address string) {
|
func StartPProf(address string, withMetrics bool) {
|
||||||
// Hook go-metrics into expvar on any /debug/metrics request, load all vars
|
// Hook go-metrics into expvar on any /debug/metrics request, load all vars
|
||||||
// from the registry into expvar, and execute regular expvar handler.
|
// from the registry into expvar, and execute regular expvar handler.
|
||||||
exp.Exp(metrics.DefaultRegistry)
|
if withMetrics {
|
||||||
|
exp.Exp(metrics.DefaultRegistry)
|
||||||
|
}
|
||||||
http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize))
|
http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize))
|
||||||
log.Info("Starting pprof server", "addr", fmt.Sprintf("http://%s/debug/pprof", address))
|
log.Info("Starting pprof server", "addr", fmt.Sprintf("http://%s/debug/pprof", address))
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
"github.com/ethereum/go-ethereum/metrics/prometheus"
|
"github.com/ethereum/go-ethereum/metrics/prometheus"
|
||||||
)
|
)
|
||||||
@ -52,6 +53,20 @@ func ExpHandler(r metrics.Registry) http.Handler {
|
|||||||
return http.HandlerFunc(e.expHandler)
|
return http.HandlerFunc(e.expHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup starts a dedicated metrics server at the given address.
|
||||||
|
// This function enables metrics reporting separate from pprof.
|
||||||
|
func Setup(address string) {
|
||||||
|
m := http.NewServeMux()
|
||||||
|
m.Handle("/debug/metrics", ExpHandler(metrics.DefaultRegistry))
|
||||||
|
m.Handle("/debug/metrics/prometheus", prometheus.Handler(metrics.DefaultRegistry))
|
||||||
|
log.Info("Starting metrics server", "addr", fmt.Sprintf("http://%s/debug/metrics", address))
|
||||||
|
go func() {
|
||||||
|
if err := http.ListenAndServe(address, m); err != nil {
|
||||||
|
log.Error("Failure in running metrics server", "err", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
func (exp *exp) getInt(name string) *expvar.Int {
|
func (exp *exp) getInt(name string) *expvar.Int {
|
||||||
var v *expvar.Int
|
var v *expvar.Int
|
||||||
exp.expvarLock.Lock()
|
exp.expvarLock.Lock()
|
||||||
|
@ -113,7 +113,7 @@ func NewNode(datadir string, config *NodeConfig) (stack *Node, _ error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.PprofAddress != "" {
|
if config.PprofAddress != "" {
|
||||||
debug.StartPProf(config.PprofAddress)
|
debug.StartPProf(config.PprofAddress, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the empty networking stack
|
// Create the empty networking stack
|
||||||
|
Loading…
Reference in New Issue
Block a user