aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ctracecmd.i15
-rw-r--r--tracecmd-test.py36
-rw-r--r--tracecmd.py135
3 files changed, 150 insertions, 36 deletions
diff --git a/ctracecmd.i b/ctracecmd.i
index 80fface..20a681c 100644
--- a/ctracecmd.i
+++ b/ctracecmd.i
@@ -1,13 +1,28 @@
1// tracecmd.i 1// tracecmd.i
2%module ctracecmd 2%module ctracecmd
3%include typemaps.i
3 4
4%{ 5%{
5#include "trace-cmd.h" 6#include "trace-cmd.h"
6%} 7%}
7 8
9/* typemaps must come before the implementation of wrapped functions */
10extern int pevent_read_number_field_32(struct format_field *f, void *data,
11 unsigned long *OUTPUT, unsigned long *OUTPUT);
12
8%inline %{ 13%inline %{
14int pevent_read_number_field_32(struct format_field *f, void *data, unsigned long *hi, unsigned long *lo)
15{
16 unsigned long long val64;
17 int ret;
18 ret = pevent_read_number_field(f, data, &val64);
19 *hi = (unsigned long)(val64>>32);
20 *lo = (unsigned long)((val64<<32)>>32);
21 return ret;
22}
9%} 23%}
10 24
25
11/* SWIG can't grok these, define them to nothing */ 26/* SWIG can't grok these, define them to nothing */
12#define __trace 27#define __trace
13#define __attribute__(x) 28#define __attribute__(x)
diff --git a/tracecmd-test.py b/tracecmd-test.py
deleted file mode 100644
index e35523b..0000000
--- a/tracecmd-test.py
+++ /dev/null
@@ -1,36 +0,0 @@
1#!/usr/bin/env python
2
3from ctracecmd import *
4
5# Let's move the following into a new Trace object constructor
6filename = "trace.dat"
7trace_file = open(filename)
8handle = tracecmd_open(trace_file.fileno())
9tracecmd_read_headers(handle)
10tracecmd_init_data(handle)
11
12# These should be members, i.e. Trace.cpus
13pe = tracecmd_get_pevent(handle)
14cpus = tracecmd_cpus(handle)
15print "Trace %s contains data for %d cpus" % (filename, cpus)
16
17# FIXME: this doesn't print anything...
18tracecmd_print_events(handle)
19
20print "Cycling through the events for each CPU"
21for cpu in range(0,cpus):
22 print "CPU", cpu
23 rec = tracecmd_read_data(handle, cpu)
24 while True:
25 if rec:
26 # these should be members of a Record object
27 pid = pevent_data_pid(pe, rec)
28 comm = pevent_data_comm_from_pid(pe, pid)
29 type = pevent_data_type(pe, rec)
30 event = pevent_data_event_from_type(pe, type)
31 print "\t%f %s: pid=%d comm=%s type=%d" % \
32 (record_ts_get(rec), event_name_get(event), pid, comm, type)
33
34 rec = tracecmd_read_data(handle, cpu)
35 else:
36 break
diff --git a/tracecmd.py b/tracecmd.py
new file mode 100644
index 0000000..6520a48
--- /dev/null
+++ b/tracecmd.py
@@ -0,0 +1,135 @@
1#
2# Copyright (C) International Business Machines Corp., 2009
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17#
18# 2009-Dec-17: Initial version by Darren Hart <dvhltc@us.ibm.com>
19#
20
21from ctracecmd import *
22
23"""
24Python interface to the tracecmd library for parsing ftrace traces
25
26Python tracecmd applications should be written to this interface. It will be
27updated as the tracecmd C API changes and try to minimze the impact to python
28applications. The ctracecmd Python module is automatically generated using SWIG
29and it is recommended applications not use it directly.
30
31TODO: consider a complete class hierarchy of ftrace events...
32"""
33
34def _pevent_read_number_field(field, data):
35 ret,hi,lo = pevent_read_number_field_32(field, data)
36 if ret == 0:
37 return ret,long(long(hi).__lshift__(32)+lo)
38 return ret,None
39
40
41class Event(object):
42 def __init__(self, trace, record):
43 self.trace = trace
44 self.rec = record
45 type = pevent_data_type(trace.pe, record)
46 self.ec = pevent_data_event_from_type(trace.pe, type)
47
48 def __str__(self):
49 return "%f %s: pid=%d comm=%s type=%d" % \
50 (self.ts, self.name, self.num_field("common_pid"), self.comm, self.type)
51
52
53 # TODO: consider caching the results of the properties
54 @property
55 def comm(self):
56 return self.trace.comm_from_pid(self.pid)
57
58 @property
59 def name(self):
60 return event_name_get(self.ec)
61
62 @property
63 def pid(self):
64 return pevent_data_pid(self.trace.pe, self.rec)
65
66 @property
67 def ts(self):
68 # FIXME: this currently returns a float instead of a 64bit nsec value
69 return record_ts_get(self.rec)
70
71 @property
72 def type(self):
73 return pevent_data_type(self.trace.pe, self.rec)
74
75 def num_field(self, name):
76 # FIXME: need to find an elegant way to handle 64bit fields
77 f = pevent_find_any_field(self.ec, name)
78 ret,val = _pevent_read_number_field(f, record_data_get(self.rec))
79 return val
80
81
82class Trace(object):
83 """
84 Trace object represents the trace file it is created with.
85
86 The Trace object aggregates the tracecmd structures and functions that are
87 used to manage the trace and extract events from it.
88 """
89 def __init__(self, filename):
90 self.handle = None
91 self.pe = None
92
93 try:
94 file = open(filename)
95 self.handle = tracecmd_open(file.fileno())
96 print "self.handle: ", self.handle
97 #FIXME: check if these throw exceptions automatically or if we have
98 # to check return codes manually
99 tracecmd_read_headers(self.handle)
100 tracecmd_init_data(self.handle)
101 self.pe = tracecmd_get_pevent(self.handle)
102 except:
103 return None
104
105 @property
106 def cpus(self):
107 return tracecmd_cpus(self.handle)
108
109 def read_event(self, cpu):
110 rec = tracecmd_read_data(self.handle, cpu)
111 if rec:
112 return Event(self, rec)
113 return None
114
115 def peek_event(self, cpu):
116 pass
117
118 def comm_from_pid(self, pid):
119 return pevent_data_comm_from_pid(self.pe, pid)
120
121
122# Basic builtin test, execute module directly
123if __name__ == "__main__":
124 t = Trace("trace.dat")
125 print "Trace contains data for %d cpus" % (t.cpus)
126
127 for cpu in range(0, t.cpus):
128 print "CPU %d" % (cpu)
129 ev = t.read_event(cpu)
130 while ev:
131 print "\t%s" % (ev)
132 ev = t.read_event(cpu)
133
134
135