D7K
Posts: 4
Joined: Mon Mar 08, 2021 11:29 am

Save CPU load to .log or .txt file by shell script.

Wed Apr 21, 2021 7:34 pm

Hi,
I need to save to .log or .txt file informations about GPU, CPU temperature and CPU load every second. I tried to do this by shell script. Only I can do is get and save to the file GPU and CPU temperature. I really don't know how to get informations about CPU load from for example

Code: Select all

top
or

Code: Select all

htop
command.
My dream file .log looks like:
Date 21.04.21, Time 21:12:39, GPU_temp=56.0'C, CPU_temp: 56'C, CPU_load: 3%
Date 21.04.21, Time 21:12:40, GPU_temp=55.0'C, CPU_temp: 55'C, CPU_load: 3%
Date 21.04.21, Time 21:12:41, GPU_temp=56.0'C, CPU_temp: 55'C, CPU_load: 3%
Date 21.04.21, Time 21:12:42, GPU_temp=55.0'C, CPU_temp: 55'C, CPU_load: 5%
Date 21.04.21, Time 21:12:43, GPU_temp=56.4'C, CPU_temp: 55'C, CPU_load: 8%
Date 21.04.21, Time 21:12:44, GPU_temp=56.0'C, CPU_temp: 55'C, CPU_load: 15%
Date 21.04.21, Time 21:12:45, GPU_temp=56.0'C, CPU_temp: 55'C, CPU_load: 30%
Date 21.04.21, Time 21:12:46, GPU_temp=55.5'C, CPU_temp: 55'C, CPU_load: 20%
Date 21.04.21, Time 21:12:47, GPU_temp=55.5'C, CPU_temp: 57'C, CPU_load: 18%
Code I have:

Code: Select all

#!/bin/bash

while true; do
cpu=$(cat /sys/class/thermal/thermal_zone0/temp)
echo "Date $(date +"%d.%m.%y"), Time $(date +"%T"), GPU_$(/opt/vc/bin/vcgencmd measure_temp), CPU_temp: $((cpu/1000))'C" >> test_file.log
sleep 1
done
Output I get:
Date 21.04.21, Time 21:12:39, GPU_temp=56.0'C, CPU_temp: 56'C
Date 21.04.21, Time 21:12:40, GPU_temp=55.0'C, CPU_temp: 55'C
Date 21.04.21, Time 21:12:41, GPU_temp=56.0'C, CPU_temp: 55'C
Date 21.04.21, Time 21:12:42, GPU_temp=55.0'C, CPU_temp: 55'C
Date 21.04.21, Time 21:12:43, GPU_temp=56.4'C, CPU_temp: 55'C
Date 21.04.21, Time 21:12:44, GPU_temp=56.0'C, CPU_temp: 55'C
Date 21.04.21, Time 21:12:45, GPU_temp=56.0'C, CPU_temp: 55'C
Date 21.04.21, Time 21:12:46, GPU_temp=55.5'C, CPU_temp: 55'C
Date 21.04.21, Time 21:12:47, GPU_temp=55.5'C, CPU_temp: 57'C
I searched for some information results for a long time, but I found nothing.
I will be very grateful for your help and suggestions.

User avatar
neilgl
Posts: 3056
Joined: Sun Jan 26, 2014 8:36 pm
Location: Near The National Museum of Computing

Re: Save CPU load to .log or .txt file by shell script.

Wed Apr 21, 2021 7:59 pm

Maybe you can adapt the result from uptime to get the system load averages for the past 1, 5, and 15 minutes (but not every second)?

Code: Select all

pi@pi3plus:~ $ uptime
 20:55:00 up 26 days,  4:19,  1 user,  load average: 0.04, 0.09, 0.08
Or look at /proc/stat in C in viewtopic.php?t=229992

swampdog
Posts: 610
Joined: Fri Dec 04, 2015 11:22 am

Re: Save CPU load to .log or .txt file by shell script.

Wed Apr 21, 2021 8:44 pm

There's quite a few commands you can use:

top -n 1 -b
vmstat
mpstat -P 0-3,all
..obviously read their manual.
iostat -N

You'll have to google what these values mean..
cat /proc/stat
..but can get fine grained in that /proc/[pid]/stat exists (eg: /proc/1/stat for /sbin/init).

