diff --git a/cl/singlenode/follower/follower.go b/cl/singlenode/follower/follower.go index 3c8da67f0..850abf409 100644 --- a/cl/singlenode/follower/follower.go +++ b/cl/singlenode/follower/follower.go @@ -10,6 +10,9 @@ import ( "time" "github.com/primev/mev-commit/cl/types" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" "golang.org/x/sync/errgroup" ) @@ -30,6 +33,16 @@ const ( defaultBackoff = 200 * time.Millisecond ) +var ( + followerDBDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "mev_commit", + Subsystem: "follower", + Name: "db_duration_seconds", + Help: "Duration of DB operations in follower", + Buckets: prometheus.DefBuckets, + }, []string{"op"}) +) + type PayloadDB interface { GetPayloadsSince(ctx context.Context, sinceHeight uint64, limit int) ([]types.PayloadInfo, error) GetLatestHeight(ctx context.Context) (uint64, error) @@ -73,6 +86,7 @@ func (f *Follower) Start(ctx context.Context) <-chan struct{} { defer close(f.healthStopped) mux := http.NewServeMux() mux.HandleFunc("/health", f.healthHandler) + mux.Handle("/metrics", promhttp.Handler()) server := &http.Server{Addr: f.healthAddr, Handler: mux} f.logger.Info("Health endpoint listening", "address", f.healthAddr) @@ -149,7 +163,10 @@ func (f *Follower) syncFromSharedDB(ctx context.Context) error { } cctx, cancel := context.WithTimeout(ctx, 5*time.Second) + start := time.Now() targetBlock, err := f.sharedDB.GetLatestHeight(cctx) + duration := time.Since(start) + followerDBDuration.WithLabelValues("get_latest_height").Observe(float64(duration.Seconds())) cancel() if err != nil { f.sleepRespectingContext(ctx, defaultBackoff) @@ -171,7 +188,10 @@ func (f *Follower) syncFromSharedDB(ctx context.Context) error { limit := min(f.syncBatchSize, blocksRemaining) cctx, cancel = context.WithTimeout(ctx, 5*time.Second) + start = time.Now() payloads, err := f.sharedDB.GetPayloadsSince(cctx, lastSignalledBlock+1, int(limit)) + duration = time.Since(start) + followerDBDuration.WithLabelValues("get_payloads_since").Observe(float64(duration.Seconds())) cancel() if err != nil { f.logger.Error("failed to get payloads since", "error", err) diff --git a/cl/singlenode/singlenode.go b/cl/singlenode/singlenode.go index 126606b48..fbbde649d 100644 --- a/cl/singlenode/singlenode.go +++ b/cl/singlenode/singlenode.go @@ -18,6 +18,9 @@ import ( "github.com/primev/mev-commit/cl/singlenode/payloadstore" localstate "github.com/primev/mev-commit/cl/singlenode/state" "github.com/primev/mev-commit/cl/types" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" ) const ( @@ -25,6 +28,16 @@ const ( shutdownTimeout = 5 * time.Second ) +var ( + snDBDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "mev_commit", + Subsystem: "singlenode", + Name: "db_duration_seconds", + Help: "Duration of save payload DB operation in singlenode", + Buckets: prometheus.DefBuckets, + }, []string{"op"}) +) + // Config holds the configuration for the SingleNodeApp. type Config struct { InstanceID string @@ -237,6 +250,7 @@ func (app *SingleNodeApp) Start() { defer app.wg.Done() mux := http.NewServeMux() mux.HandleFunc("/health", app.healthHandler) + mux.Handle("/metrics", promhttp.Handler()) addr := app.cfg.HealthAddr server := &http.Server{Addr: addr, Handler: mux} app.logger.Info("Health endpoint listening", "address", addr) @@ -356,6 +370,7 @@ func (app *SingleNodeApp) produceBlock() error { saveCtx, saveCancel := context.WithTimeout(app.appCtx, 200*time.Millisecond) defer saveCancel() + saveStart := time.Now() if err := app.payloadRepo.SavePayload(saveCtx, &types.PayloadInfo{ PayloadID: currentState.PayloadID, ExecutionPayload: currentState.ExecutionPayload, @@ -363,6 +378,8 @@ func (app *SingleNodeApp) produceBlock() error { }); err != nil { return fmt.Errorf("failed to save payload: %w", err) } + saveDuration := time.Since(saveStart) + snDBDuration.WithLabelValues("save_payload").Observe(float64(saveDuration.Seconds())) app.logger.Info( "payload saved to repository", "payload_id", currentState.PayloadID,