forked from HarshEvilGeek/Android-Log-Analyzer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathandroidloganalyzer.py
287 lines (260 loc) · 9.51 KB
/
androidloganalyzer.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
import sys
import zipfile
import re
import os
#configure these lines according to the app you wish to analyze
app_marker_name = 'com.fiberlink'
key_word_agent = 'agent'
key_word_docs = 'docs'
key_word_pim = 'pim'
key_word_device_info = 'device'
#standard constants
cmd_marker = 'Cmd line: '
key_word_anr = 'anr'
key_word_migration = 'migra'
key_word_wait = 'WAIT'
key_word_thread_id = 'tid='
key_word_held_by = 'held by tid='
key_word_dalvik_threads = 'DALVIK THREADS'
key_word_native_threads = 'NATIVE THREADS'
key_word_main = '"main"'
#global variables
map = {}
matchesMap = {}
def stripByteArrayString(line):
line = line.replace('\\t', ' ')
line = line.replace('\\r','')
line = line.replace('b\'','')
line = line.replace('\'','')
line = line.replace('\\n','')
line = line.replace('\\r','')
return line
def processAnr(filename, logfile):
f = logfile.open(filename, 'r')
currentapp = ''
ourapp = False
issue = False
ismain = False
currentthread = -1
threadtype = ''
deadlockoccured = False
deadlock = []
finaldeadlock = []
deadlockapp = ''
mainwait = ''
mainheldby = ''
threadstate = ''
threadwait = {}
threadstoprint = []
firstapplines = []
threadregex = re.compile('.*".+".*prio=\d+.*tid=\d+.*')
for line in f:
line = str(line)
if cmd_marker in line:
currentapp = stripByteArrayString(line[line.index(cmd_marker) + len(cmd_marker):])
threadwait = {}
if currentapp.startswith(app_marker_name):
ourapp = True
if ourapp and ismain and app_marker_name in line:
firstapplines.append(stripByteArrayString(line)[2:])
elif key_word_dalvik_threads in line:
threadtype = 'Dalvik'
elif key_word_native_threads in line:
threadtype = 'Native'
elif re.match(threadregex, line):
analyze = line[line.index(key_word_thread_id):]
currentthread = int(re.findall('\d+',analyze)[0])
threadstate = re.findall('[A-Z]+',analyze)[0]
if key_word_main in line:
ismain = True
if threadstate is key_word_wait:
identifier = (currentapp, currentthread)
threadstoprint.append(identifier)
mainwait = currentapp
else:
ismain = False
if key_word_held_by in line:
analyze = line[line.index(key_word_held_by):]
heldby = int(re.findall('\d+',analyze)[0])
threadwait[currentthread] = heldby
lookfor = [currentthread]
if currentthread is not heldby and threadtype is not 'Native':
if ismain:
mainheldby = heldby
try:
identifier = (currentapp, currentthread)
threadstoprint.append(identifier)
deadlock.append(identifier)
identifier = (currentapp, heldby)
threadstoprint.append(identifier)
deadlock.append(identifier)
while heldby is not threadwait[heldby]:
lookfor.append(heldby)
heldby = threadwait[heldby]
identifier = (currentapp, heldby)
threadstoprint.append(identifier)
deadlock.append(identifier)
if heldby in lookfor:
if mainheldby is not '':
if mainheldby in deadlock or not finaldeadlock:
finaldeadlock = deadlock
deadlockapp = currentapp
else:
finaldeadlock = deadlock
deadlockapp = currentapp
deadlock = []
deadlockoccured = True
break
else:
deadlockoccured = False;
if not deadlockoccured:
deadlock = []
except:
deadlock = []
print('Most likely cause of ANR:\n')
if len(finaldeadlock) > 0:
print('Deadlock has occured in ' + deadlockapp + '\n')
last = len(finaldeadlock) - 1
deadlockedthreads = []
for i in range (0, len(finaldeadlock)):
deadlockedthreads.append(finaldeadlock[i][1])
if i == last:
print ('thread number ' + str(finaldeadlock[i][1]))
elif i == 0:
print ('Thread number ' + str(finaldeadlock[i][1]) + ' was held by '),
else:
print ('Thread number ' + str(finaldeadlock[i][1]) + ' which was held by '),
if mainheldby is not '' and mainheldby in deadlockedthreads:
print ('main thread is held by ' + str(mainheldby) + ' which is deadlocked ')
elif mainwait:
print('Main thread of ' + mainwait + ' is waiting\n')
else:
print('Heavy operations on UI. Might be caused from the following classes:\n')
for line in firstapplines:
print(line)
p = False
print ('\nThreads to look at:\n')
f = logfile.open(filename, 'r')
for line in f:
line = str(line)
if cmd_marker in line:
currentapp = stripByteArrayString(line[line.index(cmd_marker) + len(cmd_marker):])
elif re.match(threadregex, line):
analyze = line[line.index(key_word_thread_id):]
currentthread = int(re.findall('\d+',analyze)[0])
identifier = (currentapp, currentthread)
if identifier in threadstoprint:
print('In app ' + currentapp + ':')
p = True
else:
p = False
if p:
print (stripByteArrayString(line))
def processLog(filename, logfile):
p = False
f = logfile.open(filename, 'r')
found = False
end = re.compile('.*\d+\-\d+\-\d.*')
for line in f:
line = str(line)
if end.match(line):
if p:
print('\n\n')
p = False
if 'UNCAUGHT EXCEPTION' in line:
p = True
print ('\nUncaught Exception in file ' + filename + '\n')
found = True
if p:
line = stripByteArrayString(line)
print(line)
for key in matchesMap:
if key in line:
line = stripByteArrayString(line)
time = line.split(' |')[0]
matchesMap[key].append(time);
if not found:
print('No uncaught exceptions in file ' + filename + '\n')
def processDeviceLog(filename, logfile):
with logfile.open(filename, 'r') as f:
for line in f:
line = str(line)
line = stripByteArrayString(line)
print(line)
def main():
printdevicedata = False;
if (len(sys.argv) < 2):
print('Please pass the path of the zipped log file or log folder as an argument')
return
logfile = ''
f = open('map.txt', 'r')
for line in f:
temp = [x.strip() for x in line.split(':')]
map[temp[0]] = temp[1]
matchesMap[temp[1]] = []
f.close()
if os.path.isdir(sys.argv[1]):
logfile = zipfile.ZipFile(sys.argv[1] + '.zip', 'w')
for dirname, subdirs, files in os.walk(sys.argv[1]):
logfile.write(dirname)
for filename in files:
logfile.write(os.path.join(dirname, filename))
elif 'zip' in sys.argv[1]:
logfile = zipfile.ZipFile(sys.argv[1])
else:
logfile = zipfile.ZipFile('logs.zip', 'w')
logfile.write(sys.argv[1])
files = logfile.namelist()
anr = False
migration = False
pim = False
docs = False
for filename in files:
if key_word_device_info in filename and printdevicedata:
print('Device Info\n')
processDeviceLog(filename, logfile)
if key_word_anr in filename:
anr = True
if key_word_migration in filename:
migration = True
if key_word_pim in filename:
pim = True
if key_word_docs in filename:
docs = True
if anr:
print('\nProcessing ANR Logs\n')
for filename in files:
if key_word_anr in filename:
processAnr(filename, logfile)
if migration:
print('\nProcessing Migration Logs\n')
for filename in files:
if key_word_migration in filename:
processLog(filename, logfile)
print('\nProcessing Agent Logs\n')
for filename in files:
if key_word_agent in filename:
processLog(filename, logfile)
if pim:
print('\nProcessing PIM Logs\n')
for filename in files:
if key_word_pim in filename:
processLog(filename, logfile)
if docs:
print('\nProcessing Docs Logs\n')
for filename in files:
if key_word_docs in filename:
processLog(filename, logfile)
for key in map:
temp = matchesMap[map[key]]
if (len(temp) > 0):
sys.stdout.write (key + ': ' + str(len(temp)) + ' occurences at ')
last = len(temp) - 1
for i in range (0, len(temp)):
if i == last:
print ('and ' + temp[i] + '\n')
else:
sys.stdout.write (temp[i] + ', ')
logfile.close()
if __name__ == '__main__':
main()