xref: /aosp_15_r20/external/trace-cmd/Documentation/README.PythonPlugin (revision 58e6ee5f017f6a8912852c892d18457e4bafb554)
1*58e6ee5fSAndroid Build Coastguard Worker PYTHON PLUGIN DOCUMENTATION
2*58e6ee5fSAndroid Build Coastguard Worker=============================
3*58e6ee5fSAndroid Build Coastguard Worker
4*58e6ee5fSAndroid Build Coastguard WorkerWith the python plugin (make python-plugin) you can now
5*58e6ee5fSAndroid Build Coastguard Workerwrite plugins in python. The API exported by the python
6*58e6ee5fSAndroid Build Coastguard Workerplugin itself (written in C) allows you to access most
7*58e6ee5fSAndroid Build Coastguard Workerinformation about a record from python.
8*58e6ee5fSAndroid Build Coastguard Worker
9*58e6ee5fSAndroid Build Coastguard WorkerTo write a python plugin, put a new .py file into a new
10*58e6ee5fSAndroid Build Coastguard Worker~/.trace-cmd/python/ directory.
11*58e6ee5fSAndroid Build Coastguard Worker
12*58e6ee5fSAndroid Build Coastguard WorkerThe most basic python plugin is this:
13*58e6ee5fSAndroid Build Coastguard Worker
14*58e6ee5fSAndroid Build Coastguard Worker--- %< ---
15*58e6ee5fSAndroid Build Coastguard Workerdef register(pevent):
16*58e6ee5fSAndroid Build Coastguard Worker    pass
17*58e6ee5fSAndroid Build Coastguard Worker--- >% ---
18*58e6ee5fSAndroid Build Coastguard Worker
19*58e6ee5fSAndroid Build Coastguard Workerwhich obviously does nothing at all.
20*58e6ee5fSAndroid Build Coastguard Worker
21*58e6ee5fSAndroid Build Coastguard WorkerTo register a callback, use the pevent.register_event_handler
22*58e6ee5fSAndroid Build Coastguard Workerfunction:
23*58e6ee5fSAndroid Build Coastguard Worker
24*58e6ee5fSAndroid Build Coastguard Worker--- %< ---
25*58e6ee5fSAndroid Build Coastguard Workerimport tracecmd
26*58e6ee5fSAndroid Build Coastguard Worker
27*58e6ee5fSAndroid Build Coastguard Workerdef my_event_handler(trace_seq, event):
28*58e6ee5fSAndroid Build Coastguard Worker    pass
29*58e6ee5fSAndroid Build Coastguard Worker
30*58e6ee5fSAndroid Build Coastguard Workerdef register(pevent):
31*58e6ee5fSAndroid Build Coastguard Worker    pevent.register_event_handler("subsys", "event_name",
32*58e6ee5fSAndroid Build Coastguard Worker                                  my_event_handler)
33*58e6ee5fSAndroid Build Coastguard Worker--- >% ---
34*58e6ee5fSAndroid Build Coastguard Worker
35*58e6ee5fSAndroid Build Coastguard Worker
36*58e6ee5fSAndroid Build Coastguard WorkerThere are four object types that you get, described below.
37*58e6ee5fSAndroid Build Coastguard Worker
38*58e6ee5fSAndroid Build Coastguard Worker tracecmd.PEvent
39*58e6ee5fSAndroid Build Coastguard Worker-----------------
40*58e6ee5fSAndroid Build Coastguard Worker
41*58e6ee5fSAndroid Build Coastguard WorkerThis is the class of the 'pevent' object above,
42*58e6ee5fSAndroid Build Coastguard Workeryou get one of those via your register callback.
43*58e6ee5fSAndroid Build Coastguard WorkerIt has one method and one property:
44*58e6ee5fSAndroid Build Coastguard Worker * register_event_handler() - example above, to register
45*58e6ee5fSAndroid Build Coastguard Worker                              an event handler function
46*58e6ee5fSAndroid Build Coastguard Worker * file_endian              - either '<' or '>' indicating
47*58e6ee5fSAndroid Build Coastguard Worker                              which endianness the file has,
48*58e6ee5fSAndroid Build Coastguard Worker                              to be used with struct.unpack()
49*58e6ee5fSAndroid Build Coastguard Worker
50*58e6ee5fSAndroid Build Coastguard Worker tracecmd.TraceSeq
51*58e6ee5fSAndroid Build Coastguard Worker-------------------
52*58e6ee5fSAndroid Build Coastguard Worker
53*58e6ee5fSAndroid Build Coastguard WorkerThis is the class of the 'trace_seq' parameter to your callback
54*58e6ee5fSAndroid Build Coastguard Workerfunction. It has only one method, puts(), to put data into the
55*58e6ee5fSAndroid Build Coastguard Workerbuffer. Formatting must be done in python.
56*58e6ee5fSAndroid Build Coastguard Worker
57*58e6ee5fSAndroid Build Coastguard Worker tracecmd.Event
58*58e6ee5fSAndroid Build Coastguard Worker----------------------
59*58e6ee5fSAndroid Build Coastguard Worker
60*58e6ee5fSAndroid Build Coastguard WorkerThis is the class of the 'event' parameter to your callback
61*58e6ee5fSAndroid Build Coastguard Workerfunction. Note that it doesn't just contain the format, but
62*58e6ee5fSAndroid Build Coastguard Workeralso the event data. As such, you can do much with this, and
63*58e6ee5fSAndroid Build Coastguard Workerthis is what you'll usually use. Each instance of this allows
64*58e6ee5fSAndroid Build Coastguard Workeraccess to record items via the dict protocol, and you can get
65*58e6ee5fSAndroid Build Coastguard Workerthe items via its keys() methods. So for example, your
66*58e6ee5fSAndroid Build Coastguard Workercallback could be
67*58e6ee5fSAndroid Build Coastguard Worker
68*58e6ee5fSAndroid Build Coastguard Worker--- %< ---
69*58e6ee5fSAndroid Build Coastguard Workerdef my_callback(trace_seq, event):
70*58e6ee5fSAndroid Build Coastguard Worker    for fieldname in event.keys():
71*58e6ee5fSAndroid Build Coastguard Worker        field = event[fieldname]
72*58e6ee5fSAndroid Build Coastguard Worker--- >% ---
73*58e6ee5fSAndroid Build Coastguard Worker
74*58e6ee5fSAndroid Build Coastguard WorkerEach field returned from the dict protocol is an instance of
75*58e6ee5fSAndroid Build Coastguard Workerthe next (and last) class:
76*58e6ee5fSAndroid Build Coastguard Worker
77*58e6ee5fSAndroid Build Coastguard Worker tracecmd.Field
78*58e6ee5fSAndroid Build Coastguard Worker----------------------
79*58e6ee5fSAndroid Build Coastguard Worker
80*58e6ee5fSAndroid Build Coastguard WorkerThis is an instance of a field, including its data. It affords
81*58e6ee5fSAndroid Build Coastguard Workernumerous use cases and is what you'll be using most.
82*58e6ee5fSAndroid Build Coastguard Worker
83*58e6ee5fSAndroid Build Coastguard Worker * If this is an integer field, i.e. 1, 2, 4 or 8 bytes long,
84*58e6ee5fSAndroid Build Coastguard Worker   you can convert it to the number contained, according to
85*58e6ee5fSAndroid Build Coastguard Worker   the file's endianness, by simply casting it to a long:
86*58e6ee5fSAndroid Build Coastguard Worker
87*58e6ee5fSAndroid Build Coastguard Worker     field = event['myint']
88*58e6ee5fSAndroid Build Coastguard Worker     value = long(field)
89*58e6ee5fSAndroid Build Coastguard Worker
90*58e6ee5fSAndroid Build Coastguard Worker * You can access the field's data, as field.data, and if the
91*58e6ee5fSAndroid Build Coastguard Worker   data is really a "__data_loc" type that will be resolved
92*58e6ee5fSAndroid Build Coastguard Worker   automatically. (If you don't know what this means, don't
93*58e6ee5fSAndroid Build Coastguard Worker   worry about it and just use field.data)
94*58e6ee5fSAndroid Build Coastguard Worker
95*58e6ee5fSAndroid Build Coastguard Worker
96*58e6ee5fSAndroid Build Coastguard WorkerThis is it. It's pretty simple. A fully-featured plugin could
97*58e6ee5fSAndroid Build Coastguard Workerlook like this:
98*58e6ee5fSAndroid Build Coastguard Worker
99*58e6ee5fSAndroid Build Coastguard Worker--- %< ---
100*58e6ee5fSAndroid Build Coastguard Workerdef my_event_handler(trace_seq, event):
101*58e6ee5fSAndroid Build Coastguard Worker    trace_seq.puts("myev: %u", long(event['myfield']))
102*58e6ee5fSAndroid Build Coastguard Worker
103*58e6ee5fSAndroid Build Coastguard Workerdef register(pevent):
104*58e6ee5fSAndroid Build Coastguard Worker    pevent.register_event_handler("subsys", "event_name",
105*58e6ee5fSAndroid Build Coastguard Worker                                  my_event_handler)
106*58e6ee5fSAndroid Build Coastguard Worker--- >% ---
107*58e6ee5fSAndroid Build Coastguard Worker
108*58e6ee5fSAndroid Build Coastguard Worker
109*58e6ee5fSAndroid Build Coastguard Worker Tips and tricks
110*58e6ee5fSAndroid Build Coastguard Worker-----------------
111*58e6ee5fSAndroid Build Coastguard Worker
112*58e6ee5fSAndroid Build Coastguard WorkerBe familiar with the struct module and use it, always
113*58e6ee5fSAndroid Build Coastguard Workerchecking endianness and potentially using pevent.file_endian.
114*58e6ee5fSAndroid Build Coastguard Worker
115*58e6ee5fSAndroid Build Coastguard Worker
116*58e6ee5fSAndroid Build Coastguard WorkerIf you need access to pevent in your callbacks, simply
117*58e6ee5fSAndroid Build Coastguard Workerpass it in yourself:
118*58e6ee5fSAndroid Build Coastguard Worker
119*58e6ee5fSAndroid Build Coastguard Worker--- %< ---
120*58e6ee5fSAndroid Build Coastguard Workerdef my_event_handler(pevent, trace_seq, event):
121*58e6ee5fSAndroid Build Coastguard Worker    pass
122*58e6ee5fSAndroid Build Coastguard Worker
123*58e6ee5fSAndroid Build Coastguard Workerdef register(pevent):
124*58e6ee5fSAndroid Build Coastguard Worker    pevent.register_event_handler("subsys", "event_name",
125*58e6ee5fSAndroid Build Coastguard Worker        lambda *args: my_event_handler(pevent, *args)
126*58e6ee5fSAndroid Build Coastguard Worker    )
127*58e6ee5fSAndroid Build Coastguard Worker--- >% ---
128