-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsplit_traces.py
executable file
·134 lines (105 loc) · 4.37 KB
/
split_traces.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/python
# Copyright 2015 Personal [email protected].
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import sys
import re
import argparse
import string
__author__ = 'duanqizhi'
class Options:
def __init__(self, **kwds):
self.__dict__.update(kwds)
@staticmethod
def parse_arguments():
parser = argparse.ArgumentParser(description='Split traces by each pid.')
parser.add_argument('-f', '--file', dest='file', help='text file containing android traces log')
parser.add_argument('-p', '--pid', dest='pid', help='filter out trace partitions of the pid', type=int)
args = parser.parse_args()
if args.file is None:
parser.print_help()
sys.exit(1)
return args
class Traces:
""" Model of text traces file
"""
# Regex to match text like: "----- pid 880 at 2015-10-14 13:47:53 -----", group out pid and time
RE_START = re.compile("----- pid (?P<pid>\d+) at (?P<time>.*?) -----")
# Regex to match text like: "Cmd line: system_server", group out process name
RE_PNAME = re.compile("Cmd line: (?P<pname>.*)")
# Regex to match text like: "----- end 880 -----", group out pid
RE_END = re.compile("----- end (?P<pid>\d+) -----")
def __init__(self, in_file):
self.in_file = in_file
self.partition_dir = os.path.join(os.path.dirname(in_file), "partitions")
if not os.path.exists(self.partition_dir):
os.makedirs(self.partition_dir)
def split(self, pid=None):
""" Split the traces.txt to partitions.
:param pid: If pid is presented, only keep partitions of the pid
"""
f = open(self.in_file, "r")
all_lines = f.readlines()
partition_name = None
process_name = None
content = None
num = 0
for line in all_lines:
# Escape the illegal characters
line = line.replace("\00", "")
if partition_name is None:
start = Traces.RE_START.match(line)
if start is not None:
start_pid = start.group("pid")
if pid is not None and int(start_pid) != pid:
#print "ignore"
continue
start_time = start.group("time")
# Generate the partition_name with pid and time
partition_name = "%s_%s" % (start_pid, start_time.replace(" ", "-"))
content = line
num += 1
continue
if partition_name:
content += line
if process_name is None:
process_match = Traces.RE_PNAME.match(line)
if process_match is not None:
process_name = os.path.basename(process_match.group("pname"))
# Insert the process_name to partition_name
partition_name = "%s_%s" % (process_name, partition_name)
print("%s" % partition_name)
else:
end = Traces.RE_END.match(line)
if end is not None:
self.write_partition(partition_name, content)
partition_name = None
process_name = None
f.close()
if num > 0:
print('* Totally %d partitions are split out into "%s" ' % (num, os.path.abspath(self.partition_dir)))
else:
print('* No partition is split out.')
def write_partition(self, partition_name, content):
partition_path = os.path.join(self.partition_dir, partition_name)
f = open(partition_path, "w+")
f.seek(0)
f.truncate()
f.writelines(content)
f.flush()
f.close()
if __name__ == '__main__':
args = Options.parse_arguments()
Traces(args.file).split(args.pid)