From 93690fdb1d51f8ef470fd4f1d84490c14bf1f442 Mon Sep 17 00:00:00 2001 From: alvarius Date: Mon, 29 Apr 2024 17:03:13 +0100 Subject: [PATCH] feat(store-indexer): add metric for distance from block tag to follow (#2763) --- .changeset/good-fireants-retire.md | 5 +++++ packages/store-indexer/bin/postgres-indexer.ts | 9 +++++++++ packages/store-indexer/bin/sqlite-indexer.ts | 9 +++++++++ packages/store-indexer/src/koa-middleware/metrics.ts | 12 ++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 .changeset/good-fireants-retire.md diff --git a/.changeset/good-fireants-retire.md b/.changeset/good-fireants-retire.md new file mode 100644 index 0000000000..000fdc278b --- /dev/null +++ b/.changeset/good-fireants-retire.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/store-indexer": patch +--- + +Added a `distance_from_follow_block` metric to compare the latest stored block number with the block number corresponding to the block tag the indexer follows. diff --git a/packages/store-indexer/bin/postgres-indexer.ts b/packages/store-indexer/bin/postgres-indexer.ts index ba4b7cc6b6..d95c4cca50 100644 --- a/packages/store-indexer/bin/postgres-indexer.ts +++ b/packages/store-indexer/bin/postgres-indexer.ts @@ -66,6 +66,14 @@ async function getLatestStoredBlockNumber(): Promise { } } +async function getDistanceFromFollowBlock(): Promise { + const [latestStoredBlockNumber, latestFollowBlock] = await Promise.all([ + getLatestStoredBlockNumber(), + publicClient.getBlock({ blockTag: env.FOLLOW_BLOCK_TAG }), + ]); + return (latestStoredBlockNumber ?? -1n) - latestFollowBlock.number; +} + const latestStoredBlockNumber = await getLatestStoredBlockNumber(); if (latestStoredBlockNumber != null) { startBlock = latestStoredBlockNumber + 1n; @@ -117,6 +125,7 @@ if (env.HEALTHCHECK_HOST != null || env.HEALTHCHECK_PORT != null) { isHealthy: () => true, isReady: () => isCaughtUp, getLatestStoredBlockNumber, + getDistanceFromFollowBlock, followBlockTag: env.FOLLOW_BLOCK_TAG, }), ); diff --git a/packages/store-indexer/bin/sqlite-indexer.ts b/packages/store-indexer/bin/sqlite-indexer.ts index 61d9ca02a1..3b55093363 100644 --- a/packages/store-indexer/bin/sqlite-indexer.ts +++ b/packages/store-indexer/bin/sqlite-indexer.ts @@ -73,6 +73,14 @@ async function getLatestStoredBlockNumber(): Promise { return currentChainState?.lastUpdatedBlockNumber ?? undefined; } +async function getDistanceFromFollowBlock(): Promise { + const [latestStoredBlockNumber, latestFollowBlock] = await Promise.all([ + getLatestStoredBlockNumber(), + publicClient.getBlock({ blockTag: env.FOLLOW_BLOCK_TAG }), + ]); + return (latestStoredBlockNumber ?? -1n) - latestFollowBlock.number; +} + const currentChainState = await getCurrentChainState(); if (currentChainState) { // Reset the db if the version changed @@ -132,6 +140,7 @@ server.use( isHealthy: () => true, isReady: () => isCaughtUp, getLatestStoredBlockNumber, + getDistanceFromFollowBlock, followBlockTag: env.FOLLOW_BLOCK_TAG, }), ); diff --git a/packages/store-indexer/src/koa-middleware/metrics.ts b/packages/store-indexer/src/koa-middleware/metrics.ts index 7bfe3d0327..cda3f801d0 100644 --- a/packages/store-indexer/src/koa-middleware/metrics.ts +++ b/packages/store-indexer/src/koa-middleware/metrics.ts @@ -5,6 +5,7 @@ type MetricsOptions = { isHealthy?: () => boolean; isReady?: () => boolean; getLatestStoredBlockNumber?: () => Promise; + getDistanceFromFollowBlock?: () => Promise; followBlockTag?: "latest" | "safe" | "finalized"; }; @@ -15,6 +16,7 @@ export function metrics({ isHealthy, isReady, getLatestStoredBlockNumber, + getDistanceFromFollowBlock, followBlockTag, }: MetricsOptions = {}): Middleware { promClient.collectDefaultMetrics(); @@ -61,6 +63,16 @@ export function metrics({ blockTagGauge.set(blockTagToValue[followBlockTag]); } + if (getDistanceFromFollowBlock != null) { + new promClient.Gauge({ + name: "distance_from_follow_block", + help: "Block distance from the block tag this the indexer is following", + async collect(): Promise { + this.set(Number(await getDistanceFromFollowBlock())); + }, + }); + } + return async function metricsMiddleware(ctx, next): Promise { if (ctx.path === "/metrics") { ctx.status = 200;