@@ -50,6 +50,7 @@ def __init__(self, args, tree):
50
50
self .frames = {}
51
51
self .samples = []
52
52
self .last_task = None
53
+ self .metadata = {}
53
54
if self .args .trace :
54
55
for trace in self .args .trace :
55
56
if trace .endswith (".etl" ):
@@ -209,13 +210,17 @@ def calc_time_sync(time_sync, series=True):
209
210
210
211
def global_metadata (self , data ):
211
212
if data ['str' ] == "__process__" : # this is the very first record in the trace
212
- if data . has_key ( 'data' ) :
213
+ if 'data' in data :
213
214
self .file .write (
214
215
'{"name": "process_name", "ph":"M", "pid":%d, "tid":%d, "args": {"name":"%s"}},\n ' % (int (data ['pid' ]), int (data ['tid' ]), data ['data' ].replace ("\\ " , "\\ \\ " ).encode ('utf-8' ))
215
216
)
216
- if data . has_key ( 'delta' ) :
217
+ if 'delta' in data :
217
218
self .file .write (
218
- '{"name": "process_sort_index", "ph":"M", "pid":%d, "tid":%s, "args": {"sort_index":%d}},\n ' % (data ['pid' ], data ['tid' ], data ['delta' ])
219
+ '{"name": "process_sort_index", "ph":"M", "pid":%d, "tid":%s, "args": {"sort_index":%d}},\n ' % (data ['pid' ], data ['tid' ], abs (data ['delta' ]) if abs (data ['delta' ]) > 100 else data ['delta' ])
220
+ )
221
+ if 'labels' in data and data ['labels' ]:
222
+ self .file .write (
223
+ '{"name": "process_labels", "ph":"M", "pid":%d, "tid":%s, "args": {"labels":"%s"}},\n ' % (data ['pid' ], data ['tid' ], ',' .join (data ['labels' ]))
219
224
)
220
225
if data ['tid' ] >= 0 and not self .tree ['threads' ].has_key ('%d,%d' % (data ['pid' ], data ['tid' ])): # marking the main thread
221
226
self .file .write (
@@ -225,10 +230,12 @@ def global_metadata(self, data):
225
230
self .file .write (
226
231
'{"name": "thread_name", "ph":"M", "pid":%d, "tid":%d, "args": {"name":"%s"}},\n ' % (int (data ['pid' ]), int (data ['tid' ]), data ['data' ].replace ("\\ " , "\\ \\ " ).encode ('utf-8' ))
227
232
)
228
- if data . has_key ( 'delta' ) :
233
+ if 'delta' in data :
229
234
self .file .write (
230
- '{"name": "thread_sort_index", "ph":"M", "pid":%d, "tid":%s, "args": {"sort_index":%d}},\n ' % (data ['pid' ], data ['tid' ], data ['delta' ])
235
+ '{"name": "thread_sort_index", "ph":"M", "pid":%d, "tid":%s, "args": {"sort_index":%d}},\n ' % (data ['pid' ], data ['tid' ], abs ( data [ 'delta' ]) if abs ( data [ 'delta' ]) > 100 else data ['delta' ])
231
236
)
237
+ else :
238
+ self .metadata .setdefault (data ['str' ], []).append (data ['data' ])
232
239
233
240
def relation (self , data , head , tail ):
234
241
if not head or not tail :
@@ -266,12 +273,14 @@ def complete_task(self, type, begin, end):
266
273
self .last_task = (type , begin , end )
267
274
assert (GoogleTrace .Phase .has_key (type ))
268
275
if begin ['type' ] == 7 : # frame_begin
269
- begin ['id' ] = begin ['tid' ] if begin .has_key ('tid' ) else 0 # Async events are groupped by cat & id
276
+ if 'id' not in begin :
277
+ begin ['id' ] = id (begin ) # Async events are groupped by cat & id
270
278
res = self .format_task ('b' , 'frame' , begin , {})
271
- res += [',\n ' ]
272
- end_begin = begin .copy ()
273
- end_begin ['time' ] = end ['time' ]
274
- res += self .format_task ('e' , 'frame' , end_begin , {})
279
+ if end :
280
+ res += [',\n ' ]
281
+ end_begin = begin .copy ()
282
+ end_begin ['time' ] = end ['time' ] - 1000
283
+ res += self .format_task ('e' , 'frame' , end_begin , {})
275
284
else :
276
285
res = self .format_task (GoogleTrace .Phase [type ], type , begin , end )
277
286
@@ -331,7 +340,7 @@ def handle_stack(self, task, stack, name='stack'):
331
340
332
341
def format_task (self , phase , type , begin , end ):
333
342
res = []
334
- res .append ('{"ph":"%s"' % ( phase ) )
343
+ res .append ('{"ph":"%s"' % phase )
335
344
res .append (', "pid":%(pid)d' % begin )
336
345
if begin .has_key ('tid' ):
337
346
res .append (', "tid":%(tid)d' % begin )
@@ -374,7 +383,7 @@ def format_task(self, phase, type, begin, end):
374
383
res .append (', "cat":"%s"' % (begin ['domain' ]))
375
384
376
385
if 'id' in begin :
377
- res .append (', "id":%s ' % (begin ['id' ]))
386
+ res .append (', "id":"%s" ' % str (begin ['id' ]))
378
387
if type in ['task' ]:
379
388
dur = self .convert_time (end ['time' ]) - self .convert_time (begin ['time' ])
380
389
if dur < self .args .min_dur :
@@ -392,7 +401,8 @@ def format_task(self, phase, type, begin, end):
392
401
args ["__file__" ] = begin ["__file__" ]
393
402
args ["__line__" ] = begin ["__line__" ]
394
403
if 'counter' == type :
395
- args [name ] = begin ['delta' ]
404
+ if 'delta' in begin : # multi-counter is passed as named sub-counters dict
405
+ args [name ] = begin ['delta' ]
396
406
if 'memory' in begin :
397
407
total = 0
398
408
breakdown = {}
@@ -426,23 +436,31 @@ def remove_last(self, count):
426
436
self .file .truncate ()
427
437
428
438
def finish (self , intermediate = False ):
429
- if self .samples and not intermediate :
430
- self .remove_last (2 )
431
- self .file .write ('], "stackFrames": {\n ' )
432
- for id , frame in self .frames .iteritems ():
433
- self .file .write ('"%s": %s,\n ' % (id , json .dumps (frame )))
434
- if self .frames : # deleting last two symbols from the file as we can't leave comma at the end due to json restrictions
435
- self .remove_last (2 )
436
- self .file .write ('\n }, "samples": [\n ' )
437
- for sample in self .samples :
438
- self .file .write (json .dumps (sample ) + ',\n ' )
439
- if self .samples : # deleting last two symbols from the file as we can't leave comma at the end due to json restrictions
440
- self .remove_last (2 )
441
- self .file .write ('\n ]}' )
442
- self .samples = []
443
- self .frames = {}
444
- else :
445
- self .file .write ('{}]}' )
439
+ self .remove_last (2 ) # remove trailing ,\n
440
+ if not intermediate :
441
+ if self .samples :
442
+ self .file .write ('], "stackFrames": {\n ' )
443
+ for id , frame in self .frames .iteritems ():
444
+ self .file .write ('"%s": %s,\n ' % (id , json .dumps (frame )))
445
+ if self .frames : # deleting last two symbols from the file as we can't leave comma at the end due to json restrictions
446
+ self .remove_last (2 )
447
+ self .file .write ('\n }, "samples": [\n ' )
448
+ for sample in self .samples :
449
+ self .file .write (json .dumps (sample ) + ',\n ' )
450
+ if self .samples : # deleting last two symbols from the file as we can't leave comma at the end due to json restrictions
451
+ self .remove_last (2 )
452
+ self .samples = []
453
+ self .frames = {}
454
+ if self .metadata :
455
+ self .file .write ('\n ],\n ' )
456
+ for key , value in self .metadata .iteritems ():
457
+ self .file .write ('"%s": %s,\n ' % (key , json .dumps (value [0 ] if len (value ) == 1 else value )))
458
+ self .remove_last (2 ) # remove trailing ,\n
459
+ self .file .write ('\n }' )
460
+ self .file .close ()
461
+ return
462
+
463
+ self .file .write ('\n ]}' )
446
464
self .file .close ()
447
465
448
466
@staticmethod
0 commit comments