Add metrics client

This commit is contained in:
Agustin Pazos 2023-07-06 18:04:16 -03:00
parent 93e1a72409
commit 9025f6f640
9 changed files with 116 additions and 6 deletions

View File

@ -77,7 +77,7 @@ func (q *SQS) Consume(ctx context.Context) <-chan ConsumerMessage {
q.logger.Error("Error decoding vaaEvent message from SQSEvent", zap.Error(err)) q.logger.Error("Error decoding vaaEvent message from SQSEvent", zap.Error(err))
continue continue
} }
q.metrics.IncVaaConsumedQueue(vaaEvent.ChainID) q.metrics.IncVaaConsumedQueue(uint16(vaaEvent.ChainID))
// filter vaaEvent by p2p net. // filter vaaEvent by p2p net.
if q.filterConsume(&vaaEvent) { if q.filterConsume(&vaaEvent) {

View File

@ -21,6 +21,7 @@ import (
"github.com/wormhole-foundation/wormhole-explorer/txtracker/config" "github.com/wormhole-foundation/wormhole-explorer/txtracker/config"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/consumer" "github.com/wormhole-foundation/wormhole-explorer/txtracker/consumer"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/http/infrastructure" "github.com/wormhole-foundation/wormhole-explorer/txtracker/http/infrastructure"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/internal/metrics"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/queue" "github.com/wormhole-foundation/wormhole-explorer/txtracker/queue"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -54,6 +55,9 @@ func main() {
}() }()
db := cli.Database(cfg.MongodbDatabase) db := cli.Database(cfg.MongodbDatabase)
// initialize metrics
metrics := newMetrics(cfg)
// start serving /health and /ready endpoints // start serving /health and /ready endpoints
healthChecks, err := makeHealthChecks(rootCtx, cfg, db) healthChecks, err := makeHealthChecks(rootCtx, cfg, db)
if err != nil { if err != nil {
@ -63,9 +67,9 @@ func main() {
server.Start() server.Start()
// create and start a consumer. // create and start a consumer.
vaaConsumeFunc := newVAAConsumeFunc(rootCtx, cfg, logger) vaaConsumeFunc := newVAAConsumeFunc(rootCtx, cfg, metrics, logger)
repository := consumer.NewRepository(logger, db) repository := consumer.NewRepository(logger, db)
consumer := consumer.New(vaaConsumeFunc, &cfg.RpcProviderSettings, rootCtx, logger, repository) consumer := consumer.New(vaaConsumeFunc, &cfg.RpcProviderSettings, rootCtx, logger, repository, metrics)
consumer.Start(rootCtx) consumer.Start(rootCtx)
logger.Info("Started wormhole-explorer-tx-tracker") logger.Info("Started wormhole-explorer-tx-tracker")
@ -91,6 +95,7 @@ func main() {
func newVAAConsumeFunc( func newVAAConsumeFunc(
ctx context.Context, ctx context.Context,
cfg *config.ServiceSettings, cfg *config.ServiceSettings,
metrics metrics.Metrics,
logger *zap.Logger, logger *zap.Logger,
) queue.VAAConsumeFunc { ) queue.VAAConsumeFunc {
@ -99,7 +104,7 @@ func newVAAConsumeFunc(
logger.Fatal("failed to create sqs consumer", zap.Error(err)) logger.Fatal("failed to create sqs consumer", zap.Error(err))
} }
vaaQueue := queue.NewVaaSqs(sqsConsumer, logger) vaaQueue := queue.NewVaaSqs(sqsConsumer, metrics, logger)
return vaaQueue.Consume return vaaQueue.Consume
} }
@ -175,3 +180,10 @@ func makeHealthChecks(
return plugins, nil return plugins, nil
} }
func newMetrics(cfg *config.ServiceSettings) metrics.Metrics {
if !cfg.MetricsEnabled {
return metrics.NewDummyMetrics()
}
return metrics.NewPrometheusMetrics(cfg.Environment)
}

View File

@ -37,8 +37,10 @@ type BackfillerSettings struct {
type ServiceSettings struct { type ServiceSettings struct {
// MonitoringPort defines the TCP port for the /health and /ready endpoints. // MonitoringPort defines the TCP port for the /health and /ready endpoints.
MonitoringPort string `split_words:"true" default:"8000"` MonitoringPort string `split_words:"true" default:"8000"`
Environment string `split_words:"true" required:"true"`
LogLevel string `split_words:"true" default:"INFO"` LogLevel string `split_words:"true" default:"INFO"`
PprofEnabled bool `split_words:"true" default:"false"` PprofEnabled bool `split_words:"true" default:"false"`
MetricsEnabled bool `split_words:"true" default:"false"`
AwsSettings AwsSettings
MongodbSettings MongodbSettings

View File

@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/config" "github.com/wormhole-foundation/wormhole-explorer/txtracker/config"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/internal/metrics"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/queue" "github.com/wormhole-foundation/wormhole-explorer/txtracker/queue"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -30,9 +31,10 @@ func New(
ctx context.Context, ctx context.Context,
logger *zap.Logger, logger *zap.Logger,
repository *Repository, repository *Repository,
metrics metrics.Metrics,
) *Consumer { ) *Consumer {
workerPool := NewWorkerPool(ctx, logger, rpcServiceProviderSettings, repository) workerPool := NewWorkerPool(ctx, logger, rpcServiceProviderSettings, repository, metrics)
c := Consumer{ c := Consumer{
consumeFunc: consumeFunc, consumeFunc: consumeFunc,

View File

@ -7,6 +7,7 @@ import (
"github.com/wormhole-foundation/wormhole-explorer/txtracker/chains" "github.com/wormhole-foundation/wormhole-explorer/txtracker/chains"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/config" "github.com/wormhole-foundation/wormhole-explorer/txtracker/config"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/internal/metrics"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/queue" "github.com/wormhole-foundation/wormhole-explorer/txtracker/queue"
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa" sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
"go.uber.org/zap" "go.uber.org/zap"
@ -22,6 +23,7 @@ type WorkerPool struct {
logger *zap.Logger logger *zap.Logger
rpcProviderSettings *config.RpcProviderSettings rpcProviderSettings *config.RpcProviderSettings
repository *Repository repository *Repository
metrics metrics.Metrics
} }
// NewWorkerPool creates a new worker pool. // NewWorkerPool creates a new worker pool.
@ -30,6 +32,7 @@ func NewWorkerPool(
logger *zap.Logger, logger *zap.Logger,
rpcProviderSettings *config.RpcProviderSettings, rpcProviderSettings *config.RpcProviderSettings,
repository *Repository, repository *Repository,
metrics metrics.Metrics,
) *WorkerPool { ) *WorkerPool {
w := WorkerPool{ w := WorkerPool{
@ -111,12 +114,14 @@ func (w *WorkerPool) process(msg queue.ConsumerMessage) {
msg.Failed() msg.Failed()
return return
} }
w.metrics.IncVaaUnexpired(uint16(event.ChainID))
// Do not process messages from PythNet // Do not process messages from PythNet
if event.ChainID == sdk.ChainIDPythNet { if event.ChainID == sdk.ChainIDPythNet {
msg.Done() msg.Done()
return return
} }
w.metrics.IncVaaUnfiltered(uint16(event.ChainID))
// Process the VAA // Process the VAA
p := ProcessSourceTxParams{ p := ProcessSourceTxParams{
@ -139,6 +144,7 @@ func (w *WorkerPool) process(msg queue.ConsumerMessage) {
zap.Error(err), zap.Error(err),
) )
} else { } else {
w.metrics.IncOriginTxInserted(uint16(event.ChainID))
w.logger.Info("Updated originTx in the database", w.logger.Info("Updated originTx in the database",
zap.String("id", event.ID), zap.String("id", event.ID),
) )

View File

@ -0,0 +1,22 @@
package metrics
// DummyMetrics is a dummy implementation of Metric interface.
type DummyMetrics struct {
}
// NewDummyMetrics returns a new instance of DummyMetrics.
func NewDummyMetrics() *DummyMetrics {
return &DummyMetrics{}
}
// IncVaaConsumedQueue is a dummy implementation of IncVaaConsumedQueue.
func (d *DummyMetrics) IncVaaConsumedQueue(chainID uint16) {}
// IncVaaUnexpired is a dummy implementation of IncVaaUnexpired.
func (d *DummyMetrics) IncVaaUnexpired(chainID uint16) {}
// IncVaaUnfiltered is a dummy implementation of IncVaaUnfiltered.
func (d *DummyMetrics) IncVaaUnfiltered(chainID uint16) {}
// IncOriginTxInserted is a dummy implementation of IncOriginTxInserted.
func (d *DummyMetrics) IncOriginTxInserted(chainID uint16) {}

View File

@ -0,0 +1,10 @@
package metrics
const serviceName = "wormscan-tx-tracker"
type Metrics interface {
IncVaaConsumedQueue(chainID uint16)
IncVaaUnexpired(chainID uint16)
IncVaaUnfiltered(chainID uint16)
IncOriginTxInserted(chainID uint16)
}

View File

@ -0,0 +1,52 @@
package metrics
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
)
// PrometheusMetrics is a Prometheus implementation of Metric interface.
type PrometheusMetrics struct {
vaaTxTrackerCount *prometheus.CounterVec
}
// NewPrometheusMetrics returns a new instance of PrometheusMetrics.
func NewPrometheusMetrics(environment string) *PrometheusMetrics {
vaaTxTrackerCount := promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "vaa_tx_tracker_count_by_chain",
Help: "Total number of vaa processed by tx tracker by chain",
ConstLabels: map[string]string{
"environment": environment,
"service": serviceName,
},
}, []string{"chain", "type"})
return &PrometheusMetrics{
vaaTxTrackerCount: vaaTxTrackerCount,
}
}
// IncVaaConsumedQueue increments the number of consumed VAA.
func (m *PrometheusMetrics) IncVaaConsumedQueue(chainID uint16) {
chain := vaa.ChainID(chainID).String()
m.vaaTxTrackerCount.WithLabelValues(chain, "consumed_queue").Inc()
}
// IncVaaUnexpired increments the number of unexpired VAA.
func (m *PrometheusMetrics) IncVaaUnexpired(chainID uint16) {
chain := vaa.ChainID(chainID).String()
m.vaaTxTrackerCount.WithLabelValues(chain, "unexpired").Inc()
}
// IncVaaUnfiltered increments the number of unfiltered VAA.
func (m *PrometheusMetrics) IncVaaUnfiltered(chainID uint16) {
chain := vaa.ChainID(chainID).String()
m.vaaTxTrackerCount.WithLabelValues(chain, "unfiltered").Inc()
}
// IncOriginTxInserted increments the number of inserted origin tx.
func (m *PrometheusMetrics) IncOriginTxInserted(chainID uint16) {
chain := vaa.ChainID(chainID).String()
m.vaaTxTrackerCount.WithLabelValues(chain, "origin_tx_inserted").Inc()
}

View File

@ -9,6 +9,7 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
sqs_client "github.com/wormhole-foundation/wormhole-explorer/common/client/sqs" sqs_client "github.com/wormhole-foundation/wormhole-explorer/common/client/sqs"
"github.com/wormhole-foundation/wormhole-explorer/txtracker/internal/metrics"
) )
// SQSOption represents a VAA queue in SQS option function. // SQSOption represents a VAA queue in SQS option function.
@ -20,6 +21,7 @@ type SQS struct {
ch chan ConsumerMessage ch chan ConsumerMessage
chSize int chSize int
wg sync.WaitGroup wg sync.WaitGroup
metrics metrics.Metrics
logger *zap.Logger logger *zap.Logger
} }
@ -27,9 +29,10 @@ type SQS struct {
type FilterConsumeFunc func(vaaEvent *VaaEvent) bool type FilterConsumeFunc func(vaaEvent *VaaEvent) bool
// NewVaaSqs creates a VAA queue in SQS instances. // NewVaaSqs creates a VAA queue in SQS instances.
func NewVaaSqs(consumer *sqs_client.Consumer, logger *zap.Logger, opts ...SQSOption) *SQS { func NewVaaSqs(consumer *sqs_client.Consumer, metrics metrics.Metrics, logger *zap.Logger, opts ...SQSOption) *SQS {
s := &SQS{ s := &SQS{
consumer: consumer, consumer: consumer,
metrics: metrics,
chSize: 10, chSize: 10,
logger: logger} logger: logger}
for _, opt := range opts { for _, opt := range opts {
@ -72,6 +75,7 @@ func (q *SQS) Consume(ctx context.Context) <-chan ConsumerMessage {
q.logger.Error("Error decoding vaaEvent message from SQSEvent", zap.Error(err)) q.logger.Error("Error decoding vaaEvent message from SQSEvent", zap.Error(err))
continue continue
} }
q.metrics.IncVaaConsumedQueue(uint16(vaaEvent.ChainID))
q.wg.Add(1) q.wg.Add(1)
q.ch <- &sqsConsumerMessage{ q.ch <- &sqsConsumerMessage{