# Takes 'stap-out.pickle' generated by parse_stap_out.py
# and pretty-prints it in HTML format

from parse_stap_out import Process
import cPickle, datetime

def ms_to_datetime(ms):
  return datetime.datetime.fromtimestamp(float(ms) / 1000)


def pretty_duration_str(td):
  assert type(td) is datetime.timedelta

  if td.seconds == 0:
    # anything less than 1/10 second is "instant"
    if td.microseconds < 100000:
      return 'instant'
    else:
      return '%.2gs' % (float(td.microseconds) / 1000000)
  elif td.seconds < 3600:
    m = td.seconds / 60
    s = td.seconds % 60
    return '%02d:%02d' % (m, s)
  else:
    return str(td)


all_procs = cPickle.load(open('stap-out.pickle'))

# sort by creation_time
all_procs_lst = all_procs.values()
all_procs_lst.sort(key = lambda e: e.creation_time)

initial_dt = ms_to_datetime(all_procs_lst[0].creation_time)

import os
my_uid = os.getuid()

print "Session start", initial_dt
print

for proc in all_procs_lst:
  # only print out programs that YOU'VE launched!
  if proc.uid != my_uid: continue

  print 'Name:', proc.get_canonical_name()

  parent = None
  if proc.ppid in all_procs:
    parent = all_procs[proc.ppid]


  if parent:
    print "  Parent:", parent.get_canonical_name()
  else:
    print "  Parent not found :("

  start_dt = ms_to_datetime(proc.creation_time)
  rel_start_dt = start_dt - initial_dt
  print "Start:", rel_start_dt


  if proc.uid_changed:
    print "UID changed!"


  if proc.exited:
    print "Duration:", pretty_duration_str(ms_to_datetime(proc.exit_time) - start_dt)
    if proc.exit_code != 0:
      print "EXIT WITH ERROR", proc.exit_code
  else:
    print "NOT EXITED"

  for e in proc.execve_calls:
    print '  EXEC:', e
  '''
  for e in sorted(proc.files_read):
    print '  READ:  ', e
  for e in sorted(proc.files_written):
    print '  WRITE: ', e
  for e in sorted(proc.files_renamed):
    print '  RENAME:', e
  '''

  print

