Skip to content

Commit

Permalink
feat(store-indexer): add prometheus metrics (#2739)
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs committed Apr 25, 2024
1 parent f736c43 commit 27c4fde
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-eagles-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/store-indexer": patch
---

Add Prometheus metrics at `/metrics` to the Postgres indexer backend and frontend, as well as the SQLite indexer.
7 changes: 7 additions & 0 deletions packages/store-indexer/bin/postgres-frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { apiRoutes } from "../src/postgres/apiRoutes";
import { sentry } from "../src/koa-middleware/sentry";
import { healthcheck } from "../src/koa-middleware/healthcheck";
import { helloWorld } from "../src/koa-middleware/helloWorld";
import { metrics } from "../src/koa-middleware/metrics";

const env = parseEnv(
z.intersection(
Expand All @@ -34,6 +35,12 @@ if (env.SENTRY_DSN) {

server.use(cors());
server.use(healthcheck());
server.use(
metrics({
isHealthy: () => true,
isReady: () => true,
}),
);
server.use(helloWorld());
server.use(apiRoutes(database));

Expand Down
7 changes: 7 additions & 0 deletions packages/store-indexer/bin/postgres-indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ if (env.HEALTHCHECK_HOST != null || env.HEALTHCHECK_PORT != null) {
const { default: Koa } = await import("koa");
const { default: cors } = await import("@koa/cors");
const { healthcheck } = await import("../src/koa-middleware/healthcheck");
const { metrics } = await import("../src/koa-middleware/metrics");
const { helloWorld } = await import("../src/koa-middleware/helloWorld");

const server = new Koa();
Expand All @@ -106,6 +107,12 @@ if (env.HEALTHCHECK_HOST != null || env.HEALTHCHECK_PORT != null) {
isReady: () => isCaughtUp,
}),
);
server.use(
metrics({
isHealthy: () => true,
isReady: () => isCaughtUp,
}),
);
server.use(helloWorld());

server.listen({ host: env.HEALTHCHECK_HOST, port: env.HEALTHCHECK_PORT });
Expand Down
7 changes: 7 additions & 0 deletions packages/store-indexer/bin/sqlite-indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { healthcheck } from "../src/koa-middleware/healthcheck";
import { helloWorld } from "../src/koa-middleware/helloWorld";
import { apiRoutes } from "../src/sqlite/apiRoutes";
import { sentry } from "../src/koa-middleware/sentry";
import { metrics } from "../src/koa-middleware/metrics";

const env = parseEnv(
z.intersection(
Expand Down Expand Up @@ -107,6 +108,12 @@ server.use(
isReady: () => isCaughtUp,
}),
);
server.use(
metrics({
isHealthy: () => true,
isReady: () => isCaughtUp,
}),
);
server.use(helloWorld());
server.use(apiRoutes(database));

Expand Down
1 change: 1 addition & 0 deletions packages/store-indexer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"koa": "^2.14.2",
"koa-compose": "^4.1.0",
"postgres": "3.3.5",
"prom-client": "^15.1.2",
"rxjs": "7.5.5",
"superjson": "^1.12.4",
"trpc-koa-adapter": "^1.1.3",
Expand Down
43 changes: 43 additions & 0 deletions packages/store-indexer/src/koa-middleware/metrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Middleware } from "koa";
import promClient from "prom-client";

type MetricsOptions = {
isHealthy?: () => boolean;
isReady?: () => boolean;
};

/**
* Middleware to add Prometheus metrics endpoints
*/
export function metrics({ isHealthy, isReady }: MetricsOptions = {}): Middleware {
promClient.collectDefaultMetrics();
if (isHealthy != null) {
new promClient.Gauge({
name: "health_status",
help: "Health status (0 = unhealthy, 1 = healthy)",
collect(): void {
this.set(Number(isHealthy()));
},
});
}

if (isReady != null) {
new promClient.Gauge({
name: "readiness_status",
help: "Readiness status (whether the service is ready to receive requests, 0 = not ready, 1 = ready)",
collect(): void {
this.set(Number(isReady()));
},
});
}

return async function metricsMiddleware(ctx, next): Promise<void> {
if (ctx.path === "/metrics") {
ctx.status = 200;
ctx.body = await promClient.register.metrics();
return;
}

await next();
};
}
46 changes: 36 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 27c4fde

Please sign in to comment.