1

I am working on a python script which will give us a list of top 5 application or process using the highest CPU in linux. I can get the cpu usage percent by using psutil but I have not been able to find the list of application which are using the CPU. For ex: in case of Ubuntu we can do htop to get the list of application along with their cpu percent:

enter image description here

Considering the above image, from the python code we should be able to get the results like:

[{
    "name": "vncserver",
    "cpu": 9.1
}, {
    "name": "vncserver",
    "cpu": 4.6
}, {
    "name": "dotnet",
    "cpu": 3.9
}, {
    "name": "htop",
    "cpu": 2.6
}, {
    "name": "td-agent",
    "cpu": 2.6
}]

Can anyone please help in this or suggest some good libraries/articles which I can refer. Thanks

S Andrew
  • 5,592
  • 27
  • 115
  • 237

1 Answers1

0

Here is cpu_percent() method to get CPU usage of exact process. But cpu_percent() with interval less than 1 second working not correct

You may see warning:

Warning the first time this method is called with interval = 0.0 or None it will return a meaningless 0.0 value which you are supposed to ignore.

And that is not full description. Actually if you try to call cpu_percent() second time inside 1 second, it will return bad value again. So you need to wait 1 second or more to get correct value.

Because of it loop over all processes need long time and here is two workarounds

  1. Filter processes by some rule and get CPU usage just for processes that you want to check

  2. Run loop over processes asynchronically. And here is example how you can do that:

import psutil
from psutil import Process
from awaits.awaitable import awaitable
import asyncio


@awaitable
def _worker(p: Process):
    try:
        return {
          'name': p.name(),
          'pid': p.pid,
          'commnd_line': p.cmdline(),
          'cpu_usage': p.cpu_percent(interval=1)
        }
    except Exception as e:
        print('ERROR:', e)
        return None


async def get_proc_info(p: Process):
    return await _worker(p)


async def scan_processes():
    tasks = []
    results = []

    for p in psutil.process_iter(attrs=None, ad_value=None):
        tasks.append(asyncio.create_task(get_proc_info(p)))

    for task in tasks:
        results.append(await task)

    return [i for i in results if i]

procs = asyncio.run(scan_processes())

sorted_procs = sorted(procs, key=lambda i: i['cpu_usage'])

print('High load TOP 3 are:')
print('1', sorted_procs[-1]['name'] + f' [{sorted_procs[-1]["pid"]}]', sorted_procs[-1]['cpu_usage'])
print('2', sorted_procs[-2]['name'] + f' [{sorted_procs[-2]["pid"]}]', sorted_procs[-2]['cpu_usage'])
print('3', sorted_procs[-3]['name'] + f' [{sorted_procs[-3]["pid"]}]', sorted_procs[-3]['cpu_usage'])
print('...')

print('Most tiny one is')
print(len(sorted_procs), sorted_procs[0]['name'] + f' [{sorted_procs[0]["pid"]}]', sorted_procs[0]['cpu_usage'])

Output will be like:

ERROR: psutil.AccessDenied (pid=0, name='kernel_task')
ERROR: psutil.AccessDenied (pid=658, name='CrashReporterSup')
ERROR: psutil.AccessDenied (pid=659, name='fcconfig')
ERROR: psutil.ZombieProcess process still exists but it`s a zombie (pid=698, name='uname')
ERROR: psutil.AccessDenied (pid=85270, name='login')
High load TOP 3 are:
1 python3.9 [11030] 97.0
2 com.apple.WebKit.WebContent [10747] 31.6
3 python3.7 [83425] 11.5
...
Most tiny one is
402 loginwindow [204] 0.0
rzlvmp
  • 7,512
  • 5
  • 16
  • 45