more updates

This commit is contained in:
henrygd
2026-03-03 16:32:50 -05:00
parent bdbd135fdd
commit 016d775675
4 changed files with 89 additions and 5 deletions

View File

@@ -82,14 +82,18 @@ func (pm *pveManager) getPVEStats() ([]*container.PveNodeStats, error) {
var sent_delta, recv_delta float64 var sent_delta, recv_delta float64
if initialized { if initialized {
secondsElapsed := time.Since(resourceStats.PrevReadTime).Seconds() secondsElapsed := time.Since(resourceStats.PrevReadTime).Seconds()
sent_delta = float64(total_sent-resourceStats.PrevNet.Sent) / secondsElapsed if secondsElapsed > 0 {
recv_delta = float64(total_recv-resourceStats.PrevNet.Recv) / secondsElapsed sent_delta = float64(total_sent-resourceStats.PrevNet.Sent) / secondsElapsed
recv_delta = float64(total_recv-resourceStats.PrevNet.Recv) / secondsElapsed
}
} }
resourceStats.PrevNet.Sent = total_sent
resourceStats.PrevNet.Recv = total_recv
resourceStats.PrevReadTime = time.Now() resourceStats.PrevReadTime = time.Now()
// Update final stats values // Update final stats values
resourceStats.Cpu = twoDecimals(100.0 * resource.CPU * float64(resource.MaxCPU) / float64(pm.cpuCount)) resourceStats.Cpu = twoDecimals(100.0 * resource.CPU * float64(resource.MaxCPU) / float64(pm.cpuCount))
resourceStats.Mem = float64(resource.Mem) resourceStats.Mem = bytesToMegabytes(float64(resource.Mem))
resourceStats.Bandwidth = [2]uint64{uint64(sent_delta), uint64(recv_delta)} resourceStats.Bandwidth = [2]uint64{uint64(sent_delta), uint64(recv_delta)}
stats = append(stats, resourceStats) stats = append(stats, resourceStats)

View File

@@ -23,14 +23,16 @@ export default memo(function ContainerChart({
chartType, chartType,
chartConfig, chartConfig,
unit = "%", unit = "%",
filterStore = $containerFilter,
}: { }: {
dataKey: string dataKey: string
chartData: ChartData chartData: ChartData
chartType: ChartType chartType: ChartType
chartConfig: ChartConfig chartConfig: ChartConfig
unit?: string unit?: string
filterStore?: typeof $containerFilter
}) { }) {
const filter = useStore($containerFilter) const filter = useStore(filterStore)
const userSettings = useStore($userSettings) const userSettings = useStore($userSettings)
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth() const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()

View File

@@ -25,6 +25,7 @@ import {
$containerFilter, $containerFilter,
$direction, $direction,
$maxValues, $maxValues,
$pveFilter,
$systems, $systems,
$temperatureFilter, $temperatureFilter,
$userSettings, $userSettings,
@@ -160,6 +161,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
const [system, setSystem] = useState({} as SystemRecord) const [system, setSystem] = useState({} as SystemRecord)
const [systemStats, setSystemStats] = useState([] as SystemStatsRecord[]) const [systemStats, setSystemStats] = useState([] as SystemStatsRecord[])
const [containerData, setContainerData] = useState([] as ChartData["containerData"]) const [containerData, setContainerData] = useState([] as ChartData["containerData"])
const [pveData, setPveData] = useState([] as ChartData["containerData"])
const temperatureChartRef = useRef<HTMLDivElement>(null) const temperatureChartRef = useRef<HTMLDivElement>(null)
const persistChartTime = useRef(false) const persistChartTime = useRef(false)
const [bottomSpacing, setBottomSpacing] = useState(0) const [bottomSpacing, setBottomSpacing] = useState(0)
@@ -177,8 +179,10 @@ export default memo(function SystemDetail({ id }: { id: string }) {
persistChartTime.current = false persistChartTime.current = false
setSystemStats([]) setSystemStats([])
setContainerData([]) setContainerData([])
setPveData([])
setDetails({} as SystemDetailsRecord) setDetails({} as SystemDetailsRecord)
$containerFilter.set("") $containerFilter.set("")
$pveFilter.set("")
} }
}, [id]) }, [id])
@@ -277,6 +281,10 @@ export default memo(function SystemDetail({ id }: { id: string }) {
// Share chart config computation for all container charts // Share chart config computation for all container charts
const containerChartConfigs = useContainerChartConfigs(containerData) const containerChartConfigs = useContainerChartConfigs(containerData)
// PVE chart data and configs
const pveSyntheticChartData = useMemo(() => ({ ...chartData, containerData: pveData }), [chartData, pveData])
const pveChartConfigs = useContainerChartConfigs(pveData)
// make container stats for charts // make container stats for charts
const makeContainerData = useCallback((containers: ContainerStatsRecord[]) => { const makeContainerData = useCallback((containers: ContainerStatsRecord[]) => {
const containerData = [] as ChartData["containerData"] const containerData = [] as ChartData["containerData"]
@@ -307,7 +315,8 @@ export default memo(function SystemDetail({ id }: { id: string }) {
Promise.allSettled([ Promise.allSettled([
getStats<SystemStatsRecord>("system_stats", system, chartTime), getStats<SystemStatsRecord>("system_stats", system, chartTime),
getStats<ContainerStatsRecord>("container_stats", system, chartTime), getStats<ContainerStatsRecord>("container_stats", system, chartTime),
]).then(([systemStats, containerStats]) => { getStats<ContainerStatsRecord>("pve_stats", system, chartTime),
]).then(([systemStats, containerStats, pveStats]) => {
// loading: false // loading: false
setChartLoading(false) setChartLoading(false)
@@ -334,6 +343,17 @@ export default memo(function SystemDetail({ id }: { id: string }) {
cache.set(cs_cache_key, containerData) cache.set(cs_cache_key, containerData)
} }
setContainerData(makeContainerData(containerData)) setContainerData(makeContainerData(containerData))
// make new pve stats
const ps_cache_key = `${system.id}_${chartTime}_pve_stats`
let pveRecords = (cache.get(ps_cache_key) || []) as ContainerStatsRecord[]
if (pveStats.status === "fulfilled" && pveStats.value.length) {
pveRecords = pveRecords.concat(addEmptyValues(pveRecords, pveStats.value, expectedInterval))
if (pveRecords.length > 120) {
pveRecords = pveRecords.slice(-100)
}
cache.set(ps_cache_key, pveRecords)
}
setPveData(makeContainerData(pveRecords))
}) })
}, [system, chartTime]) }, [system, chartTime])
@@ -399,6 +419,7 @@ export default memo(function SystemDetail({ id }: { id: string }) {
const showMax = maxValues && isLongerChart const showMax = maxValues && isLongerChart
const containerFilterBar = containerData.length ? <FilterBar /> : null const containerFilterBar = containerData.length ? <FilterBar /> : null
const pveFilterBar = pveData.length ? <FilterBar store={$pveFilter} /> : null
const dataEmpty = !chartLoading && chartData.systemStats.length === 0 const dataEmpty = !chartLoading && chartData.systemStats.length === 0
const lastGpus = systemStats.at(-1)?.stats?.g const lastGpus = systemStats.at(-1)?.stats?.g
@@ -493,6 +514,24 @@ export default memo(function SystemDetail({ id }: { id: string }) {
</ChartCard> </ChartCard>
)} )}
{pveFilterBar && (
<ChartCard
empty={dataEmpty}
grid={grid}
title={t`Proxmox CPU Usage`}
description={t`Average CPU utilization of VMs and containers`}
cornerEl={pveFilterBar}
>
<ContainerChart
chartData={pveSyntheticChartData}
dataKey="c"
chartType={ChartType.CPU}
chartConfig={pveChartConfigs.cpu}
filterStore={$pveFilter}
/>
</ChartCard>
)}
<ChartCard <ChartCard
empty={dataEmpty} empty={dataEmpty}
grid={grid} grid={grid}
@@ -520,6 +559,24 @@ export default memo(function SystemDetail({ id }: { id: string }) {
</ChartCard> </ChartCard>
)} )}
{pveFilterBar && (
<ChartCard
empty={dataEmpty}
grid={grid}
title={t`Proxmox Memory Usage`}
description={t`Memory usage of Proxmox VMs and containers`}
cornerEl={pveFilterBar}
>
<ContainerChart
chartData={pveSyntheticChartData}
dataKey="m"
chartType={ChartType.Memory}
chartConfig={pveChartConfigs.memory}
filterStore={$pveFilter}
/>
</ChartCard>
)}
<ChartCard empty={dataEmpty} grid={grid} title={t`Disk Usage`} description={t`Usage of root partition`}> <ChartCard empty={dataEmpty} grid={grid} title={t`Disk Usage`} description={t`Usage of root partition`}>
<DiskChart chartData={chartData} dataKey="stats.du" diskSize={systemStats.at(-1)?.stats.d ?? NaN} /> <DiskChart chartData={chartData} dataKey="stats.du" diskSize={systemStats.at(-1)?.stats.d ?? NaN} />
</ChartCard> </ChartCard>
@@ -641,6 +698,24 @@ export default memo(function SystemDetail({ id }: { id: string }) {
</ChartCard> </ChartCard>
)} )}
{pveFilterBar && pveData.length > 0 && (
<ChartCard
empty={dataEmpty}
grid={grid}
title={t`Proxmox Network I/O`}
description={t`Network traffic of Proxmox VMs and containers`}
cornerEl={pveFilterBar}
>
<ContainerChart
chartData={pveSyntheticChartData}
chartType={ChartType.Network}
dataKey="n"
chartConfig={pveChartConfigs.network}
filterStore={$pveFilter}
/>
</ChartCard>
)}
{/* Swap chart */} {/* Swap chart */}
{(systemStats.at(-1)?.stats.su ?? 0) > 0 && ( {(systemStats.at(-1)?.stats.su ?? 0) > 0 && (
<ChartCard <ChartCard

View File

@@ -55,6 +55,9 @@ listenKeys($userSettings, ["chartTime"], ({ chartTime }) => $chartTime.set(chart
/** Container chart filter */ /** Container chart filter */
export const $containerFilter = atom("") export const $containerFilter = atom("")
/** PVE chart filter */
export const $pveFilter = atom("")
/** Temperature chart filter */ /** Temperature chart filter */
export const $temperatureFilter = atom("") export const $temperatureFilter = atom("")