Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: telemetry/telemetry/value/trace.py

Issue 2661573003: Refactor TraceData to encapsulate internal traces' representation (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import datetime 5 import datetime
6 import json
7 import logging 6 import logging
8 import os 7 import os
9 import random 8 import random
10 import shutil 9 import shutil
11 import subprocess
12 import sys 10 import sys
13 import tempfile 11 import tempfile
14 12
15 from py_utils import cloud_storage # pylint: disable=import-error 13 from py_utils import cloud_storage # pylint: disable=import-error
16 14
17 from telemetry.internal.util import file_handle 15 from telemetry.internal.util import file_handle
18 from telemetry.timeline import trace_data as trace_data_module 16 from telemetry.timeline import trace_data as trace_data_module
19 from telemetry import value as value_module 17 from telemetry import value as value_module
20 18
21 _TRACE2HTML_PATH = os.path.join(os.path.dirname(__file__), '..', '..', '..',
22 'tracing', 'bin', 'trace2html')
23
24 19
25 class TraceValue(value_module.Value): 20 class TraceValue(value_module.Value):
26 def __init__(self, page, trace_data, important=False, description=None): 21 def __init__(self, page, trace_data, important=False, description=None):
27 """A value that contains a TraceData object and knows how to 22 """A value that contains a TraceData object and knows how to
28 output it. 23 output it.
29 24
30 Adding TraceValues and outputting as JSON will produce a directory full of 25 Adding TraceValues and outputting as JSON will produce a directory full of
31 HTML files called trace_files. Outputting as chart JSON will also produce 26 HTML files called trace_files. Outputting as chart JSON will also produce
32 an index, files.html, linking to each of these files. 27 an index, files.html, linking to each of these files.
33 """ 28 """
34 super(TraceValue, self).__init__( 29 super(TraceValue, self).__init__(
35 page, name='trace', units='', important=important, 30 page, name='trace', units='', important=important,
36 description=description, tir_label=None, grouping_keys=None) 31 description=description, tir_label=None, grouping_keys=None)
37 self._temp_file = self._GetTempFileHandle(trace_data) 32 self._temp_file = self._GetTempFileHandle(trace_data)
38 self._cloud_url = None 33 self._cloud_url = None
39 self._serialized_file_handle = None 34 self._serialized_file_handle = None
40 35
41 @property 36 @property
42 def value(self): 37 def value(self):
43 if self._cloud_url: 38 if self._cloud_url:
44 return self._cloud_url 39 return self._cloud_url
45 elif self._serialized_file_handle: 40 elif self._serialized_file_handle:
46 return self._serialized_file_handle.GetAbsPath() 41 return self._serialized_file_handle.GetAbsPath()
47 42
48 def _GetTraceParts(self, trace_data): 43 def _GetTraceParts(self, trace_data):
49 return [(trace_data.GetTracesFor(p), p) 44 return [(trace_data.GetTracesFor(p), p)
50 for p in trace_data_module.ALL_TRACE_PARTS 45 for p in trace_data_module.ALL_TRACE_PARTS
51 if trace_data.HasTracesFor(p)] 46 if trace_data.HasTracesFor(p)]
52 47
53 @staticmethod
54 def _DumpTraceToFile(trace, path):
55 with open(path, 'w') as fp:
56 if isinstance(trace, basestring):
57 fp.write(trace)
58 elif isinstance(trace, dict) or isinstance(trace, list):
59 json.dump(trace, fp)
60 else:
61 raise TypeError('Trace is of unknown type.')
62
63 def _GetTempFileHandle(self, trace_data): 48 def _GetTempFileHandle(self, trace_data):
64 temp_dir = tempfile.mkdtemp() 49 tf = tempfile.NamedTemporaryFile(delete=False, suffix='.html')
65 trace_files = [] 50 tf.close()
66 counter = 0 51 title = ''
67 try: 52 if self.page:
68 trace_size_data = {} 53 title = self.page.display_name
69 for traces_list, part in self._GetTraceParts(trace_data): 54 trace_data.Serialize(tf.name, trace_title=title)
70 for trace in traces_list: 55 return file_handle.FromFilePath(tf.name)
71 if isinstance(trace, trace_data_module.TraceFileHandle):
72 file_path = trace.file_path
73 else:
74 file_path = os.path.join(temp_dir, '%s.trace' % counter)
75 self._DumpTraceToFile(trace, file_path)
76 trace_size_data.setdefault(part, 0)
77 trace_size_data[part] += os.path.getsize(file_path)
78 trace_files.append(file_path)
79 counter += 1
80 logging.info('Trace sizes in bytes: %s', trace_size_data)
81 tf = tempfile.NamedTemporaryFile(delete=False, suffix='.html')
82 tf.close()
83 if trace_files:
84 title = ''
85 if self.page:
86 title = self.page.display_name
87 cmd = (['python', _TRACE2HTML_PATH] + trace_files +
88 ['--output', tf.name] + ['--title', title])
89 subprocess.check_output(cmd)
90 else:
91 logging.warning('No traces to convert to html.')
92 return file_handle.FromTempFile(tf)
93 finally:
94 shutil.rmtree(temp_dir)
95 56
96 def __repr__(self): 57 def __repr__(self):
97 if self.page: 58 if self.page:
98 page_name = self.page.display_name 59 page_name = self.page.display_name
99 else: 60 else:
100 page_name = 'None' 61 page_name = 'None'
101 return 'TraceValue(%s, %s)' % (page_name, self.name) 62 return 'TraceValue(%s, %s)' % (page_name, self.name)
102 63
103 def CleanUp(self): 64 def CleanUp(self):
104 """Cleans up tempfile after it is no longer needed. 65 """Cleans up tempfile after it is no longer needed.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 fh.extension)) 151 fh.extension))
191 self._cloud_url = cloud_storage.Insert( 152 self._cloud_url = cloud_storage.Insert(
192 bucket, remote_path, fh.GetAbsPath()) 153 bucket, remote_path, fh.GetAbsPath())
193 sys.stderr.write( 154 sys.stderr.write(
194 'View generated trace files online at %s for page %s\n' % 155 'View generated trace files online at %s for page %s\n' %
195 (self._cloud_url, self.page.url if self.page else 'unknown')) 156 (self._cloud_url, self.page.url if self.page else 'unknown'))
196 return self._cloud_url 157 return self._cloud_url
197 except cloud_storage.PermissionError as e: 158 except cloud_storage.PermissionError as e:
198 logging.error('Cannot upload trace files to cloud storage due to ' 159 logging.error('Cannot upload trace files to cloud storage due to '
199 ' permission error: %s' % e.message) 160 ' permission error: %s' % e.message)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698