Skip to content

Commit

Permalink
Add gpu monitor to bottom bar
Browse files Browse the repository at this point in the history
  • Loading branch information
hientominh authored and hiento09 committed Jan 24, 2024
1 parent 203e97b commit 0bb5315
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 10 deletions.
5 changes: 3 additions & 2 deletions extensions/monitoring-extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@janhq/monitoring-extension",
"version": "1.0.9",
"version": "1.0.10",
"description": "This extension provides system health and OS level data",
"main": "dist/index.js",
"module": "dist/module.js",
Expand All @@ -26,6 +26,7 @@
"README.md"
],
"bundleDependencies": [
"node-os-utils"
"node-os-utils",
"@janhq/core"
]
}
54 changes: 47 additions & 7 deletions extensions/monitoring-extension/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
const nodeOsUtils = require("node-os-utils");
const getJanDataFolderPath = require("@janhq/core/node").getJanDataFolderPath;
const path = require("path");
const { readFileSync } = require("fs");
const exec = require("child_process").exec;

const NVIDIA_INFO_FILE = path.join(
getJanDataFolderPath(),
"settings",
"settings.json"
);

const getResourcesInfo = () =>
new Promise((resolve) => {
Expand All @@ -16,18 +26,48 @@ const getResourcesInfo = () =>
});

const getCurrentLoad = () =>
new Promise((resolve) => {
new Promise((resolve, reject) => {
nodeOsUtils.cpu.usage().then((cpuPercentage) => {
const response = {
cpu: {
usage: cpuPercentage,
},
let data = {
run_mode: "cpu",
gpus_in_use: [],
};
resolve(response);
if (process.platform !== "darwin") {
data = JSON.parse(readFileSync(NVIDIA_INFO_FILE, "utf-8"));
}
if (data.run_mode === "gpu" && data.gpus_in_use.length > 0) {
const gpuIds = data["gpus_in_use"].join(",");
if (gpuIds !== "") {
exec(
`nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.total,memory.free,utilization.memory --format=csv,noheader,nounits --id=${gpuIds}`,
(error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
reject(error);
return;
}
const gpuInfo = stdout.trim().split("\n").map((line) => {
const [id, name, temperature, utilization, memoryTotal, memoryFree, memoryUtilization] = line.split(", ").map(item => item.replace(/\r/g, ""));
return { id, name, temperature, utilization, memoryTotal, memoryFree, memoryUtilization };
});
resolve({
cpu: { usage: cpuPercentage },
gpu: gpuInfo
});
}
);
} else {
// Handle the case where gpuIds is empty
resolve({ cpu: { usage: cpuPercentage }, gpu: [] });
}
} else {
// Handle the case where run_mode is not 'gpu' or no GPUs are in use
resolve({ cpu: { usage: cpuPercentage }, gpu: [] });
}
});
});

module.exports = {
getResourcesInfo,
getCurrentLoad,
};
};
20 changes: 19 additions & 1 deletion web/containers/Layout/BottomBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,21 @@ const menuLinks = [

const BottomBar = () => {
const { activeModel, stateModel } = useActiveModel()
const { ram, cpu } = useGetSystemResources()
const { ram, cpu, gpus } = useGetSystemResources()
const progress = useAtomValue(appDownloadProgress)
const { downloadedModels } = useGetDownloadedModels()
const { setMainViewState } = useMainViewState()
const { downloadStates } = useDownloadState()
const setShowSelectModelModal = useSetAtom(showSelectModelModalAtom)
const [serverEnabled] = useAtom(serverEnabledAtom)

const calculateGpuMemoryUsage = (gpu: Record<string, never>) => {
const total = parseInt(gpu.memoryTotal)
const free = parseInt(gpu.memoryFree)
if (!total || !free) return 0
return Math.round(((total - free) / total) * 100)
}

return (
<div className="fixed bottom-0 left-16 z-20 flex h-12 w-[calc(100%-64px)] items-center justify-between border-t border-border bg-background/80 px-3">
<div className="flex flex-shrink-0 items-center gap-x-2">
Expand Down Expand Up @@ -117,6 +124,17 @@ const BottomBar = () => {
<SystemItem name="CPU:" value={`${cpu}%`} />
<SystemItem name="Mem:" value={`${ram}%`} />
</div>
{gpus.length > 0 && (
<div className="flex items-center gap-x-2">
{gpus.map((gpu, index) => (
<SystemItem
key={index}
name={`GPU ${gpu.id}:`}
value={`${gpu.utilization}% Util, ${calculateGpuMemoryUsage(gpu)}% Mem`}
/>
))}
</div>
)}
{/* VERSION is defined by webpack, please see next.config.js */}
<span className="text-xs text-muted-foreground">
Jan v{VERSION ?? ''}
Expand Down
4 changes: 4 additions & 0 deletions web/hooks/useGetSystemResources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
export default function useGetSystemResources() {
const [ram, setRam] = useState<number>(0)
const [cpu, setCPU] = useState<number>(0)

const [gpus, setGPUs] = useState<Record<string, never>[]>([])
const setTotalRam = useSetAtom(totalRamAtom)
const setUsedRam = useSetAtom(usedRamAtom)
const setCpuUsage = useSetAtom(cpuUsageAtom)
Expand Down Expand Up @@ -42,6 +44,7 @@ export default function useGetSystemResources() {
setRam(Math.round(ram * 100))
setCPU(Math.round(currentLoadInfor?.cpu?.usage ?? 0))
setCpuUsage(Math.round(currentLoadInfor?.cpu?.usage ?? 0))
setGPUs(currentLoadInfor?.gpu ?? [])
}

useEffect(() => {
Expand All @@ -63,5 +66,6 @@ export default function useGetSystemResources() {
totalRamAtom,
ram,
cpu,
gpus,
}
}

0 comments on commit 0bb5315

Please sign in to comment.