Commit c6e6f6e8 authored by OptimismBot's avatar OptimismBot Committed by GitHub

Merge pull request #6911 from ethereum-optimism/jg/challenger_metrics

op-challenger: Add basic metrics & pprof setup
parents 7b30659f ba939af9
......@@ -68,7 +68,7 @@ func Main(version string, cliCtx *cli.Context) error {
l.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort)
go func() {
if err := m.Serve(ctx, metricsCfg.ListenAddr, metricsCfg.ListenPort); err != nil {
l.Error("error starting metrics server", err)
l.Error("error starting metrics server", "err", err)
}
}()
m.StartBalanceMetrics(ctx, l, batchSubmitter.L1Client, batchSubmitter.TxManager.From())
......
......@@ -5,6 +5,8 @@ import (
"fmt"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
)
......@@ -105,7 +107,9 @@ type Config struct {
CannonL2 string // L2 RPC Url
CannonSnapshotFreq uint // Frequency of snapshots to create when executing cannon (in VM instructions)
TxMgrConfig txmgr.CLIConfig
TxMgrConfig txmgr.CLIConfig
MetricsConfig opmetrics.CLIConfig
PprofConfig oppprof.CLIConfig
}
func NewConfig(
......@@ -122,7 +126,9 @@ func NewConfig(
TraceType: traceType,
TxMgrConfig: txmgr.NewCLIConfig(l1EthRpc),
TxMgrConfig: txmgr.NewCLIConfig(l1EthRpc),
MetricsConfig: opmetrics.DefaultCLIConfig(),
PprofConfig: oppprof.DefaultCLIConfig(),
CannonSnapshotFreq: DefaultCannonSnapshotFreq,
}
......@@ -182,5 +188,11 @@ func (c Config) Check() error {
if err := c.TxMgrConfig.Check(); err != nil {
return err
}
if err := c.MetricsConfig.Check(); err != nil {
return err
}
if err := c.PprofConfig.Check(); err != nil {
return err
}
return nil
}
......@@ -8,9 +8,11 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/version"
"github.com/ethereum-optimism/optimism/op-service/client"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
......@@ -25,12 +27,14 @@ type Service interface {
type service struct {
logger log.Logger
metrics metrics.Metricer
monitor *gameMonitor
}
// NewService creates a new Service.
func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*service, error) {
txMgr, err := txmgr.NewSimpleTxManager("challenger", logger, &metrics.NoopTxMetrics{}, cfg.TxMgrConfig)
m := metrics.NewMetrics()
txMgr, err := txmgr.NewSimpleTxManager("challenger", logger, &m.TxMetrics, cfg.TxMgrConfig)
if err != nil {
return nil, fmt.Errorf("failed to create the transaction manager: %w", err)
}
......@@ -40,6 +44,27 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
return nil, fmt.Errorf("failed to dial L1: %w", err)
}
pprofConfig := cfg.PprofConfig
if pprofConfig.Enabled {
logger.Info("starting pprof", "addr", pprofConfig.ListenAddr, "port", pprofConfig.ListenPort)
go func() {
if err := oppprof.ListenAndServe(ctx, pprofConfig.ListenAddr, pprofConfig.ListenPort); err != nil {
logger.Error("error starting pprof", "err", err)
}
}()
}
metricsCfg := cfg.MetricsConfig
if metricsCfg.Enabled {
logger.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort)
go func() {
if err := m.Serve(ctx, metricsCfg.ListenAddr, metricsCfg.ListenPort); err != nil {
logger.Error("error starting metrics server", "err", err)
}
}()
m.StartBalanceMetrics(ctx, logger, client, txMgr.From())
}
factory, err := bindings.NewDisputeGameFactory(cfg.GameFactoryAddress, client)
if err != nil {
return nil, fmt.Errorf("failed to bind the fault dispute game factory contract: %w", err)
......@@ -49,9 +74,14 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
monitor := newGameMonitor(logger, client.BlockNumber, cfg.GameAddress, loader, func(addr common.Address) (gamePlayer, error) {
return NewGamePlayer(ctx, logger, cfg, addr, txMgr, client)
})
m.RecordInfo(version.SimpleWithMeta)
m.RecordUp()
return &service{
monitor: monitor,
logger: logger,
metrics: m,
monitor: monitor,
}, nil
}
......
......@@ -9,6 +9,8 @@ import (
opservice "github.com/ethereum-optimism/optimism/op-service"
openum "github.com/ethereum-optimism/optimism/op-service/enum"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
oppprof "github.com/ethereum-optimism/optimism/op-service/pprof"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
......@@ -134,6 +136,8 @@ var optionalFlags = []cli.Flag{
func init() {
optionalFlags = append(optionalFlags, oplog.CLIFlags(envVarPrefix)...)
optionalFlags = append(optionalFlags, txmgr.CLIFlags(envVarPrefix)...)
optionalFlags = append(optionalFlags, opmetrics.CLIFlags(envVarPrefix)...)
optionalFlags = append(optionalFlags, oppprof.CLIFlags(envVarPrefix)...)
Flags = append(requiredFlags, optionalFlags...)
}
......@@ -201,6 +205,8 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
}
txMgrConfig := txmgr.ReadCLIConfig(ctx)
metricsConfig := opmetrics.ReadCLIConfig(ctx)
pprofConfig := oppprof.ReadCLIConfig(ctx)
traceTypeFlag := config.TraceType(strings.ToLower(ctx.String(TraceTypeFlag.Name)))
......@@ -222,5 +228,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
CannonSnapshotFreq: ctx.Uint(CannonSnapshotFreqFlag.Name),
AgreeWithProposedOutput: ctx.Bool(AgreeWithProposedOutputFlag.Name),
TxMgrConfig: txMgrConfig,
MetricsConfig: metricsConfig,
PprofConfig: pprofConfig,
}, nil
}
package metrics
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/prometheus/client_golang/prometheus"
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
)
const Namespace = "op_challenger"
type Metricer interface {
RecordInfo(version string)
RecordUp()
// Record Tx metrics
txmetrics.TxMetricer
}
type Metrics struct {
ns string
registry *prometheus.Registry
factory opmetrics.Factory
txmetrics.TxMetrics
info prometheus.GaugeVec
up prometheus.Gauge
}
var _ Metricer = (*Metrics)(nil)
func NewMetrics() *Metrics {
registry := opmetrics.NewRegistry()
factory := opmetrics.With(registry)
return &Metrics{
ns: Namespace,
registry: registry,
factory: factory,
TxMetrics: txmetrics.MakeTxMetrics(Namespace, factory),
info: *factory.NewGaugeVec(prometheus.GaugeOpts{
Namespace: Namespace,
Name: "info",
Help: "Pseudo-metric tracking version and config info",
}, []string{
"version",
}),
up: factory.NewGauge(prometheus.GaugeOpts{
Namespace: Namespace,
Name: "up",
Help: "1 if the op-challenger has finished starting up",
}),
}
}
func (m *Metrics) Serve(ctx context.Context, host string, port int) error {
return opmetrics.ListenAndServe(ctx, m.registry, host, port)
}
func (m *Metrics) StartBalanceMetrics(ctx context.Context, l log.Logger, client *ethclient.Client, account common.Address) {
opmetrics.LaunchBalanceMetrics(ctx, l, m.registry, m.ns, client, account)
}
// RecordInfo sets a pseudo-metric that contains versioning and
// config info for the op-proposer.
func (m *Metrics) RecordInfo(version string) {
m.info.WithLabelValues(version).Set(1)
}
// RecordUp sets the up metric to 1.
func (m *Metrics) RecordUp() {
prometheus.MustRegister()
m.up.Set(1)
}
func (m *Metrics) Document() []opmetrics.DocumentedMetric {
return m.factory.Document()
}
package metrics
import (
txmetrics "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics"
)
type noopMetrics struct {
txmetrics.NoopTxMetrics
}
var NoopMetrics Metricer = new(noopMetrics)
func (*noopMetrics) RecordInfo(version string) {}
func (*noopMetrics) RecordUp() {}
......@@ -27,4 +27,6 @@ $CHALLENGER_DIR/bin/op-challenger \
--game-address $FAULT_GAME_ADDRESS \
--private-key $CHARLIE_KEY \
--num-confirmations 1 \
--metrics.enabled --metrics.port=7304 \
--pprof.enabled --pprof.port=6064 \
--agree-with-proposed-output=true
......@@ -27,4 +27,6 @@ $CHALLENGER_DIR/bin/op-challenger \
--game-address $FAULT_GAME_ADDRESS \
--private-key $MALLORY_KEY \
--num-confirmations 1 \
--metrics.enabled --metrics.port=7305 \
--pprof.enabled --pprof.port=6065 \
--agree-with-proposed-output=false
......@@ -4,3 +4,11 @@ var (
Version = "v0.1.0"
Meta = "dev"
)
var SimpleWithMeta = func() string {
v := Version
if Meta != "" {
v += "-" + Meta
}
return v
}()
......@@ -85,7 +85,7 @@ func Main(version string, cliCtx *cli.Context) error {
l.Info("starting metrics server", "addr", metricsCfg.ListenAddr, "port", metricsCfg.ListenPort)
go func() {
if err := m.Serve(ctx, metricsCfg.ListenAddr, metricsCfg.ListenPort); err != nil {
l.Error("error starting metrics server", err)
l.Error("error starting metrics server", "err", err)
}
}()
m.StartBalanceMetrics(ctx, l, proposerConfig.L1Client, proposerConfig.TxManager.From())
......
......@@ -13,8 +13,18 @@ const (
EnabledFlagName = "metrics.enabled"
ListenAddrFlagName = "metrics.addr"
PortFlagName = "metrics.port"
defaultListenAddr = "0.0.0.0"
defaultListenPort = 7300
)
func DefaultCLIConfig() CLIConfig {
return CLIConfig{
Enabled: false,
ListenAddr: defaultListenAddr,
ListenPort: defaultListenPort,
}
}
func CLIFlags(envPrefix string) []cli.Flag {
return []cli.Flag{
&cli.BoolFlag{
......@@ -25,13 +35,13 @@ func CLIFlags(envPrefix string) []cli.Flag {
&cli.StringFlag{
Name: ListenAddrFlagName,
Usage: "Metrics listening address",
Value: "0.0.0.0", // TODO(CLI-4159): Switch to 127.0.0.1
Value: defaultListenAddr, // TODO(CLI-4159): Switch to 127.0.0.1
EnvVars: opservice.PrefixEnvVar(envPrefix, "METRICS_ADDR"),
},
&cli.IntFlag{
Name: PortFlagName,
Usage: "Metrics listening port",
Value: 7300,
Value: defaultListenPort,
EnvVars: opservice.PrefixEnvVar(envPrefix, "METRICS_PORT"),
},
}
......
......@@ -12,8 +12,18 @@ const (
EnabledFlagName = "pprof.enabled"
ListenAddrFlagName = "pprof.addr"
PortFlagName = "pprof.port"
defaultListenAddr = "0.0.0.0"
defaultListenPort = 6060
)
func DefaultCLIConfig() CLIConfig {
return CLIConfig{
Enabled: false,
ListenAddr: defaultListenAddr,
ListenPort: defaultListenPort,
}
}
func CLIFlags(envPrefix string) []cli.Flag {
return []cli.Flag{
&cli.BoolFlag{
......@@ -24,13 +34,13 @@ func CLIFlags(envPrefix string) []cli.Flag {
&cli.StringFlag{
Name: ListenAddrFlagName,
Usage: "pprof listening address",
Value: "0.0.0.0", // TODO(CLI-4159): Switch to 127.0.0.1
Value: defaultListenAddr, // TODO(CLI-4159): Switch to 127.0.0.1
EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_ADDR"),
},
&cli.IntFlag{
Name: PortFlagName,
Usage: "pprof listening port",
Value: 6060,
Value: defaultListenPort,
EnvVars: opservice.PrefixEnvVar(envPrefix, "PPROF_PORT"),
},
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment