Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iroha-connector): add prometheus exporter to the plugin #3461

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"express": "4.20.0",
"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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down Expand Up @@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down Expand Up @@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -792,6 +793,7 @@ export class CactusIrohaV2Client {
* @returns `TransactResponseV1`
*/
public async send(
prometheusExporter: PrometheusExporter,
txParams?: TransactionPayloadParameters,
waitForCommit = false,
): Promise<TransactResponseV1> {
Expand Down Expand Up @@ -820,6 +822,9 @@ export class CactusIrohaV2Client {
this.prerequisitesProvider.getApiHttpProperties(),
signedTx,
);
// counter will increase here
prometheusExporter.addCurrentTransaction();

this.clear();

if (statusPromise) {
Expand All @@ -843,6 +848,7 @@ export class CactusIrohaV2Client {
public async sendSignedPayload(
signedPayload: VersionedSignedTransaction | ArrayBufferView,
waitForCommit = false,
prometheusExporter: PrometheusExporter,
): Promise<TransactResponseV1> {
Checks.truthy(signedPayload, "sendSigned arg signedPayload");

Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<RequestArgs> => {
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.
Expand Down Expand Up @@ -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<string>> {
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.
Expand Down Expand Up @@ -790,6 +830,15 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa
generateTransactionV1(generateTransactionRequestV1?: GenerateTransactionRequestV1, options?: any): AxiosPromise<string> {
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<string> {
return localVarFp.getPrometheusMetricsV1(options).then((request) => request(axios, basePath));
},
/**
*
* @summary Executes a query on a Iroha V2 ledger and returns it\'s results.
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -72,6 +78,7 @@ export interface IPluginLedgerConnectorIroha2Options
pluginRegistry: PluginRegistry;
logLevel?: LogLevelDesc;
defaultConfig?: Iroha2BaseConfig;
prometheusExporter?: PrometheusExporter;
}

/**
Expand All @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -133,6 +151,16 @@ export class PluginLedgerConnectorIroha2
return OAS;
}

public getPrometheusExporter(): PrometheusExporter {
return this.prometheusExporter;
}

public async getPrometheusExporterMetrics(): Promise<string> {
const res: string = await this.prometheusExporter.getPrometheusMetrics();
this.log.debug(`getPrometheusExporterMetrics() response: %o`, res);
return res;
}

/**
* @warning Method not implemented - do not use!
*/
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -589,7 +626,6 @@ export class PluginLedgerConnectorIroha2
if (!reqParams) {
return undefined;
}

return {
ttl: reqParams.ttl ? BigInt(reqParams.ttl) : undefined,
creationTime: reqParams.creationTime
Expand All @@ -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,
);
Expand All @@ -625,6 +662,7 @@ export class PluginLedgerConnectorIroha2
return await client.sendSignedPayload(
transactionBinary,
req.waitForCommit,
this.prometheusExporter,
);
} else {
const eMsg =
Expand Down
Original file line number Diff line number Diff line change
@@ -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<void> {
transactions.counter++;
totalTxCount.labels(K_CACTUS_IROHA2_TOTAL_TX_COUNT).set(transactions.counter);
}
Original file line number Diff line number Diff line change
@@ -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"],
});
Loading
Loading