173

I would like to monitor one process's memory / cpu usage in real time. Similar to top but targeted at only one process, preferably with a history graph of some sort.

  • What memory statistics do you want? There are lots of them. – vwduder Jan 13 '11 at 11:33
  • Memory usage over a given time frame, current usage, maximum usage, average. – Josh K Jan 13 '11 at 11:33

11 Answers 11

141

On Linux, top actually supports focusing on a single process, although it naturally doesn't have a history graph:

top -p PID

This is also available on Mac OS X with a different syntax:

top -pid PID
  • 9
    And since you may not want to look up the PID every time, try something like top -p `pgrep -f /usr/bin/kvm`. – Stefan Lasiewski Aug 17 '10 at 3:33
  • I use Cacti to monitor some individual processes, but installing a full blown Cacti installation sounds too complex for the simple situation asked here. – Stefan Lasiewski Aug 17 '10 at 3:34
  • @Stefan: I'm assuming I would have to run that remotely? – Josh K Aug 17 '10 at 4:00
  • @Josh : Yes you would need to run Cacti (Which requires MySQL, Apache and few other packages) on another server. On most distros, it's pretty simple to install using Yum or apt-get. – Stefan Lasiewski Aug 17 '10 at 20:48
  • @Stefan if you want to to check remotly you can do ssh@remotehost 'top -p PID > ~hostname_pid.txt; exit'and – klerk May 13 '14 at 20:02
63

htop is a great replacement to top. It has... Colors! Simple keyboard shortcuts! Scroll the list using the arrow keys! Kill a process without leaving and without taking note of the PID! Mark multiple processes and kill them all!

Among all of the features, the manpage says you can press F to follow a process.

Really, you should try htop. I never started top again, after the first time I used htop.

Display a single process:

htop -p PID

  • 7
    +1 for htop. This is one of the first program I install on a new system. It makes my life much easier. The tree view is also very handy. – Barthelemy Nov 24 '10 at 12:22
  • 9
    top also has colors. Press z. – tshepang Jan 12 '11 at 1:41
  • 2
    You're right! top has colors! Too bad its colors are quite useless, specially when compared to htop (which fades other users processes and highlights the program basename). – Denilson Sá Maia Jan 12 '11 at 18:17
  • 1
    And htop -p PID will work too, just like the example given by @Michael Mrozek. – noisebleed Nov 25 '14 at 12:05
  • 1
    Then only reason to use top, is because htop is not available or can't be installed. That is why htop was created, to provide much more features. – lepe Apr 13 '15 at 2:55
63

psrecord

The following addresses history graph of some sort. Python psrecord package does exactly this.

pip install psrecord                             # local user install
sudo apt-get install python-matplotlib python-tk # for plotting; or via pip

For single process it's the following (stopped by Ctrl+C):

psrecord $(pgrep proc-name1) --interval 1 --plot plot1.png

For several processes the following script is helpful to synchronise the charts:

#!/bin/bash    
psrecord $(pgrep proc-name1) --interval 1 --duration 60 --plot plot1.png &
P1=$!
psrecord $(pgrep proc-name2) --interval 1 --duration 60 --plot plot2.png &
P2=$!
wait $P1 $P2
echo 'Done'

Charts look like: psrecord example

memory_profiler

The package provides RSS-only sampling (plus some Python-specific options). It can also record process with its children processes (see mprof --help).

pip install memory_profiler
mprof run /path/to/executable
mprof plot

By default this pops up a Tkinter-based (python-tk may be needed) chart explorer which can be exported:

mprof

graphite-stack & statsd

It may seem an overkill for a simple one-off test, but for something like a several-day debugging it's, for sure, reasonable. A handy all-in-one raintank/graphite-stack (from Grafana's authors) image and psutil and statsd client. procmon.py provides an implementation.

$ docker run --rm -p 8080:3000 -p 8125:8125/udp raintank/graphite-stack

Then in another terminal, after starting target process:

$ sudo apt-get install python-statsd python-psutil # or via pip
$ python procmon.py -s localhost -f chromium -r 'chromium.*'

Then opening Grafana at http://localhost:8080, authentication as admin:admin, setting up datasource https://localhost, you can plot a chart like:

grafana chart

graphite-stack & telegraf

Instead of Python script sending the metrics to Statsd, telegraf (and procstat input plugin) can be used to send the metrics to Graphite directly.

Minimal telegraf configuration looks like:

[agent]
  interval = "1s"

[[outputs.graphite]]
  servers = ["localhost:2003"]
  prefix = "testprfx"

[[inputs.procstat]]
  pid_file = "/path/to/file/with.pid"

Then run line telegraf --config minconf.conf. Grafana part is the same, except metrics names.

sysdig

