TransWikia.com

How to log CPU usage but only when it is high or touching certain treshold ? (+ formatting)

Unix & Linux Asked by Tommy Aria Pradana on December 26, 2020

How can we log CPU usage but only when there is a process(s) with utilization above certain threshold (for example 30% or more) ?

What i am trying to achieve (with shell script) are more or less like this

currCPU = $(cpu-checker)
while true; do
 if(($currCPU >= 80)); then
  echo "$(date +%F %R)"
  $(top -n 1 | head -n 12  | tail -n 3 | replace "n" "n  ") >> someFile.log
 fi
 sleep 2.5
done
# (cpu-checker) and (replace "n" "n  ") are the
# problematic part

with the expected output will be (sort of) like this

2020-08-03 02:31
  16979 root      20   0   43188   4280   3396 R 104.3  0.0   0:00.06 super-process-1
  1     root      20   0  225760   9428   6648 S   0.0  0.0   0:08.94 systemd
  2     root      20   0       0      0      0 S   0.0  0.0   0:00.04 kthreadd
  4     root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H

2020-08-03 09:44
  16979 root      20   0   43188   4280   3396 R  93.3  0.0   0:00.06 another-process
  1     root      20   0  225760   9428   6648 S   0.0  0.0   0:08.94 systemd
  2     root      20   0       0      0      0 S 102.0  0.0   0:00.04 random-proce
  4     root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H

I have tried few things, with all case tried on a Ubuntu Server 16.04.4 (as this is the only environment that i have)

So far, i have not found anything yet for the cpu-checker part, but for the formatting part (replace "n" "n ") i have tried to use tr "n" "n " and sed G with no avail.

One Answer

Some hints:

sed 's/^/ /'

replaces each starting of a line with a space.

uptime | sed 's/.*load average: //;s/,.*//'

gives you the load average of the last minute as a fraction (CPU%). This may a measurement for how busy your system is.

As @Paul_Pedant suggested in his comment:

top -b -n 1 | awk '/%Cpu/ || $1 == "PID" || $1 ~ /^[0-9]+/; NR >= 12 { exit; }' 

gives you the real CPU %.

Or, if you are adventurous and don't mind some Python code:

from __future__ import print_function
from time import sleep


last_idle = last_total = 0
with open('/proc/stat') as f:
    fields = [float(column) for column in f.readline().strip().split()[1:]]
idle, total = fields[3], sum(fields)
idle_delta, total_delta = idle - last_idle, total - last_total
last_idle, last_total = idle, total
sleep(1)
with open('/proc/stat') as f:
    fields = [float(column) for column in f.readline().strip().split()[1:]]
idle, total = fields[3], sum(fields)
idle_delta, total_delta = idle - last_idle, total - last_total
last_idle, last_total = idle, total
utilisation = 100.0 * (1.0 - idle_delta / total_delta)
print('%5.1f' % utilisation)

reads /proc/stat and does the calculation for you.

date '+%F %R'

gives exactly the same output as

echo "$(date '+%F %R')"

And you may want to redirect the output to your log.

and finally,

top -bn 1 | sed '1,/PID *USER/d' | head -3

is probably more reliable than your tail and head combination.

Answered by Ljm Dullaart on December 26, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP