2

I'm trying to log the output of CPU and RAM consumption of specific processes in linux using python's os.system() command. To differentiate the output taken at each iteration, I've added print statements with the iteration number above and below this os.system() command.

My code is as below:

import os
i=0
while i<30:
    print "----CPU----"
    op=os.system("ps -raxxxo pid,%cpu,%mem,vsize,time,command | grep -E 'java|gui' ")
    print i
    i+=1
    sleep(1.0/3.0)

Now, after running the script and taking a look at the log it doesnt meet my expectation. I see that for all iterations the output for os.system is printed first and then those print statements are at the end. This doesnt help me differentiate the output of each iteration.

Output after running the python script.py >& log.txt. (I'm running this script in linux env) - partial output

1332   0.0  3.6  572960     5:56.04 /data/bin/gui
20978   0.0  0.5   79480     1:47.16 java
13040   0.0  0.0   18976     0:00.00 grep -E java|gui
1332   0.0  3.6  572960     5:56.04 /data/bin/gui
20978   0.0  0.5   79480     1:47.16 java
13043   0.0  0.0   18976     0:00.00 grep -E java|gui
----CPU----
0
1
----CPU----
0
2

How can I have an output like below in python?

----CPU----
1332   0.0  3.6  572960     5:56.04 /data/bin/gui
20978   0.0  0.5   79480     1:47.16 java
13043   0.0  0.0   18976     0:00.00 grep -E java|gui
<iteration-number>

Looking forward to the community's answer and comments. Also, if this is a duplicate question please point me the similar one as I didn't get a similar Q&A for it.

pratz91
  • 25
  • 1
  • 9
  • Possible duplicate of [Python script prints output of os.system before print](https://stackoverflow.com/questions/15731231/python-script-prints-output-of-os-system-before-print) – urban Dec 03 '17 at 10:47

2 Answers2

2

It would seem that os.system and print use different buffers that are flushed in different times! (for explanation see here and crosslink)

The following works for me (force flushing the output):

import os
import sys
from time import sleep


i=0
while i<30:
    print "----CPU----"
    sys.stdout.flush()
    op=os.system("ps -e -o pid,%cpu,%mem,vsize,time,command | grep java | grep -v grep ")
    sys.stdout.flush()
    print i
    sys.stdout.flush()
    i+=1
    sleep(1.0/3.0)

Alternatively:

  • use the -u flag to disable buffered output (python -u /tmp/test.py 1> /tmp/test.log)
  • use subprocess.check_output() or
  • pipe the idividual processes (instead of spawning a shell) which is a bit more long-winded (see here)

Hope it helps

urban
  • 5,392
  • 3
  • 19
  • 45
  • Using the -u flag while running the script helped. And thanks for sharing the link to explanation. Seems my question became duplicate to that thread. Link : (https://stackoverflow.com/questions/15731231/python-script-prints-output-of-os-system-before-print/15731329#15731329) – pratz91 Dec 02 '17 at 19:52
0

While urban's answer gives great context and general tips...

... to answer your precise question. You can simply add a date call to every call of your one-liner, e.g.

op=os.system("date && ps -raxxxo pid,%cpu,%mem,vsize,time,command | grep -E 'java|gui' ")

or

op=os.system("date +%s && ps -raxxxo pid,%cpu,%mem,vsize,time,command | grep -E 'java|gui' ")

for less readable, but more distinct output.

Grzegorz Oledzki
  • 23,614
  • 16
  • 68
  • 106
  • Thanks for the comment, though Urban's answer helps here much. It was a matter of flushing the buffer. – pratz91 Dec 02 '17 at 19:57