This page looks best with JavaScript enabled

CPU and RAM monitoring scripts for Awesome

 ·  🎃 kr0m

In this article, I will explain how to integrate monitoring scripts into Awesome. To do this, we will use timers that will execute our bash script every X time and pass the processed data via Dbus to a function that will update the widget that displays the metric on the screen. The best thing about these scripts is that they are valid for both FreeBSD and Linux.


CPU

The LUA code for CPU monitoring is as follows:

vi cpuUsage.lua

-- https://awesomewm.org/doc/api/libraries/dbus.html
local wibox = require("wibox")
local awful = require("awful")

kr0mCpuWidget = wibox.widget.textbox()

-- DBUS listener which update textbox value
dbus.request_name("session", "com.alfaexploit.cpuUsage")
dbus.add_match("session", "interface='com.alfaexploit.cpuUsage', member='data'" )
dbus.connect_signal("com.alfaexploit.cpuUsage", 
  function (...)
    local data = {...}
    local dbustext = data[2]
    kr0mCpuWidget:set_text(dbustext)
  end)

-- qdbus-qt5
-- dbus-monitor "interface='com.alfaexploit.cpuUsage'"

-- Timer that sends script execution output to DBUS listener
sleepTimerDbus = timer ({timeout = 5})
sleepTimerDbus:connect_signal ("timeout", 
  function ()
    awful.util.spawn_with_shell("dbus-send --session --dest=com.alfaexploit.cpuUsage /com/alfaexploit/cpuUsage com.alfaexploit.cpuUsage.data string:$(~/.config/awesome/kr0mWidgets/cpuUsage.sh)")
  end)
sleepTimerDbus:start()

-- First timeout is triggered manually to evade NULL values
sleepTimerDbus:emit_signal("timeout")

The bash script:

vi cpuUsage.sh

#!/usr/bin/env bash
# pkg install stress-ng
# emerge app-benchmarks/stress-ng
# stress-ng -c 4

LOG_FILE=/tmp/cpuUsage.log
uname -a|grep FreeBSD 1>/dev/null
if [ $? -eq 0 ]; then
    OS=FREEBSD
else
    OS=LINUX
fi

#date >> $LOG_FILE
if [ $OS == "FREEBSD" ]; then
    # cp_time
    # user
    # nice
    # system
    # interrupt
    # idle
    cp_time=$(sysctl kern.cp_time)
    set -- $cp_time
    #echo "User: $2"
    #echo "Nice: $3"
    #echo "System: $4"
    #echo "Interrupt: $5"
    #echo "Idle: $6"

    cpuused=$(($2+$3+$4+$5))
    cputotal=$(($2+$3+$4+$5+$6))
    #echo "cpuused=$cpuused"
    #echo "cputotal=$cputotal"
else
    cp_time=$(cat /proc/stat | head -n 1)
    set -- $cp_time
    #echo "User: $2"
    #echo "Nice: $3"
    #echo "System: $4"
    #echo "Idle: $5"
    #echo "IOWait: $6"
    #echo "IRQ:  $7"
    #echo "softIRQ $8"

    cpuused=$(($2+$3+$4+$6+$7+$8))
    cputotal=$(($2+$3+$4+$5+$6+$7+$8))
    #echo "cpuused=$cpuused"
    #echo "cputotal=$cputotal"
fi

if [ -f $LOG_FILE ]; then
    previous_cpuused=$(cat $LOG_FILE | awk '{print$1}')
    previous_cputotal=$(cat $LOG_FILE | awk '{print$2}')
    #echo "previous_cpuused=$previous_cpuused"
    #echo "previous_cputotal=$previous_cputotal"
else
    # Save current values
    > $LOG_FILE 2>/dev/null
    echo $cpuused $cputotal > $LOG_FILE
    cpu_usage=NULL
    echo "NULL"
    #echo "cpu_usage: $cpu_usage"
    exit
fi

#(%/100)*TOTAL=USED
#%=(USED/TOTAL)*100
#cpu_usage = total_time_without_idle / total_time * 100
cpu_usage=$(echo "scale=2;($cpuused-$previous_cpuused)/($cputotal-$previous_cputotal)*100" | bc | awk -F "." '{print$1}')
#echo "cpu_usage: $cpu_usage"
echo "$cpu_usage%"

