[AGS] SysInfo: Re-Structure for better perf
This commit is contained in:
parent
090492ae51
commit
11c961bfe7
@ -1,88 +1,6 @@
|
|||||||
import { exec, execAsync, interval, Variable } from "astal";
|
import { exec } from "astal";
|
||||||
import { Gtk } from "astal/gtk4";
|
import { Gtk } from "astal/gtk4";
|
||||||
|
import sysinfo from "../sysinfo";
|
||||||
const FETCH_INTERVAL = 2000;
|
|
||||||
|
|
||||||
const cpuUtil = Variable("0%");
|
|
||||||
const ramUtil = Variable("0%");
|
|
||||||
const ramUsed = Variable("0MiB");
|
|
||||||
const gpuUtil = Variable("0%");
|
|
||||||
let gpuName = "card1";
|
|
||||||
let enabled = false;
|
|
||||||
|
|
||||||
const refreshStats = (): Stats => {
|
|
||||||
gpuName = exec(`/bin/bash -c "ls /sys/class/drm/ | grep '^card[0-9]*$'"`);
|
|
||||||
const cpuNameInSensors = "CPUTIN";
|
|
||||||
const stats = {
|
|
||||||
kernel: exec("uname -sr"),
|
|
||||||
cpuTemp: exec(
|
|
||||||
`/bin/bash -c "sensors | grep -m1 ${cpuNameInSensors} | awk '{print $2}'"`,
|
|
||||||
),
|
|
||||||
cpuClk: exec(
|
|
||||||
`awk '/cpu MHz/ {sum+=$4; ++n} END {print sum/n " MHz"}' /proc/cpuinfo`,
|
|
||||||
),
|
|
||||||
gpuTemp: exec(
|
|
||||||
`/bin/bash -c "sensors | grep -E 'edge' | awk '{print $2}'"`,
|
|
||||||
),
|
|
||||||
gpuClk: exec(
|
|
||||||
`/bin/bash -c "cat /sys/class/drm/${gpuName}/device/pp_dpm_sclk | grep '\\*' | awk '{print $2 $3}'"`,
|
|
||||||
),
|
|
||||||
vram:
|
|
||||||
Math.round(
|
|
||||||
parseInt(
|
|
||||||
exec(
|
|
||||||
`cat /sys/class/drm/${gpuName}/device/mem_info_vram_used`,
|
|
||||||
),
|
|
||||||
) /
|
|
||||||
1024 /
|
|
||||||
1024,
|
|
||||||
) + "MiB",
|
|
||||||
availableVRAM:
|
|
||||||
Math.round(
|
|
||||||
parseInt(
|
|
||||||
exec(
|
|
||||||
`cat /sys/class/drm/${gpuName}/device/mem_info_vram_total`,
|
|
||||||
),
|
|
||||||
) /
|
|
||||||
1024 /
|
|
||||||
1024,
|
|
||||||
) + "MiB",
|
|
||||||
};
|
|
||||||
|
|
||||||
return stats;
|
|
||||||
};
|
|
||||||
|
|
||||||
const systemStats: Variable<Stats> = Variable(refreshStats());
|
|
||||||
|
|
||||||
const availableFeatures = {
|
|
||||||
cpu: true,
|
|
||||||
ram: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const featureTest = () => {
|
|
||||||
// Check if awk & sed are available
|
|
||||||
try {
|
|
||||||
exec("awk -V");
|
|
||||||
exec("sed --version");
|
|
||||||
enabled = true;
|
|
||||||
} catch (e) {
|
|
||||||
printerr(
|
|
||||||
"[ SysInfo ] AWK or SED missing! No system info will be available",
|
|
||||||
);
|
|
||||||
enabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if mpstat is available
|
|
||||||
try {
|
|
||||||
exec("mpstat -V");
|
|
||||||
} catch (e) {
|
|
||||||
availableFeatures.cpu = false;
|
|
||||||
printerr(
|
|
||||||
"[ SysInfo ] Feature Test for CPU info failed. mpstat from the sysstat package missing!",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const info = () => {
|
const info = () => {
|
||||||
return (
|
return (
|
||||||
@ -96,12 +14,12 @@ const info = () => {
|
|||||||
vexpand
|
vexpand
|
||||||
halign={Gtk.Align.START}
|
halign={Gtk.Align.START}
|
||||||
hexpand
|
hexpand
|
||||||
label={ramUsed(used => {
|
label={sysinfo.ramUsed(used => {
|
||||||
return "RAM: " + used + ` (${ramUtil.get()}%)`;
|
return "RAM: " + used + ` (${sysinfo.ramUtil.get()}%)`;
|
||||||
})}
|
})}
|
||||||
></label>
|
></label>
|
||||||
<label
|
<label
|
||||||
label={systemStats(stats => {
|
label={sysinfo.systemStats(stats => {
|
||||||
return `CPU: ${stats.cpuTemp}, ${stats.cpuClk}
|
return `CPU: ${stats.cpuTemp}, ${stats.cpuClk}
|
||||||
GPU: ${stats.gpuTemp}, ${stats.gpuClk} (${stats.vram} / ${stats.availableVRAM})
|
GPU: ${stats.gpuTemp}, ${stats.gpuClk} (${stats.vram} / ${stats.availableVRAM})
|
||||||
Kernel: ${stats.kernel}`;
|
Kernel: ${stats.kernel}`;
|
||||||
@ -125,69 +43,35 @@ const SystemInformationPanel = () => {
|
|||||||
return popover;
|
return popover;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sysInfoFetcher = () => {
|
|
||||||
if (enabled) {
|
|
||||||
if (availableFeatures.cpu) {
|
|
||||||
execAsync(`/bin/fish -c cpu-utilization`).then(v => {
|
|
||||||
cpuUtil.set("" + Math.round(parseFloat(v)));
|
|
||||||
}).catch( e => {
|
|
||||||
console.error( e );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
if (availableFeatures.ram) {
|
|
||||||
execAsync(
|
|
||||||
`/bin/bash -c "free | awk '/Mem:/ {print $3 \\" \\" $2}'"`,
|
|
||||||
).then( v => {
|
|
||||||
const util = parseInt( v.split( ' ' )[ 0 ] );
|
|
||||||
const available = parseInt( v.split( ' ' )[ 1 ] );
|
|
||||||
ramUtil.set( "" + Math.round( available / util ) );
|
|
||||||
ramUsed.set( `${Math.round( util / 1024 / 1024 )}MiB used of ${Math.round( available / 1024 / 1024 )}MiB` );
|
|
||||||
} ).catch( e => {
|
|
||||||
console.error( e );
|
|
||||||
} );
|
|
||||||
ramUsed.set(
|
|
||||||
exec(
|
|
||||||
`/bin/bash -c \"free -h | awk '/^Mem:/ {print $3 \\" used of \\" $2}'\"`,
|
|
||||||
)
|
|
||||||
.replaceAll("Gi", "GiB")
|
|
||||||
.replaceAll("Mi", "MiB"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
gpuUtil.set(exec("cat /sys/class/drm/card1/device/gpu_busy_percent"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const panel = SystemInformationPanel();
|
const panel = SystemInformationPanel();
|
||||||
|
|
||||||
const SystemInfo = () => {
|
const SystemInfo = () => {
|
||||||
featureTest();
|
sysinfo.startSysInfoFetcher();
|
||||||
|
|
||||||
const openSysInfo = async () => {
|
const openSysInfo = async () => {
|
||||||
panel.popup();
|
panel.popup();
|
||||||
systemStats.set(refreshStats());
|
sysinfo.refreshStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enabled) {
|
if (sysinfo.enabled) {
|
||||||
sysInfoFetcher();
|
|
||||||
interval(FETCH_INTERVAL, sysInfoFetcher);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
onClicked={() => openSysInfo()}
|
onClicked={() => openSysInfo()}
|
||||||
child={
|
child={
|
||||||
<box tooltipText={ramUsed(v => v)}>
|
<box tooltipText={sysinfo.ramUsed(v => v)}>
|
||||||
<image
|
<image
|
||||||
iconName={"power-profile-performance-symbolic"}
|
iconName={"power-profile-performance-symbolic"}
|
||||||
marginEnd={1}
|
marginEnd={1}
|
||||||
></image>
|
></image>
|
||||||
<label
|
<label
|
||||||
label={cpuUtil(util => util)}
|
label={sysinfo.cpuUtil(util => util)}
|
||||||
marginEnd={5}
|
marginEnd={5}
|
||||||
></label>
|
></label>
|
||||||
<image iconName={"histogram-symbolic"}></image>
|
<image iconName={"histogram-symbolic"}></image>
|
||||||
<label label={ramUtil(util => util)}></label>
|
<label label={sysinfo.ramUtil(util => util)}></label>
|
||||||
<image iconName={"show-gpu-effects-symbolic"}></image>
|
<image iconName={"show-gpu-effects-symbolic"}></image>
|
||||||
<label label={gpuUtil(util => util)}></label>
|
<label label={sysinfo.gpuUtil(util => util)}></label>
|
||||||
{panel}
|
{panel}
|
||||||
</box>
|
</box>
|
||||||
}
|
}
|
||||||
|
137
config/astal/components/bar/sysinfo.ts
Normal file
137
config/astal/components/bar/sysinfo.ts
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import { exec, execAsync, interval, Variable } from "astal";
|
||||||
|
|
||||||
|
const FETCH_INTERVAL = 2000;
|
||||||
|
const cpuUtil = Variable("0%");
|
||||||
|
const ramUtil = Variable("0%");
|
||||||
|
const ramUsed = Variable("0MiB");
|
||||||
|
const gpuUtil = Variable("0%");
|
||||||
|
let gpuName = "card1";
|
||||||
|
let enabled = true;
|
||||||
|
|
||||||
|
const getStats = (): Stats => {
|
||||||
|
gpuName = exec(`/bin/bash -c "ls /sys/class/drm/ | grep '^card[0-9]*$'"`);
|
||||||
|
const cpuNameInSensors = "CPUTIN";
|
||||||
|
const stats = {
|
||||||
|
kernel: exec("uname -sr"),
|
||||||
|
cpuTemp: exec(
|
||||||
|
`/bin/bash -c "sensors | grep -m1 ${cpuNameInSensors} | awk '{print $2}'"`,
|
||||||
|
),
|
||||||
|
cpuClk: exec(
|
||||||
|
`awk '/cpu MHz/ {sum+=$4; ++n} END {print sum/n " MHz"}' /proc/cpuinfo`,
|
||||||
|
),
|
||||||
|
gpuTemp: exec(
|
||||||
|
`/bin/bash -c "sensors | grep -E 'edge' | awk '{print $2}'"`,
|
||||||
|
),
|
||||||
|
gpuClk: exec(
|
||||||
|
`/bin/bash -c "cat /sys/class/drm/${gpuName}/device/pp_dpm_sclk | grep '\\*' | awk '{print $2 $3}'"`,
|
||||||
|
),
|
||||||
|
vram:
|
||||||
|
Math.round(
|
||||||
|
parseInt(
|
||||||
|
exec(
|
||||||
|
`cat /sys/class/drm/${gpuName}/device/mem_info_vram_used`,
|
||||||
|
),
|
||||||
|
) /
|
||||||
|
1024 /
|
||||||
|
1024,
|
||||||
|
) + "MiB",
|
||||||
|
availableVRAM:
|
||||||
|
Math.round(
|
||||||
|
parseInt(
|
||||||
|
exec(
|
||||||
|
`cat /sys/class/drm/${gpuName}/device/mem_info_vram_total`,
|
||||||
|
),
|
||||||
|
) /
|
||||||
|
1024 /
|
||||||
|
1024,
|
||||||
|
) + "MiB",
|
||||||
|
};
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
const systemStats: Variable<Stats> = Variable(getStats());
|
||||||
|
const availableFeatures = {
|
||||||
|
cpu: true,
|
||||||
|
ram: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshStats = () => {
|
||||||
|
systemStats.set(getStats());
|
||||||
|
}
|
||||||
|
|
||||||
|
const featureTest = () => {
|
||||||
|
print('[SysInfo] Feature test started...');
|
||||||
|
// Check if awk & sed are available
|
||||||
|
try {
|
||||||
|
exec("awk -V");
|
||||||
|
exec("sed --version");
|
||||||
|
} catch (e) {
|
||||||
|
printerr(
|
||||||
|
"[ SysInfo ] AWK or SED missing! No system info will be available",
|
||||||
|
);
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if mpstat is available
|
||||||
|
try {
|
||||||
|
exec("mpstat -V");
|
||||||
|
} catch (e) {
|
||||||
|
availableFeatures.cpu = false;
|
||||||
|
printerr(
|
||||||
|
"[ SysInfo ] Feature Test for CPU info failed. mpstat from the sysstat package missing!",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
print('[SysInfo] Feature test complete');
|
||||||
|
};
|
||||||
|
|
||||||
|
const sysInfoFetcher = () => {
|
||||||
|
if (enabled) {
|
||||||
|
if (availableFeatures.cpu) {
|
||||||
|
execAsync(`/bin/fish -c cpu-utilization`).then(v => {
|
||||||
|
cpuUtil.set("" + Math.round(parseFloat(v)));
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (availableFeatures.ram) {
|
||||||
|
execAsync(
|
||||||
|
`/bin/bash -c "free | awk '/Mem:/ {print $3 \\" \\" $2}'"`,
|
||||||
|
).then(v => {
|
||||||
|
const util = parseInt(v.split(' ')[0]);
|
||||||
|
const available = parseInt(v.split(' ')[1]);
|
||||||
|
ramUtil.set("" + Math.round(util / available * 100));
|
||||||
|
ramUsed.set(`${Math.round(util / 1024 / 1024 * 10) / 10} GiB of ${Math.round(available / 1024 / 1024 * 10) / 10} GiB used`);
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
gpuUtil.set(exec("cat /sys/class/drm/card1/device/gpu_busy_percent"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let sysInfoFetcherRunning = false;
|
||||||
|
const startSysInfoFetcher = () => {
|
||||||
|
if (!sysInfoFetcherRunning) {
|
||||||
|
sysInfoFetcherRunning = true;
|
||||||
|
|
||||||
|
featureTest();
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
// Start interval
|
||||||
|
interval(FETCH_INTERVAL, sysInfoFetcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
startSysInfoFetcher,
|
||||||
|
enabled,
|
||||||
|
gpuUtil,
|
||||||
|
cpuUtil,
|
||||||
|
ramUsed,
|
||||||
|
ramUtil,
|
||||||
|
refreshStats,
|
||||||
|
systemStats
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user