aboutsummaryrefslogblamecommitdiffstats
path: root/tracecmd.py
blob: e7ea5f6b2928450bfc7a349c35eafed08aced9db (plain) (tree)
































                                                                               
                    
                                           

                          
                      
                                                 
                                                                 

                      


                                                                            
 


                              







                                                          
                                                 






                                                       






                                                        
                                                    
                                                                       














                                                                              
                                                 














                                                                               

                            
                                        

                   




                                                                         




                                  
 




















                                                      
#
# Copyright (C) International Business Machines  Corp., 2009
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# 2009-Dec-17:	Initial version by Darren Hart <dvhltc@us.ibm.com>
#

from ctracecmd import *

"""
Python interface to the tracecmd library for parsing ftrace traces

Python tracecmd applications should be written to this interface. It will be
updated as the tracecmd C API changes and try to minimze the impact to python
applications. The ctracecmd Python module is automatically generated using SWIG
and it is recommended applications not use it directly.

TODO: consider a complete class hierarchy of ftrace events...
"""

class Event(object):
    def __init__(self, trace, record, cpu):
        self.trace = trace
        self.rec = record
        self.cpu = cpu
        type = pevent_data_type(trace.pe, record)
        self.format = pevent_data_event_from_type(trace.pe, type)

    def __str__(self):
        return "%d.%d CPU%d %s: pid=%d comm=%s type=%d" % \
               (self.ts/1000000000, self.ts%1000000000, self.cpu, self.name,
                self.num_field("common_pid"), self.comm, self.type)

    def __del__(self):
        free_record(self.rec);


    # TODO: consider caching the results of the properties
    @property
    def comm(self):
        return self.trace.comm_from_pid(self.pid)

    @property
    def name(self):
        return event_format_name_get(self.format)

    @property
    def pid(self):
        return pevent_data_pid(self.trace.pe, self.rec)

    @property
    def ts(self):
        return record_ts_get(self.rec)

    @property
    def type(self):
        return pevent_data_type(self.trace.pe, self.rec)

    def num_field(self, name):
        f = pevent_find_any_field(self.format, name)
        val = pevent_read_number_field_py(f, record_data_get(self.rec))
        return val


class Trace(object):
    """
    Trace object represents the trace file it is created with.

    The Trace object aggregates the tracecmd structures and functions that are
    used to manage the trace and extract events from it.
    """
    def __init__(self, filename):
        self.handle = None
        self.pe = None

        try:
            self.handle = tracecmd_open(filename)
            #FIXME: check if these throw exceptions automatically or if we have
            #       to check return codes manually
            tracecmd_read_headers(self.handle)
            tracecmd_init_data(self.handle)
            self.pe = tracecmd_get_pevent(self.handle)
        except:
            return None

    @property
    def cpus(self):
        return tracecmd_cpus(self.handle)

    def read_event(self, cpu):
        rec = tracecmd_read_data(self.handle, cpu)
        if rec:
            #rec.acquire()
            #rec.thisown = 1
            return Event(self, rec, cpu)
        return None

    def read_event_at(self, offset):
        res = tracecmd_read_at(self.handle, offset)
        # SWIG only returns the CPU if the record is None for some reason
        if isinstance(res, int):
            return None
        rec,cpu = res
        #rec.acquire()
        #rec.thisown = 1
        ev = Event(self, rec, cpu)
        return ev

    def peek_event(self, cpu):
        pass

    def comm_from_pid(self, pid):
        return pevent_data_comm_from_pid(self.pe, pid)


# Basic builtin test, execute module directly
if __name__ == "__main__":
    t = Trace("trace.dat")
    print "Trace contains data for %d cpus" % (t.cpus)

    for cpu in range(0, t.cpus):
        print "CPU %d" % (cpu)
        ev = t.read_event(cpu)
        while ev:
            print "\t%s" % (ev)
            ev = t.read_event(cpu)