From f8119a8bc2029c310074af01b94229f4e6718919 Mon Sep 17 00:00:00 2001 From: Michael Kim Date: Thu, 12 Sep 2024 14:56:25 +0900 Subject: [PATCH 1/2] Add exception handler on metrics --- packages/relay/src/routers/DefaultRouter.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/relay/src/routers/DefaultRouter.ts b/packages/relay/src/routers/DefaultRouter.ts index b0c4e16..e81b99f 100644 --- a/packages/relay/src/routers/DefaultRouter.ts +++ b/packages/relay/src/routers/DefaultRouter.ts @@ -57,13 +57,17 @@ export class DefaultRouter { * @private */ private async getMetrics(req: express.Request, res: express.Response) { - res.set("Content-Type", this.metrics.contentType()); - this.metrics.add("status", 1); - for (const elem of this.config.relay.certifiers) { - const wallet = new Wallet(elem, this.contractManager.sideChainProvider); - const balance = (await wallet.getBalance()).div(BigNumber.from(1_000_000_000)).toNumber(); - this.metrics.gaugeLabels("certifier_balance", { address: wallet.address }, balance); + try { + res.set("Content-Type", this.metrics.contentType()); + this.metrics.add("status", 1); + for (const elem of this.config.relay.certifiers) { + const wallet = new Wallet(elem, this.contractManager.sideChainProvider); + const balance = (await wallet.getBalance()).div(BigNumber.from(1_000_000_000)).toNumber(); + this.metrics.gaugeLabels("certifier_balance", { address: wallet.address }, balance); + } + res.end(await this.metrics.metrics()); + } catch (error: any) { + return res.status(500); } - res.end(await this.metrics.metrics()); } } From a257359e910c530868eb81580d1718b5b3880bd8 Mon Sep 17 00:00:00 2001 From: Michael Kim Date: Thu, 12 Sep 2024 15:27:08 +0900 Subject: [PATCH 2/2] Add a scheduler to measure the BOA balance of administrator accounts --- packages/relay/config/config.yaml | 5 +- packages/relay/src/main.ts | 7 +- packages/relay/src/routers/DefaultRouter.ts | 6 -- .../scheduler/MetricsCertifierScheduler.ts | 91 +++++++++++++++++++ 4 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 packages/relay/src/scheduler/MetricsCertifierScheduler.ts diff --git a/packages/relay/config/config.yaml b/packages/relay/config/config.yaml index cbe9d5e..682db3c 100644 --- a/packages/relay/config/config.yaml +++ b/packages/relay/config/config.yaml @@ -65,12 +65,15 @@ scheduler: - name: purchase enable: true expression: "*/1 * * * * *" - - name: delegatorApproval + - name: delegator_approval enable: true expression: "*/5 * * * * *" - name: metrics enable: true expression: "*/5 * * * * *" + - name: metrics_certifier + enable: true + expression: "*/5 * * * * *" relay: certifiers: diff --git a/packages/relay/src/main.ts b/packages/relay/src/main.ts index 5bf4d3a..58e90b1 100644 --- a/packages/relay/src/main.ts +++ b/packages/relay/src/main.ts @@ -5,6 +5,7 @@ import { DefaultServer } from "./DefaultServer"; import { ApprovalScheduler } from "./scheduler/ApprovalScheduler"; import { CloseScheduler } from "./scheduler/CloseScheduler"; import { DelegatorApprovalScheduler } from "./scheduler/DelegatorApprovalScheduler"; +import { MetricsCertifierScheduler } from "./scheduler/MetricsCertifierScheduler"; import { MetricsScheduler } from "./scheduler/MetricsScheduler"; import { Scheduler } from "./scheduler/Scheduler"; import { StorePurchaseScheduler } from "./scheduler/StorePurchaseScheduler"; @@ -49,7 +50,7 @@ async function main() { if (scheduler && scheduler.enable) { schedulers.push(new StorePurchaseScheduler(scheduler.expression)); } - scheduler = config.scheduler.getScheduler("delegatorApproval"); + scheduler = config.scheduler.getScheduler("delegator_approval"); if (scheduler && scheduler.enable) { schedulers.push(new DelegatorApprovalScheduler(scheduler.expression)); } @@ -57,6 +58,10 @@ async function main() { if (scheduler && scheduler.enable) { schedulers.push(new MetricsScheduler(scheduler.expression)); } + scheduler = config.scheduler.getScheduler("metrics_certifier"); + if (scheduler && scheduler.enable) { + schedulers.push(new MetricsCertifierScheduler(scheduler.expression)); + } } const contractManager = new ContractManager(config); diff --git a/packages/relay/src/routers/DefaultRouter.ts b/packages/relay/src/routers/DefaultRouter.ts index e81b99f..e2671eb 100644 --- a/packages/relay/src/routers/DefaultRouter.ts +++ b/packages/relay/src/routers/DefaultRouter.ts @@ -5,7 +5,6 @@ import { WebService } from "../service/WebService"; import { Tspec, TspecDocsMiddleware } from "tspec"; -import { BigNumber, Wallet } from "ethers"; import express from "express"; export class DefaultRouter { @@ -60,11 +59,6 @@ export class DefaultRouter { try { res.set("Content-Type", this.metrics.contentType()); this.metrics.add("status", 1); - for (const elem of this.config.relay.certifiers) { - const wallet = new Wallet(elem, this.contractManager.sideChainProvider); - const balance = (await wallet.getBalance()).div(BigNumber.from(1_000_000_000)).toNumber(); - this.metrics.gaugeLabels("certifier_balance", { address: wallet.address }, balance); - } res.end(await this.metrics.metrics()); } catch (error: any) { return res.status(500); diff --git a/packages/relay/src/scheduler/MetricsCertifierScheduler.ts b/packages/relay/src/scheduler/MetricsCertifierScheduler.ts new file mode 100644 index 0000000..270cd4e --- /dev/null +++ b/packages/relay/src/scheduler/MetricsCertifierScheduler.ts @@ -0,0 +1,91 @@ +import "@nomiclabs/hardhat-ethers"; +import { BigNumber, Wallet } from "ethers"; +import { Config } from "../common/Config"; +import { logger } from "../common/Logger"; +import { ContractManager } from "../contract/ContractManager"; +import { Metrics } from "../metrics/Metrics"; +import { GraphStorage } from "../storage/GraphStorage"; +import { RelayStorage } from "../storage/RelayStorage"; +import { Scheduler } from "./Scheduler"; + +/** + * Creates blocks at regular intervals and stores them in IPFS and databases. + */ +export class MetricsCertifierScheduler extends Scheduler { + private _config: Config | undefined; + private _contractManager: ContractManager | undefined; + private _metrics: Metrics | undefined; + private _storage: RelayStorage | undefined; + private _graph: GraphStorage | undefined; + + constructor(expression: string) { + super(expression); + } + + private get config(): Config { + if (this._config !== undefined) return this._config; + else { + logger.error("Config is not ready yet."); + process.exit(1); + } + } + + private get metrics(): Metrics { + if (this._metrics !== undefined) return this._metrics; + else { + logger.error("Metrics is not ready yet."); + process.exit(1); + } + } + + private get storage(): RelayStorage { + if (this._storage !== undefined) return this._storage; + else { + logger.error("Storage is not ready yet."); + process.exit(1); + } + } + + private get contractManager(): ContractManager { + if (this._contractManager !== undefined) return this._contractManager; + else { + logger.error("ContractManager is not ready yet."); + process.exit(1); + } + } + + private get graph(): GraphStorage { + if (this._graph !== undefined) return this._graph; + else { + logger.error("GraphStorage is not ready yet."); + process.exit(1); + } + } + + public setOption(options: any) { + if (options) { + if (options.config && options.config instanceof Config) this._config = options.config; + if (options.contractManager && options.contractManager instanceof ContractManager) + this._contractManager = options.contractManager; + if (options.storage && options.storage instanceof RelayStorage) this._storage = options.storage; + if (options.graph && options.graph instanceof GraphStorage) this._graph = options.graph; + if (options.metrics && options.metrics instanceof Metrics) this._metrics = options.metrics; + } + } + + public async onStart() { + // + } + + protected async work() { + try { + for (const elem of this.config.relay.certifiers) { + const wallet = new Wallet(elem, this.contractManager.sideChainProvider); + const balance = (await wallet.getBalance()).div(BigNumber.from(1_000_000_000)).toNumber(); + this.metrics.gaugeLabels("certifier_balance", { address: wallet.address }, balance); + } + } catch (error) { + logger.error(`Failed to execute the MetricsBOAScheduler: ${error}`); + } + } +}