[AGS] SysInfo: Re-Structure for better perf
This commit is contained in:
		| @@ -1,88 +1,6 @@ | ||||
| import { exec, execAsync, interval, Variable } from "astal"; | ||||
| import { exec } from "astal"; | ||||
| import { Gtk } from "astal/gtk4"; | ||||
|  | ||||
| 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!", | ||||
|         ); | ||||
|     } | ||||
| }; | ||||
| import sysinfo from "../sysinfo"; | ||||
|  | ||||
| const info = () => { | ||||
|     return ( | ||||
| @@ -96,12 +14,12 @@ const info = () => { | ||||
|                 vexpand | ||||
|                 halign={Gtk.Align.START} | ||||
|                 hexpand | ||||
|                 label={ramUsed(used => { | ||||
|                     return "RAM: " + used + ` (${ramUtil.get()}%)`; | ||||
|                 label={sysinfo.ramUsed(used => { | ||||
|                     return "RAM: " + used + ` (${sysinfo.ramUtil.get()}%)`; | ||||
|                 })} | ||||
|             ></label> | ||||
|             <label | ||||
|                 label={systemStats(stats => { | ||||
|                 label={sysinfo.systemStats(stats => { | ||||
|                     return `CPU: ${stats.cpuTemp}, ${stats.cpuClk} | ||||
| GPU: ${stats.gpuTemp}, ${stats.gpuClk} (${stats.vram} / ${stats.availableVRAM}) | ||||
| Kernel: ${stats.kernel}`; | ||||
| @@ -125,69 +43,35 @@ const SystemInformationPanel = () => { | ||||
|     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 SystemInfo = () => { | ||||
|     featureTest(); | ||||
|     sysinfo.startSysInfoFetcher(); | ||||
|  | ||||
|     const openSysInfo = async () => { | ||||
|         panel.popup(); | ||||
|         systemStats.set(refreshStats()); | ||||
|         sysinfo.refreshStats(); | ||||
|     }; | ||||
|  | ||||
|     if (enabled) { | ||||
|         sysInfoFetcher(); | ||||
|         interval(FETCH_INTERVAL, sysInfoFetcher); | ||||
|  | ||||
|     if (sysinfo.enabled) { | ||||
|         return ( | ||||
|             <button | ||||
|                 onClicked={() => openSysInfo()} | ||||
|                 child={ | ||||
|                     <box tooltipText={ramUsed(v => v)}> | ||||
|                     <box tooltipText={sysinfo.ramUsed(v => v)}> | ||||
|                         <image | ||||
|                             iconName={"power-profile-performance-symbolic"} | ||||
|                             marginEnd={1} | ||||
|                         ></image> | ||||
|                         <label | ||||
|                             label={cpuUtil(util => util)} | ||||
|                             label={sysinfo.cpuUtil(util => util)} | ||||
|                             marginEnd={5} | ||||
|                         ></label> | ||||
|                         <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> | ||||
|                         <label label={gpuUtil(util => util)}></label> | ||||
|                         <label label={sysinfo.gpuUtil(util => util)}></label> | ||||
|                         {panel} | ||||
|                     </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 | ||||
| } | ||||
		Reference in New Issue
	
	Block a user