Merge pull request #79 from useblacksmith/wire-metrics

*: report metrics to the VM agent
This commit is contained in:
Aditya Maru 2024-12-20 19:18:02 -05:00 committed by GitHub
commit e836937c09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 1497 additions and 19 deletions

6
babel.config.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript'
]
};

14
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -6,8 +6,12 @@ const config: Config.InitialOptions = {
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
'^.+\\.ts$': 'ts-jest',
'^.+\\.js$': 'babel-jest'
},
transformIgnorePatterns: [
'/node_modules/(?!(@buf|@connectrpc)/)'
],
verbose: true,
collectCoverage: true,
collectCoverageFrom: [

1435
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@
"packageManager": "yarn@3.6.3",
"dependencies": {
"@actions/core": "^1.10.1",
"@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20241213043610-906584953dd9.2",
"@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20241220192643-e85a9caa965d.2",
"@connectrpc/connect": "^1.6.1",
"@connectrpc/connect-node": "^1.6.1",
"@docker/actions-toolkit": "0.37.1",
@ -38,11 +38,15 @@
"portfinder": "^1.0.32"
},
"devDependencies": {
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/preset-typescript": "^7.26.0",
"@types/jest": "^29.5.14",
"@types/node": "^20.12.12",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"@vercel/ncc": "^0.38.1",
"babel-jest": "^29.7.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jest": "^28.5.0",

View File

@ -3,6 +3,7 @@ import * as main from '../main';
import * as reporter from '../reporter';
import {getDockerfilePath} from '../context';
import * as setupBuilder from '../setup_builder';
import { Metric_MetricType } from "@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb";
jest.mock('@actions/core', () => ({
debug: jest.fn(),
@ -20,9 +21,14 @@ jest.mock('../context', () => ({
Inputs: jest.fn()
}));
jest.mock('../reporter', () => ({
reportBuildPushActionFailure: jest.fn().mockResolvedValue(undefined)
}));
jest.mock('../reporter', () => {
const actual = jest.requireActual('../reporter');
return {
...actual,
reportBuildPushActionFailure: jest.fn().mockResolvedValue(undefined),
reportMetric: jest.fn().mockImplementation((type: Metric_MetricType) => Promise.resolve())
};
});
jest.mock('../setup_builder', () => ({
...jest.requireActual('../setup_builder'),

View File

@ -21,6 +21,7 @@ import {promisify} from 'util';
import {exec} from 'child_process';
import * as reporter from './reporter';
import {setupStickyDisk, startAndConfigureBuildkitd, getNumCPUs} from './setup_builder';
import { Metric, Metric_MetricType } from "@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb";
const buildxVersion = 'v0.17.0';
const mountPoint = '/var/lib/buildkit';
@ -73,9 +74,16 @@ export async function startBlacksmithBuilder(inputs: context.Inputs): Promise<{a
if (!dockerfilePath) {
throw new Error('Failed to resolve dockerfile path');
}
const stickyDiskStartTime = Date.now();
const stickyDiskSetup = await setupStickyDisk(dockerfilePath);
const stickyDiskDurationMs = Date.now() - stickyDiskStartTime;
await reporter.reportMetric(Metric_MetricType.BPA_HOTLOAD_DURATION_MS, stickyDiskDurationMs);
const parallelism = await getNumCPUs();
const buildkitdStartTime = Date.now();
const buildkitdAddr = await startAndConfigureBuildkitd(parallelism, stickyDiskSetup.device);
const buildkitdDurationMs = Date.now() - buildkitdStartTime;
await reporter.reportMetric(Metric_MetricType.BPA_BUILDKITD_READY_DURATION_MS, buildkitdDurationMs);
return {addr: buildkitdAddr, buildId: stickyDiskSetup.buildId || null, exposeId: stickyDiskSetup.exposeId};
} catch (error) {
@ -100,6 +108,7 @@ export async function startBlacksmithBuilder(inputs: context.Inputs): Promise<{a
actionsToolkit.run(
// main
async () => {
await reporter.reportMetric(Metric_MetricType.BPA_FEATURE_USAGE, 1);
const startedTime = new Date();
const inputs: context.Inputs = await context.getInputs();
stateHelper.setInputs(inputs);
@ -317,7 +326,10 @@ actionsToolkit.run(
try {
const {stdout} = await execAsync('pgrep buildkitd');
if (stdout.trim()) {
const buildkitdShutdownStartTime = Date.now();
await shutdownBuildkitd();
const buildkitdShutdownDurationMs = Date.now() - buildkitdShutdownStartTime;
await reporter.reportMetric(Metric_MetricType.BPA_BUILDKITD_SHUTDOWN_DURATION_MS, buildkitdShutdownDurationMs);
core.info('Shutdown buildkitd');
}
} catch (error) {

View File

@ -6,6 +6,7 @@ import FormData from 'form-data';
import { createClient } from "@connectrpc/connect";
import { createGrpcTransport } from "@connectrpc/connect-node";
import { StickyDiskService } from "@buf/blacksmith_vm-agent.connectrpc_es/stickydisk/v1/stickydisk_connect";
import { Metric, Metric_MetricType } from "@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb";
// Configure base axios instance for Blacksmith API.
const createBlacksmithAPIClient = () => {
@ -174,4 +175,26 @@ export async function post(client: AxiosInstance, url: string, formData: FormDat
},
signal: options?.signal
});
}
export async function reportMetric(
metricType: Metric_MetricType,
value: number
): Promise<void> {
try {
const agentClient = createBlacksmithAgentClient();
const metric = new Metric({
type: metricType,
value: { case: "intValue", value: BigInt(value) }
});
await agentClient.reportMetric({
repoName: process.env.GITHUB_REPO_NAME || '',
region: process.env.BLACKSMITH_REGION || 'eu-central',
metric: metric
});
} catch (error) {
core.warning('Error reporting metric to BlacksmithAgent:', error);
}
}