# Save current values
> $LOG_FILE 2>/dev/null
echo $cpuused $cputotal > $LOG_FILE

RAM

The LUA code for RAM monitoring is as follows:

vi ramUsage.lua

-- https://awesomewm.org/doc/api/libraries/dbus.html
local wibox = require("wibox")
local awful = require("awful")

kr0mRamWidget = wibox.widget.textbox()

-- DBUS listener which update textbox value
dbus.request_name("session", "com.alfaexploit.ramUsage")
dbus.add_match("session", "interface='com.alfaexploit.ramUsage', member='data'" )
dbus.connect_signal("com.alfaexploit.ramUsage", 
  function (...)
    local data = {...}
    local dbustext = data[2]
    kr0mRamWidget:set_text(dbustext)
  end)

-- qdbus-qt5
-- dbus-monitor "interface='com.alfaexploit.ramUsage'"

-- Timer that sends script execution output to DBUS listener
sleepTimerDbus = timer ({timeout = 5})
sleepTimerDbus:connect_signal ("timeout", 
  function ()
    awful.util.spawn_with_shell("dbus-send --session --dest=com.alfaexploit.ramUsage /com/alfaexploit/ramUsage com.alfaexploit.ramUsage.data string:$(~/.config/awesome/kr0mWidgets/ramUsage.sh)")
  end)
sleepTimerDbus:start()

-- First timeout is triggered manually to evade NULL values
sleepTimerDbus:emit_signal("timeout")

The bash script:

vi ramUsage.sh

#!/usr/bin/env bash
# emerge sys-apps/coreutils

uname -a|grep FreeBSD 1>/dev/null
if [ $? -eq 0 ]; then
    OS=FREEBSD
else
    OS=LINUX
fi

if [ $OS == "FREEBSD" ]; then
    # Page size:
    page_size=$(sysctl vm.stats.vm.v_page_size | awk '{print$2}')
    #echo "page_size=$page_size"

    # Total RAM amount:
    pages_number=$(sysctl vm.stats.vm.v_page_count | awk '{print$2}')
    #echo "pages_number=$pages_number"
    ram_amount=$(echo "$page_size*$pages_number" | bc)
    #echo "ram_amount=$ram_amount"
    human_ram_amount=$(echo $ram_amount | awk '{split("B,K,M,G,T", unit, ","); (size=$1) ? level=sprintf("%.0d", (log(size)/log(1024))) : level=0; printf "%.1f%s\n", size/(1024**level), unit[level+1]}')
    #echo ">> Human RAM: $human_ram_amount"
    
    # Used memory: active + (wired-ZFS_ARC)
    # Active:
    active_memory_pages=$(sysctl vm.stats.vm.v_active_count | awk '{print$2}')
    #echo "active_memory_pages=$active_memory_pages"
    active_memory=$(echo "$page_size*$active_memory_pages" | bc)
    #echo "active_memory=$active_memory"
    #echo ">> Human active_memory: $(echo $active_memory | awk '{split("B,K,M,G,T", unit, ","); (size=$1) ? level=sprintf("%.0d", (log(size)/log(1024))) : level=0; printf "%.1f%s\n", size/(1024**level), unit[level+1]}')"
    # Wired:
    wired_memory_pages=$(sysctl vm.stats.vm.v_wire_count | awk '{print$2}')
    #echo "wired_memory_pages=$wired_memory_pages"
    wired_memory=$(echo "$page_size*$wired_memory_pages" | bc)
    #echo "wired_memory=$wired_memory"
    #echo ">> Human wired_memory: $(echo $wired_memory | awk '{split("B,K,M,G,T", unit, ","); (size=$1) ? level=sprintf("%.0d", (log(size)/log(1024))) : level=0; printf "%.1f%s\n", size/(1024**level), unit[level+1]}')"
    # ZFS_ARC:
    zfs_arc=$(zfs-stats -AR|grep 'Target Size: (Adaptive)' | awk '{print$5}')
    #echo "zfs_arc=$zfs_arc"
    #echo ">> Human zfs_arc: $(echo $zfs_arc | awk '{split("B,K,M,G,T", unit, ","); (size=$1) ? level=sprintf("%.0d", (log(size)/log(1024))) : level=0; printf "%.1f%s\n", size/(1024**level), unit[level+1]}')"
    # Total used memory:
    used_memory=$(echo "$active_memory+($wired_memory-$zfs_arc)" | bc)
