mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-13 15:33:47 +00:00
implementation of metrics influx, influxV2 and local web server
This commit is contained in:
parent
8e8f85a32d
commit
8054d16b26
4 changed files with 211 additions and 20 deletions
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover/portalwire"
|
"github.com/ethereum/go-ethereum/p2p/discover/portalwire"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
|
@ -79,11 +80,26 @@ var (
|
||||||
utils.PortalDataCapacityFlag,
|
utils.PortalDataCapacityFlag,
|
||||||
utils.PortalLogLevelFlag,
|
utils.PortalLogLevelFlag,
|
||||||
}
|
}
|
||||||
|
metricsFlags = []cli.Flag{
|
||||||
|
utils.PortalMetricsEnabledFlag,
|
||||||
|
utils.PortalMetricsHTTPFlag,
|
||||||
|
utils.PortalMetricsPortFlag,
|
||||||
|
utils.PortalMetricsEnableInfluxDBFlag,
|
||||||
|
utils.PortalMetricsInfluxDBEndpointFlag,
|
||||||
|
utils.PortalMetricsInfluxDBDatabaseFlag,
|
||||||
|
utils.PortalMetricsInfluxDBUsernameFlag,
|
||||||
|
utils.PortalMetricsInfluxDBPasswordFlag,
|
||||||
|
utils.PortalMetricsInfluxDBTagsFlag,
|
||||||
|
utils.PortalMetricsEnableInfluxDBV2Flag,
|
||||||
|
utils.PortalMetricsInfluxDBTokenFlag,
|
||||||
|
utils.PortalMetricsInfluxDBBucketFlag,
|
||||||
|
utils.PortalMetricsInfluxDBOrganizationFlag,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
app.Action = shisui
|
app.Action = shisui
|
||||||
app.Flags = flags.Merge(portalProtocolFlags, historyRpcFlags)
|
app.Flags = flags.Merge(portalProtocolFlags, historyRpcFlags, metricsFlags)
|
||||||
flags.AutoEnvVars(app.Flags, "SHISUI")
|
flags.AutoEnvVars(app.Flags, "SHISUI")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,6 +113,12 @@ func main() {
|
||||||
func shisui(ctx *cli.Context) error {
|
func shisui(ctx *cli.Context) error {
|
||||||
setDefaultLogger(ctx.Int(utils.PortalLogLevelFlag.Name))
|
setDefaultLogger(ctx.Int(utils.PortalLogLevelFlag.Name))
|
||||||
|
|
||||||
|
// Start metrics export if enabled
|
||||||
|
utils.PortalSetupMetrics(ctx)
|
||||||
|
|
||||||
|
// Start system runtime metrics collection
|
||||||
|
go metrics.CollectProcessMetrics(3 * time.Second)
|
||||||
|
|
||||||
config, err := getPortalConfig(ctx)
|
config, err := getPortalConfig(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -1026,6 +1026,93 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
|
||||||
Category: flags.PortalNetworkCategory,
|
Category: flags.PortalNetworkCategory,
|
||||||
Value: cli.NewStringSlice(portalwire.History.Name()),
|
Value: cli.NewStringSlice(portalwire.History.Name()),
|
||||||
}
|
}
|
||||||
|
// Metrics flags for shisui
|
||||||
|
PortalMetricsEnabledFlag = &cli.BoolFlag{
|
||||||
|
Name: "metrics",
|
||||||
|
Usage: "Enable metrics collection and reporting",
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
// 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.
|
||||||
|
PortalMetricsHTTPFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.addr",
|
||||||
|
Usage: `Enable stand-alone metrics HTTP server listening interface.`,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
PortalMetricsPortFlag = &cli.IntFlag{
|
||||||
|
Name: "metrics.port",
|
||||||
|
Usage: `Metrics HTTP server listening port.
|
||||||
|
Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.`,
|
||||||
|
Value: metrics.ShisuiDefaultConfig.Port,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
PortalMetricsEnableInfluxDBFlag = &cli.BoolFlag{
|
||||||
|
Name: "metrics.influxdb",
|
||||||
|
Usage: "Enable metrics export/push to an external InfluxDB database",
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
PortalMetricsInfluxDBEndpointFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.endpoint",
|
||||||
|
Usage: "InfluxDB API endpoint to report metrics to",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBEndpoint,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
PortalMetricsInfluxDBDatabaseFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.database",
|
||||||
|
Usage: "InfluxDB database name to push reported metrics to",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBDatabase,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
PortalMetricsInfluxDBUsernameFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.username",
|
||||||
|
Usage: "Username to authorize access to the database",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBUsername,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
PortalMetricsInfluxDBPasswordFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.password",
|
||||||
|
Usage: "Password to authorize access to the database",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBPassword,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
// Tags are part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB.
|
||||||
|
// For example `host` tag could be used so that we can group all nodes and average a measurement
|
||||||
|
// across all of them, but also so that we can select a specific node and inspect its measurements.
|
||||||
|
// https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key
|
||||||
|
PortalMetricsInfluxDBTagsFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.tags",
|
||||||
|
Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBTags,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
|
||||||
|
PortalMetricsEnableInfluxDBV2Flag = &cli.BoolFlag{
|
||||||
|
Name: "metrics.influxdbv2",
|
||||||
|
Usage: "Enable metrics export/push to an external InfluxDB v2 database",
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
PortalMetricsInfluxDBTokenFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.token",
|
||||||
|
Usage: "Token to authorize access to the database (v2 only)",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBToken,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
|
||||||
|
PortalMetricsInfluxDBBucketFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.bucket",
|
||||||
|
Usage: "InfluxDB bucket name to push reported metrics to (v2 only)",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBBucket,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
|
|
||||||
|
PortalMetricsInfluxDBOrganizationFlag = &cli.StringFlag{
|
||||||
|
Name: "metrics.influxdb.organization",
|
||||||
|
Usage: "InfluxDB organization name (v2 only)",
|
||||||
|
Value: metrics.ShisuiDefaultConfig.InfluxDBOrganization,
|
||||||
|
Category: flags.PortalNetworkMetricsCategory,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -2042,6 +2129,67 @@ func RegisterFullSyncTester(stack *node.Node, eth *eth.Ethereum, target common.H
|
||||||
log.Info("Registered full-sync tester", "hash", target)
|
log.Info("Registered full-sync tester", "hash", target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PortalSetupMetrics(ctx *cli.Context) {
|
||||||
|
if metrics.Enabled {
|
||||||
|
log.Info("Enabling metrics collection")
|
||||||
|
|
||||||
|
var (
|
||||||
|
enableExport = ctx.Bool(PortalMetricsEnableInfluxDBFlag.Name)
|
||||||
|
enableExportV2 = ctx.Bool(PortalMetricsEnableInfluxDBV2Flag.Name)
|
||||||
|
)
|
||||||
|
|
||||||
|
if enableExport || enableExportV2 {
|
||||||
|
CheckExclusive(ctx, PortalMetricsEnableInfluxDBFlag, PortalMetricsEnableInfluxDBV2Flag)
|
||||||
|
|
||||||
|
v1FlagIsSet := ctx.IsSet(PortalMetricsInfluxDBUsernameFlag.Name) ||
|
||||||
|
ctx.IsSet(PortalMetricsInfluxDBPasswordFlag.Name)
|
||||||
|
|
||||||
|
v2FlagIsSet := ctx.IsSet(PortalMetricsInfluxDBTokenFlag.Name) ||
|
||||||
|
ctx.IsSet(PortalMetricsInfluxDBOrganizationFlag.Name) ||
|
||||||
|
ctx.IsSet(PortalMetricsInfluxDBBucketFlag.Name)
|
||||||
|
|
||||||
|
if enableExport && v2FlagIsSet {
|
||||||
|
Fatalf("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2")
|
||||||
|
} else if enableExportV2 && v1FlagIsSet {
|
||||||
|
Fatalf("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
endpoint = ctx.String(PortalMetricsInfluxDBEndpointFlag.Name)
|
||||||
|
database = ctx.String(PortalMetricsInfluxDBDatabaseFlag.Name)
|
||||||
|
username = ctx.String(PortalMetricsInfluxDBUsernameFlag.Name)
|
||||||
|
password = ctx.String(PortalMetricsInfluxDBPasswordFlag.Name)
|
||||||
|
|
||||||
|
token = ctx.String(PortalMetricsInfluxDBTokenFlag.Name)
|
||||||
|
bucket = ctx.String(PortalMetricsInfluxDBBucketFlag.Name)
|
||||||
|
organization = ctx.String(PortalMetricsInfluxDBOrganizationFlag.Name)
|
||||||
|
)
|
||||||
|
|
||||||
|
if enableExport {
|
||||||
|
tagsMap := SplitTagsFlag(ctx.String(PortalMetricsInfluxDBTagsFlag.Name))
|
||||||
|
|
||||||
|
log.Info("Enabling metrics export to InfluxDB")
|
||||||
|
|
||||||
|
go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", tagsMap)
|
||||||
|
} else if enableExportV2 {
|
||||||
|
tagsMap := SplitTagsFlag(ctx.String(PortalMetricsInfluxDBTagsFlag.Name))
|
||||||
|
|
||||||
|
log.Info("Enabling metrics export to InfluxDB (v2)")
|
||||||
|
|
||||||
|
go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, token, bucket, organization, "geth.", tagsMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.IsSet(PortalMetricsHTTPFlag.Name) {
|
||||||
|
address := net.JoinHostPort(ctx.String(PortalMetricsHTTPFlag.Name), fmt.Sprintf("%d", ctx.Int(PortalMetricsPortFlag.Name)))
|
||||||
|
log.Info("Enabling stand-alone metrics HTTP endpoint", "address", address)
|
||||||
|
exp.Setup(address)
|
||||||
|
} else if ctx.IsSet(PortalMetricsPortFlag.Name) {
|
||||||
|
log.Warn(fmt.Sprintf("--%s specified without --%s, metrics server will not start.", PortalMetricsPortFlag.Name, PortalMetricsHTTPFlag.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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")
|
||||||
|
|
|
||||||
|
|
@ -19,25 +19,26 @@ package flags
|
||||||
import "github.com/urfave/cli/v2"
|
import "github.com/urfave/cli/v2"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
EthCategory = "ETHEREUM"
|
EthCategory = "ETHEREUM"
|
||||||
BeaconCategory = "BEACON CHAIN"
|
BeaconCategory = "BEACON CHAIN"
|
||||||
DevCategory = "DEVELOPER CHAIN"
|
DevCategory = "DEVELOPER CHAIN"
|
||||||
StateCategory = "STATE HISTORY MANAGEMENT"
|
StateCategory = "STATE HISTORY MANAGEMENT"
|
||||||
TxPoolCategory = "TRANSACTION POOL (EVM)"
|
TxPoolCategory = "TRANSACTION POOL (EVM)"
|
||||||
BlobPoolCategory = "TRANSACTION POOL (BLOB)"
|
BlobPoolCategory = "TRANSACTION POOL (BLOB)"
|
||||||
PerfCategory = "PERFORMANCE TUNING"
|
PerfCategory = "PERFORMANCE TUNING"
|
||||||
AccountCategory = "ACCOUNT"
|
AccountCategory = "ACCOUNT"
|
||||||
APICategory = "API AND CONSOLE"
|
APICategory = "API AND CONSOLE"
|
||||||
NetworkingCategory = "NETWORKING"
|
NetworkingCategory = "NETWORKING"
|
||||||
MinerCategory = "MINER"
|
MinerCategory = "MINER"
|
||||||
GasPriceCategory = "GAS PRICE ORACLE"
|
GasPriceCategory = "GAS PRICE ORACLE"
|
||||||
VMCategory = "VIRTUAL MACHINE"
|
VMCategory = "VIRTUAL MACHINE"
|
||||||
LoggingCategory = "LOGGING AND DEBUGGING"
|
LoggingCategory = "LOGGING AND DEBUGGING"
|
||||||
MetricsCategory = "METRICS AND STATS"
|
MetricsCategory = "METRICS AND STATS"
|
||||||
MiscCategory = "MISC"
|
MiscCategory = "MISC"
|
||||||
TestingCategory = "TESTING"
|
TestingCategory = "TESTING"
|
||||||
DeprecatedCategory = "ALIASED (deprecated)"
|
DeprecatedCategory = "ALIASED (deprecated)"
|
||||||
PortalNetworkCategory = "PORTAL NETWORK"
|
PortalNetworkCategory = "PORTAL NETWORK"
|
||||||
|
PortalNetworkMetricsCategory = "PORTAL NETWORK METRICS"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
||||||
|
|
@ -54,3 +54,23 @@ var DefaultConfig = Config{
|
||||||
InfluxDBBucket: "geth",
|
InfluxDBBucket: "geth",
|
||||||
InfluxDBOrganization: "geth",
|
InfluxDBOrganization: "geth",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShisuiDefaultConfig is the default config for metrics used in shisui.
|
||||||
|
var ShisuiDefaultConfig = Config{
|
||||||
|
Enabled: false,
|
||||||
|
EnabledExpensive: false,
|
||||||
|
HTTP: "127.0.0.1",
|
||||||
|
Port: 6060,
|
||||||
|
EnableInfluxDB: false,
|
||||||
|
InfluxDBEndpoint: "http://localhost:8086",
|
||||||
|
InfluxDBDatabase: "shisui",
|
||||||
|
InfluxDBUsername: "test",
|
||||||
|
InfluxDBPassword: "test",
|
||||||
|
InfluxDBTags: "host=localhost",
|
||||||
|
|
||||||
|
// influxdbv2-specific flags
|
||||||
|
EnableInfluxDBV2: false,
|
||||||
|
InfluxDBToken: "test",
|
||||||
|
InfluxDBBucket: "shisui",
|
||||||
|
InfluxDBOrganization: "shisui",
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue