diff --git a/javascript/packages/cli/package.json b/javascript/packages/cli/package.json index 0e1643272..a25fb3c37 100644 --- a/javascript/packages/cli/package.json +++ b/javascript/packages/cli/package.json @@ -55,7 +55,7 @@ "dependencies": { "@zombienet/dsl-parser-wrapper": "^0.1.10", "@zombienet/orchestrator": "^0.0.81", - "@zombienet/utils": "^0.0.24", + "@zombienet/utils": "^0.0.25", "cli-progress": "^3.12.0", "commander": "^11.1.0", "debug": "^4.3.4", diff --git a/javascript/packages/orchestrator/package.json b/javascript/packages/orchestrator/package.json index ce7c47bee..188064518 100644 --- a/javascript/packages/orchestrator/package.json +++ b/javascript/packages/orchestrator/package.json @@ -40,7 +40,7 @@ "@polkadot/api": "^10.12.4", "@polkadot/keyring": "^12.6.2", "@polkadot/util-crypto": "^12.6.1", - "@zombienet/utils": "^0.0.24", + "@zombienet/utils": "^0.0.25", "chai": "^4.3.10", "debug": "^4.3.4", "execa": "^5.1.1", diff --git a/javascript/packages/orchestrator/src/orchestrator.ts b/javascript/packages/orchestrator/src/orchestrator.ts index a24ea828a..85f917680 100644 --- a/javascript/packages/orchestrator/src/orchestrator.ts +++ b/javascript/packages/orchestrator/src/orchestrator.ts @@ -14,6 +14,7 @@ import { series, setLogType, sleep, + registerSpawnElapsedTimeSecs, } from "@zombienet/utils"; import fs from "fs"; import tmp from "tmp-promise"; @@ -541,26 +542,7 @@ export async function start( const spawnEnd = performance.now(); const spawnElapsedSecs = Math.round((spawnEnd - spawnStart) / 1000); debug(`\t 🕰 [Spawn] elapsed time: ${spawnElapsedSecs} secs`); - - if ( - options?.inCI && - process.env["PUSHGATEWAY_URL"] && - process.env["CI_JOB_NAME"] - ) { - const jobId = process.env["CI_JOB_ID"]; - const jobName = process.env["CI_JOB_NAME"]; - const projectName = process.env["CI_PROJECT_NAME"] || ""; - const metricName = "zombie_network_ready_secs"; - const help = `# HELP ${metricName} Elapsed time to spawn the network in seconds`; - const type = `# TYPE ${metricName} gauge`; - const metricString = `${metricName}{job_id="${jobId}", job_name="${jobName}", project_name="${projectName}"} ${spawnElapsedSecs}`; - const body = [help, type, metricString, "\n"].join("\n"); - debug!(`Sending metric with content:\n ${body}`); - await fetch(process.env["PUSHGATEWAY_URL"], { - method: "POST", - body, - }); - } + if (options?.inCI) await registerSpawnElapsedTimeSecs(spawnElapsedSecs); // clean cache before dump the info. network.cleanMetricsCache(); diff --git a/javascript/packages/orchestrator/src/test-runner/index.ts b/javascript/packages/orchestrator/src/test-runner/index.ts index 0fe4952bc..f125c38b0 100644 --- a/javascript/packages/orchestrator/src/test-runner/index.ts +++ b/javascript/packages/orchestrator/src/test-runner/index.ts @@ -5,6 +5,7 @@ import { setLogType, sleep, LogType, + registerTotalElapsedTimeSecs, } from "@zombienet/utils"; import fs from "fs"; import Mocha from "mocha"; @@ -40,6 +41,7 @@ export async function run( dir: string | undefined, force: boolean = false, ) { + const testStart = performance.now(); logType && setLogType(logType); let network: Network; const backchannelMap: BackchannelMap = {}; @@ -131,6 +133,12 @@ export async function run( suite.afterAll("teardown", async function () { this.timeout(180 * 1000); if (network && !network.wasRunning) { + // report metric + const testEnd = performance.now(); + const elapsedSecs = Math.round((testEnd - testStart) / 1000); + debug(`\t 🕰 [Test] elapsed time: ${elapsedSecs} secs`); + if (inCI) await registerTotalElapsedTimeSecs(elapsedSecs); + const logsPath = await network.dumpLogs(false); const tests = this.test?.parent?.tests; diff --git a/javascript/packages/utils/package.json b/javascript/packages/utils/package.json index 43786b488..cbd61bf29 100644 --- a/javascript/packages/utils/package.json +++ b/javascript/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@zombienet/utils", - "version": "0.0.24", + "version": "0.0.25", "description": "Useful utilities for ZombieNet Framework", "main": "dist/index.js", "author": "Parity Technologies ", diff --git a/javascript/packages/utils/src/index.ts b/javascript/packages/utils/src/index.ts index 5e94a1457..15fa9797f 100644 --- a/javascript/packages/utils/src/index.ts +++ b/javascript/packages/utils/src/index.ts @@ -6,3 +6,4 @@ export * from "./net"; export * from "./nunjucksRelativeLoader"; export * from "./promiseSeries"; export * from "./tableCli"; +export * from "./zombieMetrics"; diff --git a/javascript/packages/utils/src/zombieMetrics.ts b/javascript/packages/utils/src/zombieMetrics.ts new file mode 100644 index 000000000..52f20788a --- /dev/null +++ b/javascript/packages/utils/src/zombieMetrics.ts @@ -0,0 +1,42 @@ +function canSend() { + return process.env["PUSHGATEWAY_URL"] && process.env["CI_JOB_NAME"]; +} + +function getFromCI() { + return [ + process.env["CI_JOB_ID"], + process.env["CI_JOB_NAME"], + process.env["CI_PROJECT_NAME"] || "", + process.env["PUSHGATEWAY_URL"], + ]; +} + +export async function registerSpawnElapsedTimeSecs(elapsed: number) { + if (canSend()) { + const [jobId, jobName, projectName, pushGatewayUrl] = getFromCI(); + const metricName = "zombie_network_ready_secs"; + const help = `# HELP ${metricName} Elapsed time to spawn the network in seconds`; + const type = `# TYPE ${metricName} gauge`; + const metricString = `${metricName}{job_id="${jobId}", job_name="${jobName}", project_name="${projectName}"} ${elapsed}`; + const body = [help, type, metricString, "\n"].join("\n"); + await fetch(pushGatewayUrl!, { + method: "POST", + body, + }); + } +} + +export async function registerTotalElapsedTimeSecs(elapsed: number) { + if (canSend()) { + const [jobId, jobName, projectName, pushGatewayUrl] = getFromCI(); + const metricName = "zombie_test_complete_secs"; + const help = `# HELP ${metricName} Elapsed time to complete the test job in seconds (including spawning, but not teardown)`; + const type = `# TYPE ${metricName} gauge`; + const metricString = `${metricName}{job_id="${jobId}", job_name="${jobName}", project_name="${projectName}"} ${elapsed}`; + const body = [help, type, metricString, "\n"].join("\n"); + await fetch(pushGatewayUrl!, { + method: "POST", + body, + }); + } +}