@57block/stellar-resource-usage
Version:
A library that provides convenient ways to monitor and analyze the resources consumed by smart contracts during execution
142 lines • 5.01 kB
JavaScript
import CliTable3 from 'cli-table3';
import Colors from '@colors/colors';
import { STELLAR_LIMITS_CURSORS } from '@/types/enums';
import { MetricKeys, STELLAR_LIMITS_CONFIG } from '@/constants';
const calcStatistics = (store) => {
const res = {};
const metricKeys = [
'cpu_insns',
'mem_bytes',
'entry_bytes',
'entry_reads',
'entry_writes',
'read_bytes',
'write_bytes',
'min_txn_bytes',
];
Object.entries(store).forEach(([contractName, funcs]) => {
res[contractName] = {};
Object.entries(funcs).forEach(([funcName, data]) => {
const times = data.length;
metricKeys.forEach((key) => {
if (!data[0][key]) {
return;
}
let sum = 0;
let max = data[0][key];
let min = data[0][key];
data.forEach((metric) => {
const value = metric[key] || 0;
sum += value;
if (value > max) {
max = value;
}
if (value < min) {
min = value;
}
});
const avg = sum / times;
if (!res[contractName]) {
res[contractName] = {};
}
if (!res[contractName][funcName]) {
res[contractName][funcName] = {};
}
res[contractName][funcName][key] = { avg, max, min, sum };
});
res[contractName][funcName].times = times;
});
});
return res;
};
export const loadTableDataV2 = (statistics) => {
const res = [];
Object.entries(statistics).forEach(([_, funcs]) => {
Object.entries(funcs).forEach(([func, data]) => {
const times = data.times;
const trData = [];
MetricKeys.forEach((key) => {
if (!data[key]) {
return;
}
const { avg, max, min, sum } = data[key];
const limitation = STELLAR_LIMITS_CONFIG[key].value;
trData.push([key, limitation, avg, max, min, sum]);
});
res.push({
func,
times,
data: trData,
});
});
});
return res;
};
export const printTableV2 = (contractId, store) => {
// printTableInfo();
const cliTable = new CliTable3({
style: { head: [], border: [] },
});
cliTable.push([
{
colSpan: 6,
content: Colors.brightCyan.bold('Resource Usage Table'),
hAlign: 'center',
},
]);
const labelTr = [
{ content: Colors.brightCyan.bold('Highligh Color'), colSpan: 2 },
{
content: Colors.brightYellow.bold(`Warning: ${STELLAR_LIMITS_CURSORS.DANGER * 100}% - ${STELLAR_LIMITS_CURSORS.ERROR * 100}%`),
colSpan: 2,
},
{ content: Colors.brightRed.bold(`Error: Over ${STELLAR_LIMITS_CURSORS.ERROR * 100}%`), colSpan: 2 },
];
const contractTr = [
{ content: Colors.brightCyan.bold('Contract'), colSpan: 2 },
{ content: contractId, colSpan: 4 },
];
cliTable.push(labelTr);
cliTable.push(contractTr);
const statistics = calcStatistics(store);
const res = loadTableDataV2(statistics);
res.forEach(({ func, times, data }) => {
const funcTr = [
Colors.brightCyan.bold('Function'),
{
content: func,
colSpan: 2,
},
Colors.brightCyan.bold('Times'),
{
content: times,
colSpan: 2,
},
];
cliTable.push(funcTr);
const functionTableHead = ['Resource', 'Limitation', 'Avg', 'Max', 'Min', 'Sum'].map((item) => Colors.brightCyan.bold(item));
cliTable.push(functionTableHead);
data.forEach(([key, limitation, avg, max, min, sum]) => {
const average = formatTableCell(avg, limitation);
const maximum = formatTableCell(max, limitation);
const minimum = formatTableCell(min, limitation);
cliTable.push([Colors.brightCyan.bold(key), limitation, average, maximum, minimum, sum]);
});
});
console.log(cliTable.toString());
};
const formatTableCell = (cellValue, limit) => {
// calculate the percentage
const percent = parseFloat(((Number(cellValue) / Number(limit)) * 100).toFixed(2));
// set the color based on the percentage
const isDanger = percent > STELLAR_LIMITS_CURSORS.DANGER * 100;
const isError = percent > STELLAR_LIMITS_CURSORS.ERROR * 100;
if (isError) {
return Colors.brightRed.bold(cellValue.toString());
}
if (isDanger) {
return Colors.brightYellow.bold(cellValue.toString());
}
return cellValue;
};
//# sourceMappingURL=index.js.map