mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-07-29 20:24:36 +02:00
chore(dev): tweak backend-memory-report
This commit is contained in:
41
.github/scripts/backend-memory-report.mjs
vendored
41
.github/scripts/backend-memory-report.mjs
vendored
@@ -287,10 +287,25 @@ function getHeapSnapshotCategoryValue(report, phase, category) {
|
||||
return Number.isFinite(value) ? value : null;
|
||||
}
|
||||
|
||||
function getHeapSnapshotBreakdownEntries(report, phase, category) {
|
||||
const breakdown = report?.[phase]?.heapSnapshot?.breakdowns?.[category];
|
||||
if (breakdown == null || typeof breakdown !== 'object') return [];
|
||||
|
||||
return Object.entries(breakdown)
|
||||
.filter(([, value]) => Number.isFinite(value) && value > 0)
|
||||
.toSorted((a, b) => b[1] - a[1]);
|
||||
}
|
||||
|
||||
function escapeCsvValue(value) {
|
||||
return `"${String(value).replaceAll('"', '""')}"`;
|
||||
}
|
||||
|
||||
function formatSankeyValue(value) {
|
||||
const rounded = Math.round(value * 100) / 100;
|
||||
if (Number.isInteger(rounded)) return String(rounded);
|
||||
return rounded.toFixed(2).replace(/0+$/, '').replace(/\.$/, '');
|
||||
}
|
||||
|
||||
function renderHeapSnapshotSankey(report, phase, title) {
|
||||
const total = getHeapSnapshotCategoryValue(report, phase, 'Total');
|
||||
if (total == null || total <= 0) return null;
|
||||
@@ -300,9 +315,13 @@ function renderHeapSnapshotSankey(report, phase, title) {
|
||||
.map(category => {
|
||||
const value = getHeapSnapshotCategoryValue(report, phase, category);
|
||||
if (value == null || value <= 0) return null;
|
||||
const breakdownEntries = getHeapSnapshotBreakdownEntries(report, phase, category);
|
||||
const breakdownTotal = breakdownEntries.reduce((sum, [, childValue]) => sum + childValue, 0);
|
||||
return {
|
||||
category,
|
||||
value,
|
||||
breakdownTotal,
|
||||
breakdownEntries,
|
||||
};
|
||||
})
|
||||
.filter(value => value != null);
|
||||
@@ -312,8 +331,13 @@ function renderHeapSnapshotSankey(report, phase, title) {
|
||||
const nodeColors = {
|
||||
[title]: heapSnapshotCategoriesColorsHex.Total,
|
||||
};
|
||||
for (const { category } of categories) {
|
||||
nodeColors[category] = heapSnapshotCategoriesColorsHex[category];
|
||||
for (const { category, breakdownEntries } of categories) {
|
||||
const categoryColor = heapSnapshotCategoriesColorsHex[category] ?? heapSnapshotCategoriesColorsHex.Total;
|
||||
nodeColors[category] = categoryColor;
|
||||
|
||||
for (const [childName] of breakdownEntries) {
|
||||
nodeColors[`${category}: ${childName}`] = categoryColor;
|
||||
}
|
||||
}
|
||||
|
||||
const lines = [
|
||||
@@ -327,11 +351,16 @@ function renderHeapSnapshotSankey(report, phase, title) {
|
||||
nodeColors,
|
||||
},
|
||||
})}}%%`,
|
||||
'sankey',
|
||||
'sankey-beta',
|
||||
];
|
||||
|
||||
for (const { category, value } of categories) {
|
||||
lines.push(`${escapeCsvValue(title)},${escapeCsvValue(category)},${value}`);
|
||||
for (const { category, value, breakdownTotal, breakdownEntries } of categories) {
|
||||
lines.push(`${escapeCsvValue(title)},${escapeCsvValue(category)},${formatSankeyValue(value)}`);
|
||||
|
||||
for (const [childName, childValue] of breakdownEntries) {
|
||||
const normalizedValue = breakdownTotal > 0 ? childValue * value / breakdownTotal : childValue;
|
||||
lines.push(`${escapeCsvValue(category)},${escapeCsvValue(`${category}: ${childName}`)},${formatSankeyValue(normalizedValue)}`);
|
||||
}
|
||||
}
|
||||
|
||||
lines.push('```');
|
||||
@@ -653,7 +682,7 @@ const head = JSON.parse(await readFile(headFile, 'utf8'));
|
||||
const baseJsFootprint = baseJsFootprintFile == null ? null : JSON.parse(await readFile(baseJsFootprintFile, 'utf8'));
|
||||
const headJsFootprint = headJsFootprintFile == null ? null : JSON.parse(await readFile(headJsFootprintFile, 'utf8'));
|
||||
const lines = [
|
||||
'## Backend Memory Usage Report',
|
||||
'## ⚙️ Backend Memory Usage Report',
|
||||
'',
|
||||
];
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ function readIntegerEnv(name, defaultValue, min) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const HEAP_SNAPSHOT_BREAKDOWN_TOP_N = readIntegerEnv('MK_MEMORY_HEAP_SNAPSHOT_BREAKDOWN_TOP_N', 6, 1);
|
||||
|
||||
function commandName(command) {
|
||||
if (process.platform !== 'win32') return command;
|
||||
if (command === 'pnpm') return 'pnpm.cmd';
|
||||
@@ -111,6 +113,51 @@ function median(values) {
|
||||
return Math.round((sorted[center - 1] + sorted[center]) / 2);
|
||||
}
|
||||
|
||||
function summarizeHeapSnapshotBreakdowns(samples, phase) {
|
||||
const breakdowns = {};
|
||||
|
||||
for (const category of heapSnapshotCategories) {
|
||||
if (category === 'Total') continue;
|
||||
|
||||
const childKeys = new Set();
|
||||
for (const sample of samples) {
|
||||
for (const childKey of Object.keys(sample[phase]?.heapSnapshot?.breakdowns?.[category] ?? {})) {
|
||||
childKeys.add(childKey);
|
||||
}
|
||||
}
|
||||
|
||||
const categoryBreakdown = {};
|
||||
for (const childKey of childKeys) {
|
||||
const values = samples
|
||||
.map(sample => sample[phase]?.heapSnapshot?.breakdowns?.[category]?.[childKey])
|
||||
.filter(value => Number.isFinite(value));
|
||||
|
||||
if (values.length > 0) categoryBreakdown[childKey] = median(values);
|
||||
}
|
||||
|
||||
if (Object.keys(categoryBreakdown).length > 0) {
|
||||
breakdowns[category] = collapseHeapSnapshotBreakdown(categoryBreakdown);
|
||||
}
|
||||
}
|
||||
|
||||
return breakdowns;
|
||||
}
|
||||
|
||||
function collapseHeapSnapshotBreakdown(breakdown) {
|
||||
const entries = Object.entries(breakdown)
|
||||
.filter(([, value]) => value > 0)
|
||||
.toSorted((a, b) => b[1] - a[1]);
|
||||
|
||||
const topEntries = entries.slice(0, HEAP_SNAPSHOT_BREAKDOWN_TOP_N);
|
||||
const otherValue = entries
|
||||
.slice(HEAP_SNAPSHOT_BREAKDOWN_TOP_N)
|
||||
.reduce((sum, [, value]) => sum + value, 0);
|
||||
|
||||
const collapsed = Object.fromEntries(topEntries);
|
||||
if (otherValue > 0) collapsed.Other = otherValue;
|
||||
return collapsed;
|
||||
}
|
||||
|
||||
function summarizeSamples(samples) {
|
||||
const summary = {};
|
||||
|
||||
@@ -151,9 +198,12 @@ function summarizeSamples(samples) {
|
||||
}
|
||||
|
||||
if (Object.keys(heapSnapshotCategoryValues).length > 0) {
|
||||
const heapSnapshotBreakdowns = summarizeHeapSnapshotBreakdowns(samples, phase);
|
||||
|
||||
summary[phase].heapSnapshot = {
|
||||
categories: heapSnapshotCategoryValues,
|
||||
nodeCounts: heapSnapshotNodeCountValues,
|
||||
...(Object.keys(heapSnapshotBreakdowns).length > 0 ? { breakdowns: heapSnapshotBreakdowns } : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user