feat(widgets): add per-filesystem storage chart to Beszel system stats (#6209)
This commit is contained in:
1 parent
2ada1aa249
commit
0e513fffd5
4 files changed
+64
No files matched your search
@@ -3799,6 +3799,9 @@
|
||||
},
|
||||
"showDockerNetwork": {
|
||||
"label": "Show Docker network chart"
|
||||
},
|
||||
"showStorage": {
|
||||
"label": "Show storage chart"
|
||||
}
|
||||
},
|
||||
"selectSystem": "Select system",
|
||||
@@ -3834,6 +3837,11 @@
|
||||
"read": "Read",
|
||||
"write": "Write"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Storage",
|
||||
"subtitle": "Per-filesystem disk usage",
|
||||
"series": "Used"
|
||||
},
|
||||
"network": {
|
||||
"title": "Bandwidth",
|
||||
"subtitle": "Network traffic of public interfaces",
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
CPU_Y_AXIS_DOMAIN,
|
||||
useContainerNames,
|
||||
useDockerChartData,
|
||||
useEfsChartData,
|
||||
useSystemChartData,
|
||||
} from "../beszel/_shared/chart";
|
||||
import {
|
||||
@@ -185,11 +186,31 @@ export default function BeszelSystemStatsWidget({
|
||||
timePeriod,
|
||||
);
|
||||
|
||||
const efsPaths = useMemo(() => {
|
||||
if (!systemStats) return [];
|
||||
const paths = new Set<string>();
|
||||
for (const record of systemStats) {
|
||||
if (record.stats.efs) {
|
||||
for (const path of Object.keys(record.stats.efs)) {
|
||||
paths.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [...paths];
|
||||
}, [systemStats]);
|
||||
|
||||
const storageData = useEfsChartData(statsWhenShown(options.showStorage, systemStats), efsPaths, timePeriod);
|
||||
|
||||
const containerSeries = useMemo(
|
||||
() => containerNames.map((name, i) => ({ name, color: containerColors[i % containerColors.length] as string })),
|
||||
[containerNames],
|
||||
);
|
||||
|
||||
const storageSeries = useMemo(
|
||||
() => efsPaths.map((path, i) => ({ name: path, color: containerColors[i % containerColors.length] as string })),
|
||||
[efsPaths],
|
||||
);
|
||||
|
||||
const cols = gridColumns[Number(width > 600)];
|
||||
|
||||
if (systemsError) throw systemsError;
|
||||
@@ -385,6 +406,21 @@ export default function BeszelSystemStatsWidget({
|
||||
/>
|
||||
)}
|
||||
|
||||
{options.showStorage && storageData.length > 0 && storageSeries.length > 0 && (
|
||||
<BeszelChartPanel
|
||||
title={t("chart.storage.title")}
|
||||
subtitle={t("chart.storage.subtitle")}
|
||||
chartProps={{
|
||||
h: CHART_HEIGHT,
|
||||
data: storageData,
|
||||
type: "stacked",
|
||||
series: storageSeries,
|
||||
yAxisFormatter: chartAxisFormatters.bytes,
|
||||
tooltipProps: tooltipBytesTotal,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{showDocker && containerSeries.length > 0 && (
|
||||
<>
|
||||
{options.showDockerCpu && dockerCpuData.length > 0 && (
|
||||
|
||||
@@ -45,6 +45,7 @@ export const { definition, componentLoader } = createWidgetDefinition("beszelSys
|
||||
showDockerCpu: factory.switch({ defaultValue: true }),
|
||||
showDockerMemory: factory.switch({ defaultValue: true }),
|
||||
showDockerNetwork: factory.switch({ defaultValue: true }),
|
||||
showStorage: factory.switch({ defaultValue: true }),
|
||||
}));
|
||||
},
|
||||
errors: {
|
||||
|
||||
@@ -174,6 +174,25 @@ const defaultContainerExtractors: Record<string, ContainerExtractor> = {
|
||||
network: (c) => (c?.b ? c.b[0] + c.b[1] : (c?.ns ?? 0) + (c?.nr ?? 0)),
|
||||
};
|
||||
|
||||
export const useEfsChartData = (
|
||||
systemStats: BeszelSystemStatsRecord[] | undefined,
|
||||
efsPaths: string[],
|
||||
timePeriod: BeszelTimePeriod = "1h",
|
||||
) =>
|
||||
useMemo(() => {
|
||||
if (!systemStats?.length) return [];
|
||||
const { fmt, ordered } = prepareRecords(systemStats, timePeriod);
|
||||
const mapped = ordered.map((record) => {
|
||||
const point: Record<string, unknown> = { time: fmt(record.created), rawTime: record.created };
|
||||
const efs = record.stats.efs ?? {};
|
||||
for (const path of efsPaths) {
|
||||
point[path] = efs[path]?.du ?? 0;
|
||||
}
|
||||
return point;
|
||||
});
|
||||
return padTimeGrid(mapped, timePeriod);
|
||||
}, [systemStats, efsPaths, timePeriod]);
|
||||
|
||||
export const useDockerChartData = (
|
||||
containerStats: BeszelContainerStatsRecord[] | undefined,
|
||||
containerNames: string[],
|
||||
|
||||
Reference in new issue
Block a user