From fe6f61f02821d3b12c10873b64cf11f6303fc64c Mon Sep 17 00:00:00 2001 From: Ashna Date: Sun, 4 Aug 2024 14:16:00 +0000 Subject: [PATCH] =?UTF-8?q?feat(iroha-connector):=20add=20prometheus=20exp?= =?UTF-8?q?orter=20to=20the=20plugin=20=C2=A0=20Primary=20Changes=20------?= =?UTF-8?q?----------=201.=20Added=20Prometheus=20Exporter=20to=20Iroha=20?= =?UTF-8?q?ledger=20plugin=202.=20Added=20Prometheus=20Metrics=20tracker?= =?UTF-8?q?=20to=20relevant=20iroha=20tests.=20=C2=A0=20Fixes=20#1260?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ashnashahgrover --- .../package.json | 1 + .../src/main/json/openapi.json | 29 +++++ .../src/main/json/openapi.tpl.json | 29 +++++ .../cactus-iroha-sdk-wrapper/client.ts | 15 +++ .../generated/openapi/typescript-axios/api.ts | 60 ++++++++++ .../plugin-ledger-connector-iroha2.ts | 40 ++++++- .../prometheus-exporter/data-fetcher.ts | 10 ++ .../typescript/prometheus-exporter/metrics.ts | 10 ++ .../prometheus-exporter.ts | 39 +++++++ .../prometheus-exporter/response.type.ts | 3 + ...prometheus-exporter-metrics-endpoint-v1.ts | 110 ++++++++++++++++++ .../iroha2-setup-and-basic-operations.test.ts | 21 ++++ yarn.lock | 1 + 13 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/data-fetcher.ts create mode 100644 packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/metrics.ts create mode 100644 packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/prometheus-exporter.ts create mode 100644 packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/response.type.ts create mode 100644 packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/web-services/get-prometheus-exporter-metrics-endpoint-v1.ts diff --git a/packages/cactus-plugin-ledger-connector-iroha2/package.json b/packages/cactus-plugin-ledger-connector-iroha2/package.json index 31e71536032..cc3f3c4560c 100644 --- a/packages/cactus-plugin-ledger-connector-iroha2/package.json +++ b/packages/cactus-plugin-ledger-connector-iroha2/package.json @@ -58,6 +58,7 @@ "express": "4.19.2", "fast-safe-stringify": "2.1.1", "hada": "0.0.8", + "prom-client": "15.1.3", "rxjs": "7.8.1", "sanitize-html": "2.12.1", "socket.io": "4.6.2", diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.json b/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.json index a5903bc7b42..1418b58f29d 100644 --- a/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.json +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.json @@ -488,6 +488,10 @@ } } }, + "PrometheusExporterMetricsResponse": { + "type": "string", + "nullable": false + }, "GenerateTransactionRequestV1": { "type": "object", "description": "Request for generating transaction or query payload that can be signed on the client side.", @@ -623,6 +627,31 @@ } } }, + "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/get-prometheus-exporter-metrics": { + "get": { + "x-hyperledger-cacti": { + "http": { + "verbLowerCase": "get", + "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/get-prometheus-exporter-metrics" + } + }, + "operationId": "getPrometheusMetricsV1", + "summary": "Get the Prometheus Metrics", + "parameters": [], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/PrometheusExporterMetricsResponse" + } + } + } + } + } + } + }, "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/query": { "post": { "x-hyperledger-cacti": { diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.tpl.json b/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.tpl.json index a5903bc7b42..1418b58f29d 100644 --- a/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.tpl.json +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/json/openapi.tpl.json @@ -488,6 +488,10 @@ } } }, + "PrometheusExporterMetricsResponse": { + "type": "string", + "nullable": false + }, "GenerateTransactionRequestV1": { "type": "object", "description": "Request for generating transaction or query payload that can be signed on the client side.", @@ -623,6 +627,31 @@ } } }, + "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/get-prometheus-exporter-metrics": { + "get": { + "x-hyperledger-cacti": { + "http": { + "verbLowerCase": "get", + "path": "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/get-prometheus-exporter-metrics" + } + }, + "operationId": "getPrometheusMetricsV1", + "summary": "Get the Prometheus Metrics", + "parameters": [], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/PrometheusExporterMetricsResponse" + } + } + } + } + } + } + }, "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/query": { "post": { "x-hyperledger-cacti": { diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/cactus-iroha-sdk-wrapper/client.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/cactus-iroha-sdk-wrapper/client.ts index ac2855441af..94e4888b046 100644 --- a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/cactus-iroha-sdk-wrapper/client.ts +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/cactus-iroha-sdk-wrapper/client.ts @@ -76,6 +76,7 @@ import { Iroha2BaseConfigTorii, } from "../generated/openapi/typescript-axios"; import { IrohaV2PrerequisitesProvider } from "./prerequisites-provider"; +import { PrometheusExporter } from "../prometheus-exporter/prometheus-exporter"; setCrypto(crypto); @@ -792,6 +793,7 @@ export class CactusIrohaV2Client { * @returns `TransactResponseV1` */ public async send( + prometheusExporter: PrometheusExporter, txParams?: TransactionPayloadParameters, waitForCommit = false, ): Promise { @@ -820,6 +822,9 @@ export class CactusIrohaV2Client { this.prerequisitesProvider.getApiHttpProperties(), signedTx, ); + // counter will increase here + prometheusExporter.addCurrentTransaction(); + this.clear(); if (statusPromise) { @@ -843,6 +848,7 @@ export class CactusIrohaV2Client { public async sendSignedPayload( signedPayload: VersionedSignedTransaction | ArrayBufferView, waitForCommit = false, + prometheusExporter: PrometheusExporter, ): Promise { Checks.truthy(signedPayload, "sendSigned arg signedPayload"); @@ -853,16 +859,25 @@ export class CactusIrohaV2Client { const hash = computeTransactionHash(signedPayload.as("V1").payload); if (waitForCommit) { const statusPromise = this.waitForTransactionStatus(hash); + await Torii.submit( this.prerequisitesProvider.getApiHttpProperties(), signedPayload, ); + + // counter will increase here + prometheusExporter.addCurrentTransaction(); + return await statusPromise; } else { await Torii.submit( this.prerequisitesProvider.getApiHttpProperties(), signedPayload, ); + + // counter will increase here + prometheusExporter.addCurrentTransaction(); + return { hash: bytesToHex([...hash]), status: TransactionStatusV1.Submitted, diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/generated/openapi/typescript-axios/api.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/generated/openapi/typescript-axios/api.ts index 85d89d4103b..1c10d9eb1cb 100644 --- a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/generated/openapi/typescript-axios/api.ts +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/generated/openapi/typescript-axios/api.ts @@ -659,6 +659,36 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati options: localVarRequestOptions, }; }, + /** + * + * @summary Get the Prometheus Metrics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getPrometheusMetricsV1: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/get-prometheus-exporter-metrics`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, /** * * @summary Executes a query on a Iroha V2 ledger and returns it\'s results. @@ -748,6 +778,16 @@ export const DefaultApiFp = function(configuration?: Configuration) { const localVarAxiosArgs = await localVarAxiosParamCreator.generateTransactionV1(generateTransactionRequestV1, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, + /** + * + * @summary Get the Prometheus Metrics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getPrometheusMetricsV1(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getPrometheusMetricsV1(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, /** * * @summary Executes a query on a Iroha V2 ledger and returns it\'s results. @@ -790,6 +830,15 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa generateTransactionV1(generateTransactionRequestV1?: GenerateTransactionRequestV1, options?: any): AxiosPromise { return localVarFp.generateTransactionV1(generateTransactionRequestV1, options).then((request) => request(axios, basePath)); }, + /** + * + * @summary Get the Prometheus Metrics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getPrometheusMetricsV1(options?: any): AxiosPromise { + return localVarFp.getPrometheusMetricsV1(options).then((request) => request(axios, basePath)); + }, /** * * @summary Executes a query on a Iroha V2 ledger and returns it\'s results. @@ -832,6 +881,17 @@ export class DefaultApi extends BaseAPI { return DefaultApiFp(this.configuration).generateTransactionV1(generateTransactionRequestV1, options).then((request) => request(this.axios, this.basePath)); } + /** + * + * @summary Get the Prometheus Metrics + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApi + */ + public getPrometheusMetricsV1(options?: AxiosRequestConfig) { + return DefaultApiFp(this.configuration).getPrometheusMetricsV1(options).then((request) => request(this.axios, this.basePath)); + } + /** * * @summary Executes a query on a Iroha V2 ledger and returns it\'s results. diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/plugin-ledger-connector-iroha2.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/plugin-ledger-connector-iroha2.ts index 48ad6e142d7..9466ca7f1e6 100644 --- a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/plugin-ledger-connector-iroha2.ts +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/plugin-ledger-connector-iroha2.ts @@ -64,6 +64,12 @@ import { CactusIrohaV2QueryClient } from "./cactus-iroha-sdk-wrapper/query"; import { LengthOf, stringifyBigIntReplacer } from "./utils"; import { createAccountId } from "./cactus-iroha-sdk-wrapper/data-factories"; +import { + GetPrometheusExporterMetricsEndpointV1, + IGetPrometheusExporterMetricsEndpointV1Options, +} from "./web-services/get-prometheus-exporter-metrics-endpoint-v1"; +import { PrometheusExporter } from "./prometheus-exporter/prometheus-exporter"; + /** * Input options for PluginLedgerConnectorIroha2. */ @@ -72,6 +78,7 @@ export interface IPluginLedgerConnectorIroha2Options pluginRegistry: PluginRegistry; logLevel?: LogLevelDesc; defaultConfig?: Iroha2BaseConfig; + prometheusExporter?: PrometheusExporter; } /** @@ -84,6 +91,7 @@ export class PluginLedgerConnectorIroha2 IPluginWebService { private readonly instanceId: string; + public prometheusExporter: PrometheusExporter; private readonly log: Logger; private readonly defaultConfig: Iroha2BaseConfig | undefined; private endpoints: IWebServiceEndpoint[] | undefined; @@ -102,6 +110,16 @@ export class PluginLedgerConnectorIroha2 this.instanceId = options.instanceId; + this.prometheusExporter = + options.prometheusExporter || + new PrometheusExporter({ pollingIntervalInMin: 1 }); + Checks.truthy( + this.prometheusExporter, + `${fnTag} options.prometheusExporter`, + ); + + this.prometheusExporter.startMetricsCollection(); + this.defaultConfig = options.defaultConfig; // Remove proto in case we use merge method vulnerable to proto pollution if (this.defaultConfig instanceof Object) { @@ -133,6 +151,16 @@ export class PluginLedgerConnectorIroha2 return OAS; } + public getPrometheusExporter(): PrometheusExporter { + return this.prometheusExporter; + } + + public async getPrometheusExporterMetrics(): Promise { + const res: string = await this.prometheusExporter.getPrometheusMetrics(); + this.log.debug(`getPrometheusExporterMetrics() response: %o`, res); + return res; + } + /** * @warning Method not implemented - do not use! */ @@ -266,6 +294,15 @@ export class PluginLedgerConnectorIroha2 }), ]; + { + const opts: IGetPrometheusExporterMetricsEndpointV1Options = { + connector: this, + logLevel: this.options.logLevel, + }; + const endpoint = new GetPrometheusExporterMetricsEndpointV1(opts); + endpoints.push(endpoint); + } + this.endpoints = endpoints; return endpoints; } @@ -589,7 +626,6 @@ export class PluginLedgerConnectorIroha2 if (!reqParams) { return undefined; } - return { ttl: reqParams.ttl ? BigInt(reqParams.ttl) : undefined, creationTime: reqParams.creationTime @@ -615,6 +651,7 @@ export class PluginLedgerConnectorIroha2 if (req.transaction) { this.processInstructionsRequests(client, req.transaction.instruction); return await client.send( + this.prometheusExporter, this.tryParseTransactionParams(req.transaction.params), req.waitForCommit, ); @@ -625,6 +662,7 @@ export class PluginLedgerConnectorIroha2 return await client.sendSignedPayload( transactionBinary, req.waitForCommit, + this.prometheusExporter, ); } else { const eMsg = diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/data-fetcher.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/data-fetcher.ts new file mode 100644 index 00000000000..da7c8e672f3 --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/data-fetcher.ts @@ -0,0 +1,10 @@ +import { Transactions } from "./response.type"; + +import { totalTxCount, K_CACTUS_IROHA2_TOTAL_TX_COUNT } from "./metrics"; + +export async function collectMetrics( + transactions: Transactions, +): Promise { + transactions.counter++; + totalTxCount.labels(K_CACTUS_IROHA2_TOTAL_TX_COUNT).set(transactions.counter); +} diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/metrics.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/metrics.ts new file mode 100644 index 00000000000..3800f875e3b --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/metrics.ts @@ -0,0 +1,10 @@ +import { Gauge } from "prom-client"; + +export const K_CACTUS_IROHA2_TOTAL_TX_COUNT = "cactus_iroha2_total_tx_count"; + +export const totalTxCount = new Gauge({ + registers: [], + name: "cactus_iroha2_total_tx_count", + help: "Total transactions executed", + labelNames: ["type"], +}); diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/prometheus-exporter.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/prometheus-exporter.ts new file mode 100644 index 00000000000..0df23ce3abf --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/prometheus-exporter.ts @@ -0,0 +1,39 @@ +import promClient, { Registry } from "prom-client"; +import { Transactions } from "./response.type"; +import { collectMetrics } from "./data-fetcher"; +import { K_CACTUS_IROHA2_TOTAL_TX_COUNT } from "./metrics"; +import { totalTxCount } from "./metrics"; + +export interface IPrometheusExporterOptions { + pollingIntervalInMin?: number; +} + +export class PrometheusExporter { + public readonly metricsPollingIntervalInMin: number; + public readonly transactions: Transactions = { counter: 0 }; + public readonly registry: Registry; + + constructor( + public readonly prometheusExporterOptions: IPrometheusExporterOptions, + ) { + this.metricsPollingIntervalInMin = + prometheusExporterOptions.pollingIntervalInMin || 1; + this.registry = new Registry(); + } + + public addCurrentTransaction(): void { + collectMetrics(this.transactions); + } + + public async getPrometheusMetrics(): Promise { + const result = await this.registry.getSingleMetricAsString( + K_CACTUS_IROHA2_TOTAL_TX_COUNT, + ); + return result; + } + + public startMetricsCollection(): void { + this.registry.registerMetric(totalTxCount); + promClient.collectDefaultMetrics({ register: this.registry }); + } +} diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/response.type.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/response.type.ts new file mode 100644 index 00000000000..3f1bc7f4911 --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/prometheus-exporter/response.type.ts @@ -0,0 +1,3 @@ +export type Transactions = { + counter: number; +}; diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/web-services/get-prometheus-exporter-metrics-endpoint-v1.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/web-services/get-prometheus-exporter-metrics-endpoint-v1.ts new file mode 100644 index 00000000000..2a1490f093c --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/main/typescript/web-services/get-prometheus-exporter-metrics-endpoint-v1.ts @@ -0,0 +1,110 @@ +import { Express, Request, Response } from "express"; + +import { + registerWebServiceEndpoint, + handleRestEndpointException, +} from "@hyperledger/cactus-core"; + +import OAS from "../../json/openapi.json"; + +import { + IWebServiceEndpoint, + IExpressRequestHandler, + IEndpointAuthzOptions, +} from "@hyperledger/cactus-core-api"; + +import { + LogLevelDesc, + Logger, + LoggerProvider, + Checks, + IAsyncProvider, +} from "@hyperledger/cactus-common"; + +import { PluginLedgerConnectorIroha2 } from "../plugin-ledger-connector-iroha2"; + +export interface IGetPrometheusExporterMetricsEndpointV1Options { + connector: PluginLedgerConnectorIroha2; + logLevel?: LogLevelDesc; +} + +export class GetPrometheusExporterMetricsEndpointV1 + implements IWebServiceEndpoint +{ + private readonly log: Logger; + + constructor( + public readonly options: IGetPrometheusExporterMetricsEndpointV1Options, + ) { + const fnTag = "GetPrometheusExporterMetricsEndpointV1#constructor()"; + + Checks.truthy(options, `${fnTag} options`); + Checks.truthy(options.connector, `${fnTag} options.connector`); + + const label = "get-prometheus-exporter-metrics-endpoint"; + const level = options.logLevel || "INFO"; + this.log = LoggerProvider.getOrCreate({ label, level }); + } + + getAuthorizationOptionsProvider(): IAsyncProvider { + // TODO: make this an injectable dependency in the constructor + return { + get: async () => ({ + isProtected: true, + requiredRoles: [], + }), + }; + } + + public getExpressRequestHandler(): IExpressRequestHandler { + return this.handleRequest.bind(this); + } + + public get oasPath(): (typeof OAS.paths)["/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/get-prometheus-exporter-metrics"] { + return OAS.paths[ + "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha2/get-prometheus-exporter-metrics" + ]; + } + + public getPath(): string { + return this.oasPath.get["x-hyperledger-cacti"].http.path; + } + + public getVerbLowerCase(): string { + return this.oasPath.get["x-hyperledger-cacti"].http.verbLowerCase; + } + + public getOperationId(): string { + return this.oasPath.get.operationId; + } + + public async registerExpress( + expressApp: Express, + ): Promise { + await registerWebServiceEndpoint(expressApp, this); + return this; + } + + async handleRequest(req: Request, res: Response): Promise { + const fnTag = "GetPrometheusExporterMetrics#handleRequest()"; + const reqTag = `${this.getVerbLowerCase()} - ${this.getPath()}`; + const verbUpper = this.getVerbLowerCase().toUpperCase(); + this.log.debug(`${verbUpper} ${this.getPath()}`); + + try { + const resBody = + await this.options.connector.getPrometheusExporterMetrics(); + res.status(200); + res.send(resBody); + } catch (ex) { + const errorMsg = `${reqTag} ${fnTag} failed to serve request:`; + + await handleRestEndpointException({ + errorMsg, + log: this.log, + error: ex, + res, + }); + } + } +} diff --git a/packages/cactus-plugin-ledger-connector-iroha2/src/test/typescript/integration/iroha2-setup-and-basic-operations.test.ts b/packages/cactus-plugin-ledger-connector-iroha2/src/test/typescript/integration/iroha2-setup-and-basic-operations.test.ts index f966817b011..d9bac4b63af 100644 --- a/packages/cactus-plugin-ledger-connector-iroha2/src/test/typescript/integration/iroha2-setup-and-basic-operations.test.ts +++ b/packages/cactus-plugin-ledger-connector-iroha2/src/test/typescript/integration/iroha2-setup-and-basic-operations.test.ts @@ -34,6 +34,7 @@ import { generateTestIrohaCredentials, } from "../test-helpers/iroha2-env-setup"; import { addRandomSuffix } from "../test-helpers/utils"; +import { K_CACTUS_IROHA2_TOTAL_TX_COUNT } from "../../../main/typescript/prometheus-exporter/metrics"; setCrypto(crypto); @@ -393,4 +394,24 @@ describe("Setup and basic endpoint tests", () => { }), ).toReject(); }); + + test("get prometheus exporter metrics", async () => { + const res = await env.apiClient.getPrometheusMetricsV1(); + const promMetricsOutput = + "# HELP " + + K_CACTUS_IROHA2_TOTAL_TX_COUNT + + " Total transactions executed\n" + + "# TYPE " + + K_CACTUS_IROHA2_TOTAL_TX_COUNT + + " gauge\n" + + K_CACTUS_IROHA2_TOTAL_TX_COUNT + + '{type="' + + K_CACTUS_IROHA2_TOTAL_TX_COUNT + + '"} 6'; + + expect(res).toBeTruthy(); + expect(res.data).toBeTruthy(); + expect(res.status).toEqual(200); + expect(res.data.includes(promMetricsOutput)).toBeTrue(); + }); }); diff --git a/yarn.lock b/yarn.lock index 9d7b282d75f..a9eb048b6f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10425,6 +10425,7 @@ __metadata: hada: "npm:0.0.8" jest: "npm:29.6.2" jest-extended: "npm:4.0.1" + prom-client: "npm:15.1.3" rxjs: "npm:7.8.1" sanitize-html: "npm:2.12.1" socket.io: "npm:4.6.2"