From 588865b71ea20593e3359b502c20f4f7c013294e Mon Sep 17 00:00:00 2001 From: Charles Morin Date: Tue, 5 Sep 2023 10:23:08 -0400 Subject: [PATCH] Added health endpoint and fixed headers --- package-lock.json | 22 +++++++++++----------- package.json | 2 +- src/config.ts | 2 +- src/health.ts | 33 +++++++++++++++++++++++++++++++++ src/setup.ts | 4 ++++ 5 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 src/health.ts diff --git a/package-lock.json b/package-lock.json index c6ad143..57d8852 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "substreams-sink", - "version": "0.9.4", + "version": "0.9.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "substreams-sink", - "version": "0.9.4", + "version": "0.9.5", "license": "MIT OR Apache-2.0", "dependencies": { "@substreams/core": "^0.1.18", @@ -314,9 +314,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.8.tgz", - "integrity": "sha512-eajsR9aeljqNhK028VG0Wuw+OaY5LLxYmxeoXynIoE6jannr9/Ucd1LL0hSSoafk5LTYG+FfqsyGt81Q6Zkybw==" + "version": "20.5.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz", + "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==" }, "node_modules/@types/set-cookie-parser": { "version": "2.4.3", @@ -384,9 +384,9 @@ } }, "node_modules/fast-check": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.12.0.tgz", - "integrity": "sha512-SqahE9mlL3+lhjJ39joMLwcj6F+24hfZdf/tchlNO8sHcTdrUUdA5P/ZbSFZM9Xpzs36XaneGwE0FWepm/zyOA==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.12.1.tgz", + "integrity": "sha512-aRN6WrO+q3TZV8CjXnpebx9bTHrpYIOVi6v3ttxciZiWqS739yy8b1oVx+qNEyV1b8RdVjlp/+miTY6yAp90HA==", "funding": [ { "type": "individual", @@ -493,9 +493,9 @@ } }, "node_modules/pure-rand": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", - "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.3.tgz", + "integrity": "sha512-KddyFewCsO0j3+np81IQ+SweXLDnDQTs5s67BOnrYmYe/yNmUhttQyGsYzy8yUnoljGAQ9sl38YB4vH8ur7Y+w==", "funding": [ { "type": "individual", diff --git a/package.json b/package.json index d5f53a1..e1ca5d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "substreams-sink", - "version": "0.9.4", + "version": "0.9.5", "description": "Substreams Sink", "type": "module", "exports": "./dist/index.js", diff --git a/src/config.ts b/src/config.ts index 9ab3744..af5d144 100644 --- a/src/config.ts +++ b/src/config.ts @@ -11,5 +11,5 @@ export const DEFAULT_COLLECT_DEFAULT_METRICS = false; export const DEFAULT_START_BLOCK = "-1"; export const DEFAULT_SUBSTREAMS_API_TOKEN = ""; export const DEFAULT_PARAMS = []; -export const DEFAULT_HEADERS = []; +export const DEFAULT_HEADERS = new Headers(); export const DEFAULT_AUTH_ISSUE_URL = "https://auth.pinax.network/v1/auth/issue"; diff --git a/src/health.ts b/src/health.ts new file mode 100644 index 0000000..f1522d1 --- /dev/null +++ b/src/health.ts @@ -0,0 +1,33 @@ +import type { IncomingMessage, ServerResponse } from "http"; + +import * as prometheus from "./prometheus.js"; +import * as http from "./http.js"; + +export function health() { + http.server.on("request", async (req, res) => { + if (!req.url) return; + try { + if (req.method == "GET") { + if (req.url === "/health") { + const messages = await getSingleMetric("substreams_sink_data_message") + if (messages) return toText(res, "OK"); + return toText(res, "no messages received yet", 503); + } + } + } catch (err: any) { + res.statusCode = 400; + return res.end(err.message); + } + }); +} + +async function getSingleMetric(name: string) { + const metric = prometheus.registry.getSingleMetric(name); + const get = await metric?.get(); + return get?.values[0].value; +} + +function toText(res: ServerResponse, data: any, status = 200) { + res.writeHead(status, { 'Content-Type': 'text/plain; charset=utf-8' }); + return res.end(data); +} \ No newline at end of file diff --git a/src/setup.ts b/src/setup.ts index 976826a..5c8bc82 100644 --- a/src/setup.ts +++ b/src/setup.ts @@ -10,6 +10,7 @@ import * as prometheus from "./prometheus.js"; import { logger } from "./logger.js"; import { onRestartInactivitySeconds } from "./restartInactivitySeconds.js"; import { applyParams } from "./applyParams.js"; +import { health } from "./health.js"; export async function setup(options: RunOptions) { // Configure logging with TSLog @@ -37,6 +38,9 @@ export async function setup(options: RunOptions) { // Adding default headers headers.set("User-Agent", "substreams-sink"); + // Health check + health(); + // Apply params if (params.length && substreamPackage.modules) { applyParams(params, substreamPackage.modules.modules);