diff --git a/da/da.go b/da/da.go index d30a13c..5ee571f 100644 --- a/da/da.go +++ b/da/da.go @@ -80,6 +80,8 @@ type BaseResult struct { Message string // DAHeight informs about a height on Data Availability Layer for given result. DAHeight uint64 + // BlobSize is the size of the blob submitted. + BlobSize uint64 // SubmittedCount is the number of successfully submitted blocks. SubmittedCount uint64 } @@ -192,6 +194,7 @@ func (dac *DAClient) SubmitBatch(ctx context.Context, data []*sequencing.Batch, BaseResult: BaseResult{ Code: StatusSuccess, DAHeight: binary.LittleEndian.Uint64(ids[0]), + BlobSize: blobSize, SubmittedCount: uint64(len(ids)), }, } diff --git a/sequencing/metrics.go b/sequencing/metrics.go new file mode 100644 index 0000000..9f01499 --- /dev/null +++ b/sequencing/metrics.go @@ -0,0 +1,86 @@ +package sequencing + +import ( + "github.com/go-kit/kit/metrics" + "github.com/go-kit/kit/metrics/discard" + "github.com/go-kit/kit/metrics/prometheus" + stdprometheus "github.com/prometheus/client_golang/prometheus" +) + +const ( + // MetricsSubsystem is a subsystem shared by all metrics exposed by this + // package. + MetricsSubsystem = "sequencer" +) + +// Metrics contains metrics exposed by this package. +type Metrics struct { + // GasPrice + GasPrice metrics.Gauge + // Last submitted blob size + LastBlobSize metrics.Gauge + // TODO(tuxcanfly): needs gas used, wallet balance from go-da + // cost / byte + // CostPerByte metrics.Gauge + // Wallet Balance + // WalletBalance metrics.Gauge + // Transaction Status + TransactionStatus metrics.Gauge + // Number of pending blocks. + NumPendingBlocks metrics.Gauge + // Last included block height + IncludedBlockHeight metrics.Gauge +} + +// PrometheusMetrics returns Metrics build using Prometheus client library. +// Optionally, labels can be provided along with their values ("foo", +// "fooValue"). +func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { + labels := []string{} + for i := 0; i < len(labelsAndValues); i += 2 { + labels = append(labels, labelsAndValues[i]) + } + return &Metrics{ + GasPrice: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "gas_price", + Help: "The gas price of DA.", + }, labels).With(labelsAndValues...), + LastBlobSize: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "last_blob_size", + Help: "The size in bytes of the last DA blob.", + }, labels).With(labelsAndValues...), + TransactionStatus: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "transaction_status", + Help: "The transaction status of the last DA submission.", + }, labels).With(labelsAndValues...), + NumPendingBlocks: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "num_pending_blocks", + Help: "The number of pending blocks for DA submission.", + }, labels).With(labelsAndValues...), + IncludedBlockHeight: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "included_block_height", + Help: "The last DA included block height.", + }, labels).With(labelsAndValues...), + } +} + +// NopMetrics returns no-op Metrics. +func NopMetrics() *Metrics { + return &Metrics{ + GasPrice: discard.NewGauge(), + LastBlobSize: discard.NewGauge(), + TransactionStatus: discard.NewGauge(), + NumPendingBlocks: discard.NewGauge(), + IncludedBlockHeight: discard.NewGauge(), + } +} diff --git a/sequencing/sequencer.go b/sequencing/sequencer.go index 53c178d..66e757b 100644 --- a/sequencing/sequencer.go +++ b/sequencing/sequencer.go @@ -123,6 +123,8 @@ type Sequencer struct { seenBatches map[string]struct{} bq *BatchQueue + + metrics *Metrics } // NewSequencer ... @@ -182,6 +184,14 @@ func (c *Sequencer) publishBatch() error { return nil } +func (c *Sequencer) recordMetrics(gasPrice float64, blobSize uint64, status da.StatusCode, numPendingBlocks int, includedBlockHeight uint64) { + c.metrics.GasPrice.Set(float64(gasPrice)) + c.metrics.LastBlobSize.Set(float64(blobSize)) + c.metrics.TransactionStatus.Set(float64(status)) + c.metrics.NumPendingBlocks.Set(float64(numPendingBlocks)) + c.metrics.IncludedBlockHeight.Set(float64(includedBlockHeight)) +} + func (c *Sequencer) submitBatchToDA(batch sequencing.Batch) error { batchesToSubmit := []*sequencing.Batch{&batch} submittedAllBlocks := false @@ -243,6 +253,7 @@ daSubmitRetryLoop: backoff = c.exponentialBackoff(backoff) } + c.recordMetrics(gasPrice, res.BlobSize, res.Code, len(batchesToSubmit), res.DAHeight) attempt += 1 }