def get(self): recording.dont_record() time_key = self.request.get('time') key = str(self.request.get('key')) timestamp = None record = None if time_key: try: timestamp = int(time_key) * 0.001 except Exception: pass if timestamp: record = recording.load_full_proto(recording.make_key(timestamp)) elif key: record = recording.load_full_proto(key) if record is None: self.response.set_status(404) self.response.out.write(render('details.html', {})) return rpcstats_map = {} for rpc_stat in record.individual_stats_list(): key = rpc_stat.service_call_name() count, real, api = rpcstats_map.get(key, (0, 0, 0)) count += 1 real += rpc_stat.duration_milliseconds() api += rpc_stat.api_mcycles() rpcstats_map[key] = (count, real, api) rpcstats_by_count = [ (name, count, real, recording.mcycles_to_msecs(api)) for name, (count, real, api) in rpcstats_map.iteritems()] rpcstats_by_count.sort(key=lambda x: -x[1]) real_total = 0 api_total_mcycles = 0 for i, rpc_stat in enumerate(record.individual_stats_list()): real_total += rpc_stat.duration_milliseconds() api_total_mcycles += rpc_stat.api_mcycles() api_total = recording.mcycles_to_msecs(api_total_mcycles) charged_total = recording.mcycles_to_msecs(record.processor_mcycles() + api_total_mcycles) data = {'sys': sys, 'record': record, 'rpcstats_by_count': rpcstats_by_count, 'real_total': real_total, 'api_total': api_total, 'charged_total': charged_total, 'file_url': './file', 'deadlines': [(0,'#77ff77'), (300,'#ECF000'), (1000,'#DB4900')] } self.response.out.write(render('details.html', data))
def render_record(response, record, file_url=None): """ Render an appstats record in detail. This is a minor refactoring of DetailsHandler to support an offline tool for analyzing Appstats data and to allow that tool to call the original Appstats detailed record visualization. Since the offline tool may read Appstats records from other sources (e.g., a downloaded file), we are moving the logic of DetailsHandler related to processing and visualizing individual Appstats records to this function. This function may now be called from outside this file. Args: response: An instance of the webapp response class representing data to be sent in response to a web request. record: A RequestStatProto which contains detailed Appstats recording for an individual request. file_url: Indicates the URL to be used to follow links to files in application source code. A default value of 'None' indicates that links to files in source code will not be shown. """ if record is None: response.set_status(404) response.out.write(render('details.html', {})) return rpcstats_map = {} for rpc_stat in record.individual_stats_list(): key = rpc_stat.service_call_name() count, real, api = rpcstats_map.get(key, (0, 0, 0)) count += 1 real += rpc_stat.duration_milliseconds() api += rpc_stat.api_mcycles() rpcstats_map[key] = (count, real, api) rpcstats_by_count = [ (name, count, real, recording.mcycles_to_msecs(api)) for name, (count, real, api) in rpcstats_map.iteritems()] rpcstats_by_count.sort(key=lambda x: -x[1]) real_total = 0 api_total_mcycles = 0 for i, rpc_stat in enumerate(record.individual_stats_list()): real_total += rpc_stat.duration_milliseconds() api_total_mcycles += rpc_stat.api_mcycles() api_total = recording.mcycles_to_msecs(api_total_mcycles) data = {'sys': sys, 'record': record, 'rpcstats_by_count': rpcstats_by_count, 'real_total': real_total, 'api_total': api_total, 'file_url': file_url, } response.out.write(render('details.html', data))
def render_record(response, record, file_url=None): """ Render an appstats record in detail. This is a minor refactoring of DetailsHandler to support an offline tool for analyzing Appstats data and to allow that tool to call the original Appstats detailed record visualization. Since the offline tool may read Appstats records from other sources (e.g., a downloaded file), we are moving the logic of DetailsHandler related to processing and visualizing individual Appstats records to this function. This function may now be called from outside this file. Args: response: An instance of the webapp response class representing data to be sent in response to a web request. record: A RequestStatProto which contains detailed Appstats recording for an individual request. file_url: Indicates the URL to be used to follow links to files in application source code. A default value of 'None' indicates that links to files in source code will not be shown. """ if record is None: response.set_status(404) response.out.write(render('details.html', {})) return rpcstats_map = {} for rpc_stat in record.individual_stats_list(): key = rpc_stat.service_call_name() count, real, api = rpcstats_map.get(key, (0, 0, 0)) count += 1 real += rpc_stat.duration_milliseconds() api += rpc_stat.api_mcycles() rpcstats_map[key] = (count, real, api) rpcstats_by_count = [(name, count, real, recording.mcycles_to_msecs(api)) for name, (count, real, api) in rpcstats_map.iteritems()] rpcstats_by_count.sort(key=lambda x: -x[1]) real_total = 0 api_total_mcycles = 0 for i, rpc_stat in enumerate(record.individual_stats_list()): real_total += rpc_stat.duration_milliseconds() api_total_mcycles += rpc_stat.api_mcycles() api_total = recording.mcycles_to_msecs(api_total_mcycles) data = { 'sys': sys, 'record': record, 'rpcstats_by_count': rpcstats_by_count, 'real_total': real_total, 'api_total': api_total, 'file_url': file_url, } response.out.write(render('details.html', data))
def get(self): recording.dont_record() time_key = self.request.get('time') timestamp = None record = None if time_key: try: timestamp = int(time_key) * 0.001 except Exception: pass if timestamp: record = recording.load_full_proto(timestamp) if record is None: self.response.set_status(404) self.response.out.write(render('details.html', {})) return rpcstats_map = {} for rpc_stat in record.individual_stats_list(): key = rpc_stat.service_call_name() count, real, api = rpcstats_map.get(key, (0, 0, 0)) count += 1 real += rpc_stat.duration_milliseconds() api += rpc_stat.api_mcycles() rpcstats_map[key] = (count, real, api) rpcstats_by_count = [ (name, count, real, recording.mcycles_to_msecs(api)) for name, (count, real, api) in rpcstats_map.iteritems()] rpcstats_by_count.sort(key=lambda x: -x[1]) real_total = 0 api_total_mcycles = 0 for i, rpc_stat in enumerate(record.individual_stats_list()): real_total += rpc_stat.duration_milliseconds() api_total_mcycles += rpc_stat.api_mcycles() api_total = recording.mcycles_to_msecs(api_total_mcycles) charged_total = recording.mcycles_to_msecs(record.processor_mcycles() + api_total_mcycles) data = {'sys': sys, 'record': record, 'rpcstats_by_count': rpcstats_by_count, 'real_total': real_total, 'api_total': api_total, 'charged_total': charged_total, 'file_url': './file', } self.response.out.write(render('details.html', data))
def get_details_data(record, file_url=None): """ Calculate detailed appstats data for a single request. Args: record: A RequestStatProto which contains detailed Appstats recording for an individual request. file_url: Indicates the URL to be used to follow links to files in application source code. A default value of 'None' indicates that links to files in source code will not be shown. Returns: A dictionary containing detailed appstats data for a single request. """ rpcstats_map = {} for rpc_stat in record.individual_stats_list(): key = rpc_stat.service_call_name() count, real, api, rpc_cost_micropennies, billed_ops = rpcstats_map.get( key, (0, 0, 0, 0, {})) count += 1 real += rpc_stat.duration_milliseconds() api += rpc_stat.api_mcycles() rpc_cost_micropennies += rpc_stat.call_cost_microdollars() _add_billed_ops_to_map(billed_ops, rpc_stat.billed_ops_list()) rpcstats_map[key] = (count, real, api, rpc_cost_micropennies, billed_ops) rpcstats_by_count = [ (name, count, real, recording.mcycles_to_msecs(api), rpc_cost_micropennies, _billed_ops_to_str(six.itervalues(billed_ops))) for name, (count, real, api, rpc_cost_micropennies, billed_ops) in six.iteritems(rpcstats_map) ] rpcstats_by_count.sort(key=lambda x: -x[1]) real_total = 0 api_total_mcycles = 0 for i, rpc_stat in enumerate(record.individual_stats_list()): real_total += rpc_stat.duration_milliseconds() api_total_mcycles += rpc_stat.api_mcycles() api_total = recording.mcycles_to_msecs(api_total_mcycles) return { 'sys': sys, 'record': record, 'rpcstats_by_count': rpcstats_by_count, 'real_total': real_total, 'api_total': api_total, 'file_url': file_url, }
def get_details_data(record, file_url=None): """ Calculate detailed appstats data for a single request. Args: record: A RequestStatProto which contains detailed Appstats recording for an individual request. file_url: Indicates the URL to be used to follow links to files in application source code. A default value of 'None' indicates that links to files in source code will not be shown. Returns: A dictionary containing detailed appstats data for a single request. """ rpcstats_map = {} for rpc_stat in record.individual_stats_list(): key = rpc_stat.service_call_name() count, real, api, rpc_cost_micropennies, billed_ops = rpcstats_map.get( key, (0, 0, 0, 0, {})) count += 1 real += rpc_stat.duration_milliseconds() api += rpc_stat.api_mcycles() rpc_cost_micropennies += rpc_stat.call_cost_microdollars() _add_billed_ops_to_map(billed_ops, rpc_stat.billed_ops_list()) rpcstats_map[key] = (count, real, api, rpc_cost_micropennies, billed_ops) rpcstats_by_count = [ (name, count, real, recording.mcycles_to_msecs(api), rpc_cost_micropennies, _billed_ops_to_str(billed_ops.itervalues())) for name, (count, real, api, rpc_cost_micropennies, billed_ops) in rpcstats_map.iteritems()] rpcstats_by_count.sort(key=lambda x: -x[1]) real_total = 0 api_total_mcycles = 0 for i, rpc_stat in enumerate(record.individual_stats_list()): real_total += rpc_stat.duration_milliseconds() api_total_mcycles += rpc_stat.api_mcycles() api_total = recording.mcycles_to_msecs(api_total_mcycles) return {'sys': sys, 'record': record, 'rpcstats_by_count': rpcstats_by_count, 'real_total': real_total, 'api_total': api_total, 'file_url': file_url, }