sysdig (available in Debian and Ubuntu's repos) with sysdig-inspect UI look very promising, providing extremely fine-grained details along with CPU utilisation and RSS, but unfortunately the UI is unable to render them, and sysdig can't filter procinfo event by process at the time of writing. Though, this should be possible with a custom chisel (an sysdig extension written in Lua).

  • pgrep systemd is giving multiple lines of output, and thus bugs the psrecord, what should be done? I just want to test with any process. – EralpB Apr 11 '18 at 7:09
  • 1
    @EralpB pgrep --help to the rescue. There's at least --newest and --oldest. – saaj Apr 11 '18 at 9:03
  • 2
    This should be the accepted answer, since it actually gives a memory usage history plot. Note for the psrecord method, Ctrl+C on the psrecord process just quits without saving a plot, you need to end the process-under-test. – user2561747 Jan 26 at 3:03
8

To use that information on a script you can do this:

calcPercCpu.sh

#!/bin/bash
nPid=$1;
nTimes=10; # customize it
delay=0.1; # customize it
strCalc=`top -d $delay -b -n $nTimes -p $nPid \
  |grep $nPid \
  |sed -r -e "s;\s\s*; ;g" -e "s;^ *;;" \
  |cut -d' ' -f9 \
  |tr '\n' '+' \
  |sed -r -e "s;(.*)[+]$;\1;" -e "s/.*/scale=2;(&)\/$nTimes/"`;
nPercCpu=`echo "$strCalc" |bc -l`
echo $nPercCpu

use like: calcPercCpu.sh 1234 where 1234 is the pid

For the specified $nPid, it will measure the average of 10 snapshots of the cpu usage in a whole of 1 second (delay of 0.1s each * nTimes=10); that provides a good and fast accurate result of what is happening in the very moment.

Tweak the variables to your needs.

  • Uhm, 10 processes to monitor the cpu usage of 1? – xebeche Mar 13 at 14:19
  • @xebeche "it will measure the average of 10 snapshots" "nTimes=10; # customize it" :) – Aquarius Power Mar 19 at 22:55
  • I meant I don't like the fact that you call 10 processes to retrieve 1 number ($nPercCpu): shell, top, grep, sed, cut ... bc. Many if not all of these you could for instance merge into 1 Sed or Awk script. – xebeche Mar 19 at 23:29
  • @xebeche cool, feel free to edit adding a better command to the existing one (as an alternative), you got my curiosity :) – Aquarius Power Mar 24 at 1:03
  • 1
    I've added my own answer. BTW, note that there is no point in calculating an average because top's output is an average over $delay. Cf. How to calculate the CPU usage – xebeche Mar 26 at 17:12
5

I normally use following two :

  1. HP caliper : its very good tool for monitoring processes it you can check call graph and other low level information also. But please note its free only for personal use.

  2. daemontools : a collection of tools for managing UNIX services

  • 6
    I used daemontools for years. It's great as a supervisor/watchdog for other processes. How does it help you monitor CPU/memory usage for one process? – Stefan Lasiewski Aug 19 '10 at 4:05
3

Using top and awk one could easily create e.g. a comma separated log of %CPU ($9) + %MEM ($10) usage that can later be fed into any statistics and graphing tool.

top -b -d $delay -p $pid | awk -v OFS="," '$1+0>0 {
print strftime("%Y-%m-%d %H:%M:%S"),$1,$NF,$9,$10; fflush() }'

Output will be like

2019-03-26 17:43:47,2991,firefox,13.0,5.2
2019-03-26 17:43:48,2991,firefox,4.0,5.2
2019-03-26 17:43:49,2991,firefox,64.0,5.3
2019-03-26 17:43:50,2991,firefox,71.3,5.4
2019-03-26 17:43:51,2991,firefox,67.0,5.4

This won't give good results for large $delay, though, because the printed timestamp is actually $delay behind due to how top's output works. Without going into too much detail, 1 simple way around this is to log the time provided by top:

top -b -d $delay -p $pid | awk -v OFS="," '$1=="top"{ time=$3 }
$1+0>0 { print time,$1,$NF,$9,$10; fflush() }'

Then the timestamp is accurate, but output will still be delayed by $delay.

2

If you know process name you can use

top -p $(pidof <process_name>)
  • 8
    That's pretty much what the accepted answer, from years ago, and its first comment say. – dhag Apr 29 '15 at 15:26
1

If you have a cut-down Linux distribution where top does not have per process (-p) option or related options, you can parse the output of the top command for your process name to get the CPU usage information per process.

while true;  do top -bn1 | awk '/your_process_name/ {print  $8}' ; sleep 1; done

8 represents the CPU usage per process in the output of the top command in my embedded Linux distribution

1

Not enough reputation to comment, but for psrecord you can also call it directly, in a programmatic way, directly in Python:

from psrecord.main import monitor
monitor(<pid number>, logfile = "./test.log", plot="./fig.png", include_children=True)
0

If you need the averages for a period of time of a specific process, try the accumulative -c option of top:

top -c a -pid PID

"-c a" found in top for Mac 10.8.5.

For Scientific Linux, the option is -S, that can be set interactively.

  • You'll likely want to add further details around which version(s) of top actually provide this feature. My version on Fedora 19 does not. Same too on Ubuntu 13.04. – slm May 12 '14 at 1:22
  • You're right!, I was so happy of having found something useful, I forgot I was in my mac at home. – Kieleth May 13 '14 at 19:34
0

I'm a bit late here but I'll share my command line trick using just the default ps

WATCHED_PID=$({ command_to_profile >log.stdout 2>log.stderr & } && echo $!);
while ps -p $WATCHED_PID --no-headers --format "etime pid %cpu %mem rss" do; 
   sleep 1 
done

I use this as a one-liner. Here the first line fires the command and stores the PID in the variable. Then ps will print the elapsed time, the PID the percent CPU using, the percent memory, and the RSS memory. You can add other fields as well.

As soon as the process ends, the ps command won't return "success" and the while loop will end.

You can ignore the first line if the PID you want to profile is already running. Just place the desired id in the variable.

You'll get an output like this:

  00:00  7805  0.0  0.0  2784
  00:01  7805 99.0  0.8 63876
  00:02  7805 99.5  1.3 104532
  00:03  7805  100  1.6 129876
  00:04  7805  100  2.1 170796
  00:05  7805  100  2.9 234984
  00:06  7805  100  3.7 297552
  00:07  7805  100  4.0 319464
  00:08  7805  100  4.2 337680
  00:09  7805  100  4.5 358800
  00:10  7805  100  4.7 371736
  ....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.