else
    # Total RAM amount:
    ram_amount_raw=$(cat /proc/meminfo | grep -w 'MemTotal:' | awk '{print$2}')
    ram_amount=$(echo "$ram_amount_raw*1024" | bc)
    human_ram_amount=$(echo $ram_amount | awk '{split("B,K,M,G,T", unit, ","); (size=$1) ? level=sprintf("%.0d", (log(size)/log(1024))) : level=0; printf "%.1f%s\n", size/(1024**level), unit[level+1]}')
    #echo ">> Human RAM: $human_ram_amount"

    # Used memory: MemTotal - MemFree - Buffers - Cached - SReclaimable
    # MemFree:
    mem_free_raw=$(cat /proc/meminfo | grep -w 'MemFree:' | awk '{print$2}')
    mem_free=$(echo "$mem_free_raw*1024" | bc)
    # Buffers:
    buffers_raw=$(cat /proc/meminfo | grep -w 'Buffers:' | awk '{print$2}')
    buffers=$(echo "$buffers_raw*1024" | bc)
    # Cached:
    cached_raw=$(cat /proc/meminfo | grep -w 'Cached:' | awk '{print$2}')
    cached=$(echo "$cached_raw*1024" | bc)
    # SReclaimable:
    sreclaimable_raw=$(cat /proc/meminfo | grep -w 'SReclaimable:' | awk '{print$2}')
    sreclaimable=$(echo "$sreclaimable_raw*1024" | bc)
    # Total used memory:
    used_memory=$(echo "$ram_amount-$mem_free-$buffers-$cached-$sreclaimable" | bc)
fi

#echo "used_memory=$used_memory"
human_used_memory=$(echo $used_memory | awk '{split("B,K,M,G,T", unit, ","); (size=$1) ? level=sprintf("%.0d", (log(size)/log(1024))) : level=0; printf "%.1f%s\n", size/(1024**level), unit[level+1]}')
#echo ">> Human used_memory: $human_used_memory"

percentage=$(echo "scale=2;($used_memory/$ram_amount)*100" | bc | awk -F "." '{print$1}')
echo -e "$percentage%-$human_used_memory/$human_ram_amount"

Awesome Configuration

The Awesome configuration will be as follows:

vi rc.lua

-- git clone https://github.com/streetturtle/awesome-wm-widgets.git
-- wget https://pavelmakhov.com/awesome-wm-widgets/assets/fonts/awesomewm-font.ttf ~/.local/share/fonts
local fs_widget = require("awesome-wm-widgets.fs-widget.fs-widget")
-- custom kr0m cpu widget:
local cpuIcon = wibox.widget.imagebox('/home/kr0m/.config/awesome/media_files/cpu.png')
require("kr0mWidgets.cpuUsage")
-- custom vicious widgets:
-- pkg install awesome-vicious
-- emerge x11-plugins/vicious
local vicious = require("vicious")
cpuwidget = awful.widget.graph()
cpuwidget:set_width(50)
cpuwidget:set_background_color"#494B4F"
cpuwidget:set_color{ type = "linear", from = { 0, 0 }, to = { 50, 0 },
                     stops = { { 0, "#FF5656" },
                               { 0.5, "#88A175" },
                               { 1, "#AECF96" } } }
vicious.register(cpuwidget, vicious.widgets.cpu, "$1", 3)
-- custom kr0m ram widget:
local ramIcon = wibox.widget.imagebox('/home/kr0m/.config/awesome/media_files/mem.png')
require("kr0mWidgets.ramUsage")


        s.mytasklist, -- Middle widget
        { -- Right widgets
            layout = wibox.layout.fixed.horizontal,
            mykeyboardlayout,
            wibox.widget.systray(),
            separator,
            cpuIcon,
            kr0mCpuWidget,
            cpuwidget,
            ramIcon,
            kr0mRamWidget,
            separator,
            fs_widget({ mounts = { '/', '/mnt/6T', '/mnt/2T', '/mnt/1T' } }),
            mytextclock,
            s.mylayoutbox,
        },
If you liked the article, you can treat me to a RedBull here