Fix: update tests for --no-intersection
[deliverable/lttng-analyses.git] / parser_generator.py
1 #!/usr/bin/env python3
2 #
3 # The MIT License (MIT)
4 #
5 # Copyright (C) 2015 - Julien Desfossez <jdesfossez@efficios.com>
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 # SOFTWARE.
24
25 import sys
26 import os
27 import stat
28 import argparse
29
30 try:
31 from babeltrace import TraceCollection, CTFScope
32 except ImportError:
33 # quick fix for debian-based distros
34 sys.path.append("/usr/local/lib/python%d.%d/site-packages" %
35 (sys.version_info.major, sys.version_info.minor))
36 from babeltrace import TraceCollection, CTFScope
37
38 preambule = """#!/usr/bin/env python3
39
40 import sys
41 import time
42 import argparse
43
44 NSEC_PER_SEC = 1000000000
45
46 try:
47 from babeltrace import TraceCollection
48 except ImportError:
49 # quick fix for debian-based distros
50 sys.path.append("/usr/local/lib/python%d.%d/site-packages" %
51 (sys.version_info.major, sys.version_info.minor))
52 from babeltrace import TraceCollection
53
54
55 class TraceParser:
56 def __init__(self, trace):
57 self.trace = trace
58 self.event_count = {}
59
60 def ns_to_hour_nsec(self, ns):
61 d = time.localtime(ns/NSEC_PER_SEC)
62 return "%02d:%02d:%02d.%09d" % (d.tm_hour, d.tm_min, d.tm_sec,
63 ns % NSEC_PER_SEC)
64
65 def parse(self):
66 # iterate over all the events
67 for event in self.trace.events:
68 if not event.name in self.event_count.keys():
69 self.event_count[event.name] = 0
70 method_name = "handle_%s" % \
71 event.name.replace(":", "_").replace("+", "_")
72 # call the function to handle each event individually
73 if hasattr(TraceParser, method_name):
74 func = getattr(TraceParser, method_name)
75 func(self, event)
76 # print statistics after parsing the trace
77 print("Total event count:")
78 for e in self.event_count.keys():
79 print("- %s: %d" % (e, self.event_count[e]))
80
81 """
82
83 end = """
84 if __name__ == "__main__":
85 parser = argparse.ArgumentParser(description='Trace parser')
86 parser.add_argument('path', metavar="<path/to/trace>", help='Trace path')
87 args = parser.parse_args()
88
89 traces = TraceCollection()
90 handle = traces.add_traces_recursive(args.path, "ctf")
91 if handle is None:
92 sys.exit(1)
93
94 t = TraceParser(traces)
95 t.parse()
96
97 for h in handle.values():
98 traces.remove_trace(h)
99 """
100
101
102 def gen_parser(handle, fd, args):
103 for h in handle.values():
104 for event in h.events:
105 fmt_str = "[%s] %s: { cpu_id = %s }, { "
106 fmt_fields = "self.ns_to_hour_nsec(timestamp), event.name, " \
107 "cpu_id, "
108 name = event.name.replace(":", "_").replace("+", "_")
109 fd.write(" def handle_%s(self, event):\n" % (name))
110 fd.write(" timestamp = event.timestamp\n")
111 fd.write(" cpu_id = event[\"cpu_id\"]\n")
112 for field in event.fields:
113 if field.scope == CTFScope.EVENT_FIELDS:
114 fname = field.name
115 # some field names are reserved keywords/variables
116 if fname == "in":
117 fname = "_in"
118 if fname == "event":
119 fname = "_event"
120 if fname == "from":
121 fname = "_from"
122 fd.write(" %s = event[\"%s\"]\n" % (fname,
123 field.name))
124 fmt_str = fmt_str + field.name + " = %s, "
125 fmt_fields = fmt_fields + "%s, " % (fname)
126 fd.write("\n self.event_count[event.name] += 1\n")
127 if not args.quiet:
128 fd.write(" print(\"%s }\" %% (%s))\n\n" %
129 (fmt_str[0:-2], fmt_fields[0:-1]))
130
131
132 if __name__ == "__main__":
133 parser = argparse.ArgumentParser(description='Trace parser generator')
134 parser.add_argument('path', metavar="<path/to/trace>", help='Trace path')
135 parser.add_argument('-o', '--output', type=str,
136 metavar="<output-script-name>",
137 help='Output script name')
138 parser.add_argument('-q', '--quiet', action="store_true",
139 help='Generate a quiet parser (no print)')
140 args = parser.parse_args()
141
142 traces = TraceCollection()
143 handle = traces.add_traces_recursive(args.path, "ctf")
144 if handle is None:
145 sys.exit(1)
146
147 if not args.output:
148 output = "generated-parser.py"
149 else:
150 output = args.output
151
152 fd = open(output, "w")
153 fd.write(preambule)
154 gen_parser(handle, fd, args)
155
156 for h in handle.values():
157 traces.remove_trace(h)
158 fd.write(end)
159 fd.close()
160 os.chmod(output, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
161 stat.S_IRGRP | stat.S_IXGRP |
162 stat.S_IROTH | stat.S_IXOTH)
163 print("A trace parser for this trace has been written in", output)
This page took 0.03504 seconds and 5 git commands to generate.