I've not got into "cpu load" because (for instance) https://www.google.co.uk/search?q=how+t ... x&complete it's a bit vague.

Not knowing anything else about your aims, aside from doing it once per second, I'd start with /proc/stat because if it returns values you can use, it'll be more efficient than firing a command.

These packages..

Code: Select all

foo@pi18:~ $ for i in $(which top vmstat mpstat iostat); do apt-file search -F "$i";done
procps: /usr/bin/top                      
procps: /usr/bin/vmstat                   
sysstat: /usr/bin/mpstat                  
sysstat: /usr/bin/iostat

User avatar
kerry_s
Posts: 2026
Joined: Thu Jan 30, 2020 7:14 pm

Re: Save CPU load to .log or .txt file by shell script.

Wed Apr 21, 2021 9:18 pm

i use this for tint2

Code: Select all

#!/bin/sh

cpu=$(top -bn1 | awk '/^%Cpu/ {printf "%d%s",$2,"%"}')
mem=$(free | awk '/^Mem/ {printf "%d%s",$3/$2*100,"%"}')
temp=$(vcgencmd measure_temp)

echo "cpu=$cpu   mem=$mem   $temp"

exit 0

bls
Posts: 1336
Joined: Mon Oct 22, 2018 11:25 pm
Location: Seattle, WA

Re: Save CPU load to .log or .txt file by shell script.

Wed Apr 21, 2021 9:37 pm

Here's a Bash-ical way to get the load average:

Code: Select all

read lav <<< $(cat /proc/loadavg)
lav=(${lav[@]})
loadavg="${lav[1]}"
The special file /proc/loadavg has the current system load average. The first 2 lines are some Bash array magic to make the load average into an array. There may be a way to eliminate the str= line, but beyond my available time today.

You can modify the "${lavg[1]}" to get the desired element of the array. The first 3 elements correspond to the 3 numbers in the "uptime" command (and I would assume top as well).
Pi tools:
Quickly and easily build customized-just-for-you SD Cards: https://github.com/gitbls/sdm
Easily run your network's DHCP/DNS on a Pi: https://github.com/gitbls/ndm
Easy strongSwan VPN installer/manager: https://github.com/gitbls/pistrong
Lightweight Virtual VNC Config: https://github.com/gitbls/RPiVNCHowTo

swampdog
Posts: 610
Joined: Fri Dec 04, 2015 11:22 am

Re: Save CPU load to .log or .txt file by shell script.

Wed Apr 21, 2021 10:22 pm

Doh! (to self).

"ls -l /proc/" on my PC, oops I ought to be on an rpi so "cat /proc/lo" <tab completion> (but only once) so because the thought "it isn't there" was in my mind, assumed it wasn't. Hopefully that's the stupid error(*) of the day out of the way.

(*) only 30mins until the next day so I can't relax for long!

D7K
Posts: 4
Joined: Mon Mar 08, 2021 11:29 am

Re: Save CPU load to .log or .txt file by shell script.

Thu Apr 22, 2021 9:03 pm

I think I will use

Code: Select all

iostat
or

Code: Select all

