Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/lovely-shrimps-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@eth-optimism/batch-submitter-service': patch
---

Refactors the bss-core service to use a metrics interface to allow
driver-specific metric extensions
8 changes: 4 additions & 4 deletions go/batch-submitter/drivers/proposer/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Driver struct {
rawSccContract *bind.BoundContract
ctcContract *ctc.CanonicalTransactionChain
walletAddr common.Address
metrics *metrics.Metrics
metrics *metrics.Base
}

func NewDriver(cfg Config) (*Driver, error) {
Expand Down Expand Up @@ -82,7 +82,7 @@ func NewDriver(cfg Config) (*Driver, error) {
rawSccContract: rawSccContract,
ctcContract: ctcContract,
walletAddr: walletAddr,
metrics: metrics.NewMetrics(cfg.Name),
metrics: metrics.NewBase("batch_submitter", cfg.Name),
}, nil
}

Expand All @@ -97,7 +97,7 @@ func (d *Driver) WalletAddr() common.Address {
}

// Metrics returns the subservice telemetry object.
func (d *Driver) Metrics() *metrics.Metrics {
func (d *Driver) Metrics() metrics.Metrics {
return d.metrics
}

Expand Down Expand Up @@ -184,7 +184,7 @@ func (d *Driver) CraftBatchTx(
stateRoots = append(stateRoots, block.Root())
}

d.metrics.NumElementsPerBatch.Observe(float64(len(stateRoots)))
d.metrics.NumElementsPerBatch().Observe(float64(len(stateRoots)))

log.Info(name+" batch constructed", "num_state_roots", len(stateRoots))

Expand Down
8 changes: 4 additions & 4 deletions go/batch-submitter/drivers/sequencer/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type Driver struct {
rawCtcContract *bind.BoundContract
walletAddr common.Address
ctcABI *abi.ABI
metrics *metrics.Metrics
metrics *Metrics
}

func NewDriver(cfg Config) (*Driver, error) {
Expand Down Expand Up @@ -80,7 +80,7 @@ func NewDriver(cfg Config) (*Driver, error) {
rawCtcContract: rawCtcContract,
walletAddr: walletAddr,
ctcABI: ctcABI,
metrics: metrics.NewMetrics(cfg.Name),
metrics: NewMetrics(cfg.Name),
}, nil
}

Expand All @@ -95,7 +95,7 @@ func (d *Driver) WalletAddr() common.Address {
}

// Metrics returns the subservice telemetry object.
func (d *Driver) Metrics() *metrics.Metrics {
func (d *Driver) Metrics() metrics.Metrics {
return d.metrics
}

Expand Down Expand Up @@ -219,7 +219,7 @@ func (d *Driver) CraftBatchTx(
continue
}

d.metrics.NumElementsPerBatch.Observe(float64(len(batchElements)))
d.metrics.NumElementsPerBatch().Observe(float64(len(batchElements)))
d.metrics.BatchPruneCount.Set(float64(pruneCount))

log.Info(name+" batch constructed", "num_txs", len(batchElements), "length", len(batchCallData))
Expand Down
30 changes: 30 additions & 0 deletions go/batch-submitter/drivers/sequencer/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package sequencer

import (
"github.com/ethereum-optimism/optimism/go/bss-core/metrics"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

// Metrics extends the BSS core metrics with additional metrics tracked by the
// sequencer driver.
type Metrics struct {
*metrics.Base

// BatchPruneCount tracks the number of times a batch of sequencer
// transactions is pruned in order to meet the desired size requirements.
BatchPruneCount prometheus.Gauge
}

// NewMetrics initializes a new, extended metrics object.
func NewMetrics(subsystem string) *Metrics {
base := metrics.NewBase("batch_submitter", subsystem)
return &Metrics{
Base: base,
BatchPruneCount: promauto.NewGauge(prometheus.GaugeOpts{
Name: "batch_prune_count",
Help: "Number of times a batch is pruned",
Subsystem: base.SubsystemName(),
}),
}
}
1 change: 1 addition & 0 deletions go/batch-submitter/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/ethereum-optimism/optimism/l2geth v1.0.0
github.com/ethereum/go-ethereum v1.10.16
github.com/getsentry/sentry-go v0.11.0
github.com/prometheus/client_golang v1.11.0
github.com/stretchr/testify v1.7.0
github.com/urfave/cli v1.22.5
)
Expand Down
38 changes: 38 additions & 0 deletions go/bss-core/metrics/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package metrics

import "github.com/prometheus/client_golang/prometheus"

type Metrics interface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these don't make much sense for the teleportr service, I think its going to be hard to define a perfectly abstract interface that could be used for metrics across all the services

// SubsystemName returns the subsystem name for the metrics group.
SubsystemName() string

// BalanceETH tracks the amount of ETH in the submitter's account.
BalanceETH() prometheus.Gauge

// BatchSizeBytes tracks the size of batch submission transactions.
BatchSizeBytes() prometheus.Summary

// NumElementsPerBatch tracks the number of L2 transactions in each batch
// submission.
NumElementsPerBatch() prometheus.Summary

// SubmissionTimestamp tracks the time at which each batch was confirmed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

batch -> transaction

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think batch is still accurate? We do have support for batched withdrawals. IMO "batch" is still correct, even in the degenerate case of 1 element

SubmissionTimestamp() prometheus.Gauge

// SubmissionGasUsedWei tracks the amount of gas used to submit each batch.
SubmissionGasUsedWei() prometheus.Gauge

// BatchsSubmitted tracks the total number of successful batch submissions.
BatchesSubmitted() prometheus.Counter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be transactions sent? and failed transactions?


// FailedSubmissions tracks the total number of failed batch submissions.
FailedSubmissions() prometheus.Counter

// BatchTxBuildTimeMs tracks the duration it takes to construct a batch
// transaction.
BatchTxBuildTimeMs() prometheus.Gauge

// BatchConfirmationTimeMs tracks the duration it takes to confirm a batch
// transaction.
BatchConfirmationTimeMs() prometheus.Gauge
}
158 changes: 116 additions & 42 deletions go/bss-core/metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -1,104 +1,178 @@
package metrics

import (
"fmt"
"strings"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

type Metrics struct {
// ETHBalance tracks the amount of ETH in the submitter's account.
ETHBalance prometheus.Gauge
type Base struct {
// subsystemName stores the name that will prefix all metrics. This can be
// used by drivers to futher extend the core metrics and ensure they use the
// same prefix.
subsystemName string

// BatchSizeInBytes tracks the size of batch submission transactions.
BatchSizeInBytes prometheus.Summary
// balanceETH tracks the amount of ETH in the submitter's account.
balanceETH prometheus.Gauge

// NumElementsPerBatch tracks the number of L2 transactions in each batch
// batchSizeBytes tracks the size of batch submission transactions.
batchSizeBytes prometheus.Summary

// numElementsPerBatch tracks the number of L2 transactions in each batch
// submission.
NumElementsPerBatch prometheus.Summary
numElementsPerBatch prometheus.Summary

// SubmissionTimestamp tracks the time at which each batch was confirmed.
SubmissionTimestamp prometheus.Gauge
// submissionTimestamp tracks the time at which each batch was confirmed.
submissionTimestamp prometheus.Gauge

// SubmissionGasUsed tracks the amount of gas used to submit each batch.
SubmissionGasUsed prometheus.Gauge
// submissionGasUsedWei tracks the amount of gas used to submit each batch.
submissionGasUsedWei prometheus.Gauge

// BatchsSubmitted tracks the total number of successful batch submissions.
BatchesSubmitted prometheus.Counter
// batchsSubmitted tracks the total number of successful batch submissions.
batchesSubmitted prometheus.Counter

// FailedSubmissions tracks the total number of failed batch submissions.
FailedSubmissions prometheus.Counter
// failedSubmissions tracks the total number of failed batch submissions.
failedSubmissions prometheus.Counter

// BatchTxBuildTime tracks the duration it takes to construct a batch
// batchTxBuildTimeMs tracks the duration it takes to construct a batch
// transaction.
BatchTxBuildTime prometheus.Gauge
batchTxBuildTimeMs prometheus.Gauge

// BatchConfirmationTime tracks the duration it takes to confirm a batch
// batchConfirmationTimeMs tracks the duration it takes to confirm a batch
// transaction.
BatchConfirmationTime prometheus.Gauge

// BatchPruneCount tracks the number of times a batch of sequencer
// transactions is pruned in order to meet the desired size requirements.
//
// NOTE: This is currently only active in the sequencer driver.
BatchPruneCount prometheus.Gauge
batchConfirmationTimeMs prometheus.Gauge
}

func NewMetrics(subsystem string) *Metrics {
subsystem = "batch_submitter_" + strings.ToLower(subsystem)
return &Metrics{
ETHBalance: promauto.NewGauge(prometheus.GaugeOpts{
func NewBase(serviceName, subServiceName string) *Base {
subsystem := MakeSubsystemName(serviceName, subServiceName)
return &Base{
subsystemName: subsystem,
balanceETH: promauto.NewGauge(prometheus.GaugeOpts{
Name: "balance_eth",
Help: "ETH balance of the batch submitter",
Subsystem: subsystem,
}),
BatchSizeInBytes: promauto.NewSummary(prometheus.SummaryOpts{
batchSizeBytes: promauto.NewSummary(prometheus.SummaryOpts{
Name: "batch_size_bytes",
Help: "Size of batches in bytes",
Subsystem: subsystem,
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
}),
NumElementsPerBatch: promauto.NewSummary(prometheus.SummaryOpts{
numElementsPerBatch: promauto.NewSummary(prometheus.SummaryOpts{
Name: "num_elements_per_batch",
Help: "Number of elements in each batch",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
Subsystem: subsystem,
}),
SubmissionTimestamp: promauto.NewGauge(prometheus.GaugeOpts{
submissionTimestamp: promauto.NewGauge(prometheus.GaugeOpts{
Name: "submission_timestamp_ms",
Help: "Timestamp of last batch submitter submission",
Subsystem: subsystem,
}),
SubmissionGasUsed: promauto.NewGauge(prometheus.GaugeOpts{
submissionGasUsedWei: promauto.NewGauge(prometheus.GaugeOpts{
Name: "submission_gas_used_wei",
Help: "Gas used to submit each batch",
Subsystem: subsystem,
}),
BatchesSubmitted: promauto.NewCounter(prometheus.CounterOpts{
batchesSubmitted: promauto.NewCounter(prometheus.CounterOpts{
Name: "batches_submitted",
Help: "Count of batches submitted",
Subsystem: subsystem,
}),
FailedSubmissions: promauto.NewCounter(prometheus.CounterOpts{
failedSubmissions: promauto.NewCounter(prometheus.CounterOpts{
Name: "failed_submissions",
Help: "Count of failed batch submissions",
Subsystem: subsystem,
}),
BatchTxBuildTime: promauto.NewGauge(prometheus.GaugeOpts{
batchTxBuildTimeMs: promauto.NewGauge(prometheus.GaugeOpts{
Name: "batch_tx_build_time_ms",
Help: "Time to construct batch transactions",
Subsystem: subsystem,
}),
BatchConfirmationTime: promauto.NewGauge(prometheus.GaugeOpts{
batchConfirmationTimeMs: promauto.NewGauge(prometheus.GaugeOpts{
Name: "batch_confirmation_time_ms",
Help: "Time to confirm batch transactions",
Subsystem: subsystem,
}),
BatchPruneCount: promauto.NewGauge(prometheus.GaugeOpts{
Name: "batch_prune_count",
Help: "Number of times a batch is pruned",
Subsystem: subsystem,
}),
}
}

// SubsystemName returns the subsystem name for the metrics group.
func (b *Base) SubsystemName() string {
return b.subsystemName
}

// BalanceETH tracks the amount of ETH in the submitter's account.
func (b *Base) BalanceETH() prometheus.Gauge {
return b.balanceETH
}

// BatchSizeBytes tracks the size of batch submission transactions.
func (b *Base) BatchSizeBytes() prometheus.Summary {
return b.batchSizeBytes
}

// NumElementsPerBatch tracks the number of L2 transactions in each batch
// submission.
func (b *Base) NumElementsPerBatch() prometheus.Summary {
return b.numElementsPerBatch
}

// SubmissionTimestamp tracks the time at which each batch was confirmed.
func (b *Base) SubmissionTimestamp() prometheus.Gauge {
return b.submissionTimestamp
}

// SubmissionGasUsedWei tracks the amount of gas used to submit each batch.
func (b *Base) SubmissionGasUsedWei() prometheus.Gauge {
return b.submissionGasUsedWei
}

// BatchsSubmitted tracks the total number of successful batch submissions.
func (b *Base) BatchesSubmitted() prometheus.Counter {
return b.batchesSubmitted
}

// FailedSubmissions tracks the total number of failed batch submissions.
func (b *Base) FailedSubmissions() prometheus.Counter {
return b.failedSubmissions
}

// BatchTxBuildTimeMs tracks the duration it takes to construct a batch
// transaction.
func (b *Base) BatchTxBuildTimeMs() prometheus.Gauge {
return b.batchTxBuildTimeMs
}

// BatchConfirmationTimeMs tracks the duration it takes to confirm a batch
// transaction.
func (b *Base) BatchConfirmationTimeMs() prometheus.Gauge {
return b.batchConfirmationTimeMs
}

// MakeSubsystemName builds the subsystem name for a group of metrics, which
// prometheus will use to prefix all metrics in the group. If two non-empty
// strings are provided, they are joined with an underscore. If only one
// non-empty string is provided, that name will be used alone. Otherwise an
// empty string is returned after converting the characters to lower case.
//
// NOTE: This method panics if spaces are included in either string.
func MakeSubsystemName(serviceName string, subServiceName string) string {
var subsystem string
switch {
case serviceName != "" && subServiceName != "":
subsystem = fmt.Sprintf("%s_%s", serviceName, subServiceName)
case serviceName != "":
subsystem = serviceName
default:
subsystem = subServiceName
}

if strings.ContainsAny(subsystem, " ") {
panic(fmt.Sprintf("metrics name \"%s\"cannot have spaces", subsystem))
}

return strings.ToLower(subsystem)
}
Loading