mpstat
becouse it have all I need, example output:
Linux 5.10.17-v7l+ (raspberrypi) 22.04.2021 _armv7l_ (4 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0,48 0,00 0,53 0,37 0,00 98,62

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mmcblk0 6,28 175,57 27,87 335549 53258

Linux 5.10.17-v7l+ (raspberrypi) 22.04.2021 _armv7l_ (4 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0,48 0,00 0,53 0,37 0,00 98,61

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mmcblk0 6,28 175,49 27,85 335577 53258
I got it from very easy script which is:

Code: Select all

#!/bin/bash

while true; do
iostat >> iostat.log
sleep 1
done
My question is, can I save to file only this 2 lines from iostat command?
avg-cpu: %user %nice %system %iowait %steal %idle
0,48 0,00 0,53 0,37 0,00 98,61
I tried to use something like this, but it doesn't work.

Code: Select all

#!/bin/bash

while true; do
$(grep -w 'avg-cpu:' $(iostat)) >> iostat2.log
sleep 1
done
How can I choose which line of my command I want to save?

bls
Posts: 1336
Joined: Mon Oct 22, 2018 11:25 pm
Location: Seattle, WA

Re: Save CPU load to .log or .txt file by shell script.

Thu Apr 22, 2021 9:33 pm

D7K wrote:
Thu Apr 22, 2021 9:03 pm
I think I will use

Code: Select all

iostat
or

Code: Select all

mpstat
becouse it have all I need, example output:
Linux 5.10.17-v7l+ (raspberrypi) 22.04.2021 _armv7l_ (4 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0,48 0,00 0,53 0,37 0,00 98,62

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mmcblk0 6,28 175,57 27,87 335549 53258

Linux 5.10.17-v7l+ (raspberrypi) 22.04.2021 _armv7l_ (4 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0,48 0,00 0,53 0,37 0,00 98,61

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
mmcblk0 6,28 175,49 27,85 335577 53258
I got it from very easy script which is:

Code: Select all

#!/bin/bash

while true; do
iostat >> iostat.log
sleep 1
done
My question is, can I save to file only this 2 lines from iostat command?
avg-cpu: %user %nice %system %iowait %steal %idle
0,48 0,00 0,53 0,37 0,00 98,61
I tried to use something like this, but it doesn't work.

Code: Select all

#!/bin/bash

while true; do
$(grep -w 'avg-cpu:' $(iostat)) >> iostat2.log
sleep 1
done
How can I choose which line of my command I want to save?
This is a bit kludgy, but here's one way: Pipe the output from iostat into a little inline script that takes advantage of the knowledge that the line after "avg-cpu" has the numeric info that you also want. Both lines are output.

Code: Select all

while true
do
    iostat | ( while read str ;\
                     do \
                         if [[ "$str" =~ "avg-cpu" ]]; then \
                             echo "$str" ; \
                             read str ; echo "$str" ;\
                             fi \
              done )
    sleep 1
done
EDIT: Obviously I should have looked at the iostat man page. :oops: :roll:
Last edited by bls on Thu Apr 22, 2021 10:01 pm, edited 1 time in total.
Pi tools:
Quickly and easily build customized-just-for-you SD Cards: https://github.com/gitbls/sdm
Easily run your network's DHCP/DNS on a Pi: https://github.com/gitbls/ndm
Easy strongSwan VPN installer/manager: https://github.com/gitbls/pistrong
Lightweight Virtual VNC Config: https://github.com/gitbls/RPiVNCHowTo

User avatar
kerry_s
Posts: 2026
Joined: Thu Jan 30, 2020 7:14 pm

Re: Save CPU load to .log or .txt file by shell script.

Thu Apr 22, 2021 9:43 pm

you can use awk.

you do realize writing to a file every second with no limit is going to keep growing till it takes up all the space in the drive, eventually something will break.

swampdog
Posts: 610
Joined: Fri Dec 04, 2015 11:22 am

Re: Save CPU load to .log or .txt file by shell script.

Thu Apr 22, 2021 9:55 pm

There are a couple of options (man iostat).

This regex will suffice..

Code: Select all

foo@pi18:/wrk/TT $ iostat -c | egrep "^[[:space:]]{1,}[[:digit:]]{1,}"
           2.42    1.76    0.92    0.01    0.00   94.89
..or..

Code: Select all

foo@pi18:/wrk/TT $ iostat -c | egrep -B1 "^[[:space:]]{1,}[[:digit:]]{1,}"
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           2.42    1.76    0.92    0.01    0.00   94.89
:-)

D7K
Posts: 4
Joined: Mon Mar 08, 2021 11:29 am

Re: Save CPU load to .log or .txt file by shell script.

Mon Apr 26, 2021 12:39 pm

Thank you guys for all your help and all the hints. I am not a specialist in Bash but I managed to get what I needed. My final script looks a little clunky, but it works fine.

Code: Select all

#!/bin/bash

while true; do
cpu=$(cat /sys/class/thermal/thermal_zone0/temp)
echo "Date $(date +"%d.%m.%y"), Time $(date +"%T"), GPU_$(/opt/vc/bin/vcgencmd measure_temp), CPU_temp: $((cpu/1000))'C, 	CPU_load $(iostat -c | egrep "^[[:space:]]{1,}[[:digit:]]{1,}")" >> cpu_temp_load.log
sleep 1
done

Return to “Other programming languages”