def _store_api_info(self, sender, time_taken=0, method=None, url=None, response=None, args=None, kwargs=None, **kw): time_taken *= 1000 self.total_time += time_taken # use debug-toolbar utilities to get & render stacktrace # skip last two entries, which are in eulfedora.debug_panel if dt_settings.get_config().get('ENABLE_STACKTRACES', False): stacktrace = tidy_stacktrace(reversed(get_stack()))[:-2] else: stacktrace = [] try: method_name = method.__name__.upper() except AttributeError: method_name = method self.api_calls.append({ 'time': time_taken, 'method': method_name, 'url': url, 'args': args, 'kwargs': kwargs, 'response': response, 'stack': render_stacktrace(stacktrace) })
def _store_call_info(self, sender, name=None, time_taken=0, return_value=None, args=None, kwargs=None, trace=None, template_info=None, backend=None, **kw): if name == "get": if return_value is None: self.misses += 1 else: self.hits += 1 elif name == "get_many": for key, value in return_value.items(): if value is None: self.misses += 1 else: self.hits += 1 time_taken *= 1000 self.total_time += time_taken self.counts[name] += 1 self.calls.append({ "time": time_taken, "name": name, "args": args, "kwargs": kwargs, "trace": render_stacktrace(trace), "template_info": template_info, "backend": backend, })
def _store_call_info(self, sender, name=None, time_taken=0, return_value=None, args=None, kwargs=None, trace=None, template_info=None, backend=None, **kw): if name == 'get': if return_value is None: self.misses += 1 else: self.hits += 1 elif name == 'get_many': for key, value in return_value.items(): if value is None: self.misses += 1 else: self.hits += 1 time_taken *= 1000 self.total_time += time_taken self.counts[name] += 1 self.calls.append({ 'time': time_taken, 'name': name, 'args': args, 'kwargs': kwargs, 'trace': render_stacktrace(trace), 'template_info': template_info, 'backend': backend })
def _store_call_info(self, sender, name=None, time_taken=0, return_value=None, args=None, kwargs=None, trace=None, template_info=None, backend=None, **kw): if name == 'get': if return_value is None: self.misses += 1 else: self.hits += 1 elif name == 'get_many': for key, value in return_value.items(): if value is None: self.misses += 1 else: self.hits += 1 self.total_time += time_taken * 1000 self.counts[name] += 1 self.calls.append({ 'time': time_taken, 'name': name, 'args': args, 'kwargs': kwargs, 'trace': render_stacktrace(trace), 'template_info': template_info, 'backend': backend })
def _store_api_info(self, sender, time_taken=0, method=None, url=None, response=None, args=None, kwargs=None, **kw): time_taken *= 1000 self.total_time += time_taken # use debug-toolbar utilities to get & render stacktrace # skip last two entries, which are in eulfedora.debug_panel if dt_settings.get_config().get("ENABLE_STACKTRACES", False): stacktrace = tidy_stacktrace(reversed(get_stack()))[:-2] else: stacktrace = [] try: method_name = method.__name__.upper() except AttributeError: method_name = method self.api_calls.append( { "time": time_taken, "method": method_name, "url": url, "args": args, "kwargs": kwargs, "response": response, "stack": render_stacktrace(stacktrace), } )
def record_call(self, name, keys): start = time.time() yield call_time = time.time() - start # trim the stack to remove our wrapper methods stack = get_stack()[3:] trace = render_stacktrace(tidy_stacktrace(reversed(stack))) self.calls.append(CallInfo(name, keys, call_time, trace)) self.total_time += call_time
def test_importlib_path_issue_1612(self): trace = [("/server/app.py", 1, "foo", ["code line 1", "code line 2"], { "foo": "bar" })] result = render_stacktrace(trace) self.assertIn('<span class="djdt-path">/server/</span>', result) self.assertIn('<span class="djdt-file">app.py</span> in', result) trace = [( "<frozen importlib._bootstrap>", 1, "foo", ["code line 1", "code line 2"], { "foo": "bar" }, )] result = render_stacktrace(trace) self.assertIn('<span class="djdt-path"></span>', result) self.assertIn( '<span class="djdt-file"><frozen importlib._bootstrap></span> in', result, )
def generate_stats(self, request, response): records = collector.get_collection() self.total_time = 0 self.nb_duplicates = 0 hashs = set() for record in records: self.total_time += record.duration if record.hash in hashs: self.nb_duplicates += 1 hashs.add(record.hash) record.stacktrace = render_stacktrace(record.stacktrace) self.nb_queries = len(records) collector.clear_collection() self.record_stats({"records": records})
def _store_call_info( self, sender, name=None, time_taken=0, return_value=None, args=None, kwargs=None, trace=None, template_info=None, backend=None, **kw ): if name == "get": if return_value is None: self.misses += 1 else: self.hits += 1 elif name == "get_many": for key, value in return_value.items(): if value is None: self.misses += 1 else: self.hits += 1 time_taken *= 1000 self.total_time += time_taken self.counts[name] += 1 self.calls.append( { "time": time_taken, "name": name, "args": args, "kwargs": kwargs, "trace": render_stacktrace(trace), "template_info": template_info, "backend": backend, } )
def _store_call_info( self, name, time_taken, return_value, args, kwargs, trace, template_info, backend, ): if name == "get" or name == "get_or_set": if return_value is None: self.misses += 1 else: self.hits += 1 elif name == "get_many": if "keys" in kwargs: keys = kwargs["keys"] else: keys = args[0] self.hits += len(return_value) self.misses += len(keys) - len(return_value) time_taken *= 1000 self.total_time += time_taken self.counts[name] += 1 self.calls.append({ "time": time_taken, "name": name, "args": args, "kwargs": kwargs, "trace": render_stacktrace(trace), "template_info": template_info, "backend": backend, })
def generate_stats(self, request, response): colors = contrasting_color_generator() trace_colors = defaultdict(lambda: next(colors)) query_similar = defaultdict(lambda: defaultdict(int)) query_duplicates = defaultdict(lambda: defaultdict(int)) # The keys used to determine similar and duplicate queries. def similar_key(query): return query["raw_sql"] def duplicate_key(query): raw_params = ( () if query["raw_params"] is None else tuple(query["raw_params"]) ) # saferepr() avoids problems because of unhashable types # (e.g. lists) when used as dictionary keys. # https://github.com/jazzband/django-debug-toolbar/issues/1091 return (query["raw_sql"], saferepr(raw_params)) if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.values()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n // 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db["rgb_color"] = rgb trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: query_similar[alias][similar_key(query)] += 1 query_duplicates[alias][duplicate_key(query)] += 1 trans_id = query.get("trans_id") last_trans_id = trans_ids.get(alias) if trans_id != last_trans_id: if last_trans_id: self._queries[(i - 1)][1]["ends_trans"] = True trans_ids[alias] = trans_id if trans_id: query["starts_trans"] = True if trans_id: query["in_trans"] = True query["alias"] = alias if "iso_level" in query: query["iso_level"] = get_isolation_level_display( query["vendor"], query["iso_level"] ) if "trans_status" in query: query["trans_status"] = get_transaction_status_display( query["vendor"], query["trans_status"] ) query["form"] = SignedDataForm( auto_id=None, initial=SQLSelectForm(initial=copy(query)).initial ) if query["sql"]: query["sql"] = reformat_sql(query["sql"], with_toggle=True) query["rgb_color"] = self._databases[alias]["rgb_color"] try: query["width_ratio"] = (query["duration"] / self._sql_time) * 100 except ZeroDivisionError: query["width_ratio"] = 0 query["start_offset"] = width_ratio_tally query["end_offset"] = query["width_ratio"] + query["start_offset"] width_ratio_tally += query["width_ratio"] query["stacktrace"] = render_stacktrace(query["stacktrace"]) i += 1 query["trace_color"] = trace_colors[query["stacktrace"]] if trans_id: self._queries[(i - 1)][1]["ends_trans"] = True # Queries are similar / duplicates only if there's as least 2 of them. # Also, to hide queries, we need to give all the duplicate groups an id query_colors = contrasting_color_generator() query_similar_colors = { alias: { query: (similar_count, next(query_colors)) for query, similar_count in queries.items() if similar_count >= 2 } for alias, queries in query_similar.items() } query_duplicates_colors = { alias: { query: (duplicate_count, next(query_colors)) for query, duplicate_count in queries.items() if duplicate_count >= 2 } for alias, queries in query_duplicates.items() } for alias, query in self._queries: try: (query["similar_count"], query["similar_color"]) = query_similar_colors[ alias ][similar_key(query)] ( query["duplicate_count"], query["duplicate_color"], ) = query_duplicates_colors[alias][duplicate_key(query)] except KeyError: pass for alias, alias_info in self._databases.items(): try: alias_info["similar_count"] = sum( e[0] for e in query_similar_colors[alias].values() ) alias_info["duplicate_count"] = sum( e[0] for e in query_duplicates_colors[alias].values() ) except KeyError: pass self.record_stats( { "databases": sorted( self._databases.items(), key=lambda x: -x[1]["time_spent"] ), "queries": [q for a, q in self._queries], "sql_time": self._sql_time, } )
def process_response(self, request, response): colors = contrasting_color_generator() trace_colors = defaultdict(lambda: next(colors)) query_duplicates = defaultdict(lambda: defaultdict(int)) if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.values()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n / 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db['rgb_color'] = rgb trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: query_duplicates[alias][query["raw_sql"]] += 1 trans_id = query.get('trans_id') last_trans_id = trans_ids.get(alias) if trans_id != last_trans_id: if last_trans_id: self._queries[(i - 1)][1]['ends_trans'] = True trans_ids[alias] = trans_id if trans_id: query['starts_trans'] = True if trans_id: query['in_trans'] = True query['alias'] = alias if 'iso_level' in query: query['iso_level'] = get_isolation_level_display( query['vendor'], query['iso_level'] ) if 'trans_status' in query: query['trans_status'] = get_transaction_status_display( query['vendor'], query['trans_status'] ) query['form'] = SQLSelectForm(auto_id=None, initial=copy(query)) if query['sql']: query['sql'] = reformat_sql(query['sql']) query['rgb_color'] = self._databases[alias]['rgb_color'] try: query['width_ratio'] = (query['duration'] / self._sql_time) * 100 query['width_ratio_relative' ] = (100.0 * query['width_ratio'] / (100.0 - width_ratio_tally)) except ZeroDivisionError: query['width_ratio'] = 0 query['width_ratio_relative'] = 0 query['start_offset'] = width_ratio_tally query['end_offset'] = query['width_ratio'] + query['start_offset'] width_ratio_tally += query['width_ratio'] query['stacktrace'] = render_stacktrace(query['stacktrace']) i += 1 query['trace_color'] = trace_colors[query['stacktrace']] if trans_id: self._queries[(i - 1)][1]['ends_trans'] = True # Queries are duplicates only if there's as least 2 of them. # Also, to hide queries, we need to give all the duplicate groups an id query_duplicates = dict( ( alias, dict( (query, duplicate_count) for query, duplicate_count in queries.items() if duplicate_count >= 2 ) ) for alias, queries in query_duplicates.items() ) for alias, query in self._queries: try: duplicates_count = query_duplicates[alias][query["raw_sql"]] query["duplicate_count"] = duplicates_count except KeyError: pass for alias, alias_info in self._databases.items(): try: alias_info["duplicate_count"] = sum(e for e in query_duplicates[alias].values()) except KeyError: pass self.record_stats( { 'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']), 'queries': [q for a, q in self._queries], 'sql_time': self._sql_time, } )
def generate_stats(self, request, response): colors = contrasting_color_generator() trace_colors = defaultdict(lambda: next(colors)) similar_query_groups = defaultdict(list) duplicate_query_groups = defaultdict(list) if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.values()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n // 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db["rgb_color"] = rgb # the last query recorded for each DB alias last_by_alias = {} for query in self._queries: alias = query["alias"] similar_query_groups[(alias, _similar_query_key(query))].append(query) duplicate_query_groups[( alias, _duplicate_query_key(query))].append(query) trans_id = query.get("trans_id") prev_query = last_by_alias.get(alias, {}) prev_trans_id = prev_query.get("trans_id") # If two consecutive queries for a given DB alias have different # transaction ID values, a transaction started, finished, or both, so # annotate the queries as appropriate. if trans_id != prev_trans_id: if prev_trans_id is not None: prev_query["ends_trans"] = True if trans_id is not None: query["starts_trans"] = True if trans_id is not None: query["in_trans"] = True if "iso_level" in query: query["iso_level"] = get_isolation_level_display( query["vendor"], query["iso_level"]) if "trans_status" in query: query["trans_status"] = get_transaction_status_display( query["vendor"], query["trans_status"]) query["form"] = SignedDataForm( auto_id=None, initial=SQLSelectForm(initial=copy(query)).initial) if query["sql"]: query["sql"] = reformat_sql(query["sql"], with_toggle=True) query["rgb_color"] = self._databases[alias]["rgb_color"] try: query["width_ratio"] = (query["duration"] / self._sql_time) * 100 except ZeroDivisionError: query["width_ratio"] = 0 query["start_offset"] = width_ratio_tally query["end_offset"] = query["width_ratio"] + query[ "start_offset"] width_ratio_tally += query["width_ratio"] query["stacktrace"] = render_stacktrace(query["stacktrace"]) query["trace_color"] = trace_colors[query["stacktrace"]] last_by_alias[alias] = query # Close out any transactions that were in progress, since there is no # explicit way to know when a transaction finishes. for final_query in last_by_alias.values(): if final_query.get("trans_id") is not None: final_query["ends_trans"] = True group_colors = contrasting_color_generator() _process_query_groups(similar_query_groups, self._databases, group_colors, "similar") _process_query_groups(duplicate_query_groups, self._databases, group_colors, "duplicate") self.record_stats({ "databases": sorted(self._databases.items(), key=lambda x: -x[1]["time_spent"]), "queries": self._queries, "sql_time": self._sql_time, })
def process_response(self, request, response): if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.itervalues()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n / 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db['rgb_color'] = rgb trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: trans_id = query.get('trans_id') last_trans_id = trans_ids.get(alias) if trans_id != last_trans_id: if last_trans_id: self._queries[(i - 1)][1]['ends_trans'] = True trans_ids[alias] = trans_id if trans_id: query['starts_trans'] = True if trans_id: query['in_trans'] = True query['alias'] = alias if 'iso_level' in query: query['iso_level'] = get_isolation_level_display(query['engine'], query['iso_level']) if 'trans_status' in query: query['trans_status'] = get_transaction_status_display(query['engine'], query['trans_status']) query['sql'] = reformat_sql(query['sql']) query['rgb_color'] = self._databases[alias]['rgb_color'] try: query['width_ratio'] = (query['duration'] / self._sql_time) * 100 query['width_ratio_relative'] = 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally) except ZeroDivisionError: query['width_ratio'] = 0 query['width_ratio_relative'] = 0 query['start_offset'] = width_ratio_tally query['end_offset'] = query['width_ratio'] + query['start_offset'] width_ratio_tally += query['width_ratio'] query['stacktrace'] = render_stacktrace(query['stacktrace']) i += 1 if trans_id: self._queries[(i - 1)][1]['ends_trans'] = True self.record_stats({ 'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']), 'queries': [q for a, q in self._queries], 'sql_time': self._sql_time, })
def stacktrace(self): return render_stacktrace(self.raw_stacktrace)
def generate_stats(self, request, response): colors = contrasting_color_generator() trace_colors = defaultdict(lambda: next(colors)) query_similar = defaultdict(lambda: defaultdict(int)) query_duplicates = defaultdict(lambda: defaultdict(int)) # The keys used to determine similar and duplicate queries. def similar_key(query): return query["raw_sql"] def duplicate_key(query): raw_params = ( () if query["raw_params"] is None else tuple(query["raw_params"]) ) # saferepr() avoids problems because of unhashable types # (e.g. lists) when used as dictionary keys. # https://github.com/jazzband/django-debug-toolbar/issues/1091 return (query["raw_sql"], saferepr(raw_params)) if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.values()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n // 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db["rgb_color"] = rgb trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: query_similar[alias][similar_key(query)] += 1 query_duplicates[alias][duplicate_key(query)] += 1 trans_id = query.get("trans_id") last_trans_id = trans_ids.get(alias) if trans_id != last_trans_id: if last_trans_id: self._queries[(i - 1)][1]["ends_trans"] = True trans_ids[alias] = trans_id if trans_id: query["starts_trans"] = True if trans_id: query["in_trans"] = True query["alias"] = alias if "iso_level" in query: query["iso_level"] = get_isolation_level_display( query["vendor"], query["iso_level"] ) if "trans_status" in query: query["trans_status"] = get_transaction_status_display( query["vendor"], query["trans_status"] ) query["form"] = SQLSelectForm(auto_id=None, initial=copy(query)) if query["sql"]: query["sql"] = reformat_sql(query["sql"], with_toggle=True) query["rgb_color"] = self._databases[alias]["rgb_color"] try: query["width_ratio"] = (query["duration"] / self._sql_time) * 100 query["width_ratio_relative"] = ( 100.0 * query["width_ratio"] / (100.0 - width_ratio_tally) ) except ZeroDivisionError: query["width_ratio"] = 0 query["width_ratio_relative"] = 0 query["start_offset"] = width_ratio_tally query["end_offset"] = query["width_ratio"] + query["start_offset"] width_ratio_tally += query["width_ratio"] query["stacktrace"] = render_stacktrace(query["stacktrace"]) i += 1 query["trace_color"] = trace_colors[query["stacktrace"]] if trans_id: self._queries[(i - 1)][1]["ends_trans"] = True # Queries are similar / duplicates only if there's as least 2 of them. # Also, to hide queries, we need to give all the duplicate groups an id query_colors = contrasting_color_generator() query_similar_colors = { alias: { query: (similar_count, next(query_colors)) for query, similar_count in queries.items() if similar_count >= 2 } for alias, queries in query_similar.items() } query_duplicates_colors = { alias: { query: (duplicate_count, next(query_colors)) for query, duplicate_count in queries.items() if duplicate_count >= 2 } for alias, queries in query_duplicates.items() } for alias, query in self._queries: try: (query["similar_count"], query["similar_color"]) = query_similar_colors[ alias ][similar_key(query)] ( query["duplicate_count"], query["duplicate_color"], ) = query_duplicates_colors[alias][duplicate_key(query)] except KeyError: pass for alias, alias_info in self._databases.items(): try: alias_info["similar_count"] = sum( e[0] for e in query_similar_colors[alias].values() ) alias_info["duplicate_count"] = sum( e[0] for e in query_duplicates_colors[alias].values() ) except KeyError: pass self.record_stats( { "databases": sorted( self._databases.items(), key=lambda x: -x[1]["time_spent"] ), "queries": [q for a, q in self._queries], "sql_time": self._sql_time, } )
def process_response(self, request, response): if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.itervalues()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n / 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db["rgb_color"] = rgb trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: trans_id = query.get("trans_id") last_trans_id = trans_ids.get(alias) if trans_id != last_trans_id: if last_trans_id: self._queries[(i - 1)][1]["ends_trans"] = True trans_ids[alias] = trans_id if trans_id: query["starts_trans"] = True if trans_id: query["in_trans"] = True query["alias"] = alias if "iso_level" in query: query["iso_level"] = get_isolation_level_display(query["engine"], query["iso_level"]) if "trans_status" in query: query["trans_status"] = get_transaction_status_display(query["engine"], query["trans_status"]) query["form"] = SQLSelectForm(auto_id=None, initial=copy(query)) if query["sql"]: query["sql"] = reformat_sql(query["sql"]) query["rgb_color"] = self._databases[alias]["rgb_color"] try: query["width_ratio"] = (query["duration"] / self._sql_time) * 100 query["width_ratio_relative"] = 100.0 * query["width_ratio"] / (100.0 - width_ratio_tally) except ZeroDivisionError: query["width_ratio"] = 0 query["width_ratio_relative"] = 0 query["start_offset"] = width_ratio_tally query["end_offset"] = query["width_ratio"] + query["start_offset"] width_ratio_tally += query["width_ratio"] query["stacktrace"] = render_stacktrace(query["stacktrace"]) i += 1 if trans_id: self._queries[(i - 1)][1]["ends_trans"] = True self.record_stats( { "databases": sorted(self._databases.items(), key=lambda x: -x[1]["time_spent"]), "queries": [q for a, q in self._queries], "sql_time": self._sql_time, } )
def process_response(self, request, response): colors = contrasting_color_generator() trace_colors = defaultdict(lambda: next(colors)) query_duplicates = defaultdict(lambda: defaultdict(int)) if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.values()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n / 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db['rgb_color'] = rgb trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: query_duplicates[alias][query["raw_sql"]] += 1 trans_id = query.get('trans_id') last_trans_id = trans_ids.get(alias) if trans_id != last_trans_id: if last_trans_id: self._queries[(i - 1)][1]['ends_trans'] = True trans_ids[alias] = trans_id if trans_id: query['starts_trans'] = True if trans_id: query['in_trans'] = True query['alias'] = alias if 'iso_level' in query: query['iso_level'] = get_isolation_level_display(query['vendor'], query['iso_level']) if 'trans_status' in query: query['trans_status'] = get_transaction_status_display(query['vendor'], query['trans_status']) query['form'] = SQLSelectForm(auto_id=None, initial=copy(query)) if query['sql']: query['sql'] = reformat_sql(query['sql']) query['rgb_color'] = self._databases[alias]['rgb_color'] try: query['width_ratio'] = (query['duration'] / self._sql_time) * 100 query['width_ratio_relative'] = ( 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally)) except ZeroDivisionError: query['width_ratio'] = 0 query['width_ratio_relative'] = 0 query['start_offset'] = width_ratio_tally query['end_offset'] = query['width_ratio'] + query['start_offset'] width_ratio_tally += query['width_ratio'] query['stacktrace'] = render_stacktrace(query['stacktrace']) i += 1 query['trace_color'] = trace_colors[query['stacktrace']] if trans_id: self._queries[(i - 1)][1]['ends_trans'] = True # Queries are duplicates only if there's as least 2 of them. # Also, to hide queries, we need to give all the duplicate groups an id query_duplicates = dict( (alias, dict( (query, duplicate_count) for query, duplicate_count in queries.items() if duplicate_count >= 2 )) for alias, queries in query_duplicates.items() ) for alias, query in self._queries: try: duplicates_count = query_duplicates[alias][query["raw_sql"]] query["duplicate_count"] = duplicates_count except KeyError: pass for alias, alias_info in self._databases.items(): try: alias_info["duplicate_count"] = sum(e for e in query_duplicates[alias].values()) except KeyError: pass self.record_stats({ 'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']), 'queries': [q for a, q in self._queries], 'sql_time': self._sql_time, })
def process_response(self, request, response): if self._queries: width_ratio_tally = 0 factor = int(256.0 / (len(self._databases) * 2.5)) for n, db in enumerate(self._databases.itervalues()): rgb = [0, 0, 0] color = n % 3 rgb[color] = 256 - n / 3 * factor nn = color # XXX: pretty sure this is horrible after so many aliases while rgb[color] < factor: nc = min(256 - rgb[color], 256) rgb[color] += nc nn += 1 if nn > 2: nn = 0 rgb[nn] = nc db['rgb_color'] = rgb trans_ids = {} trans_id = None i = 0 for alias, query in self._queries: trans_id = query.get('trans_id') last_trans_id = trans_ids.get(alias) if trans_id != last_trans_id: if last_trans_id: self._queries[(i - 1)][1]['ends_trans'] = True trans_ids[alias] = trans_id if trans_id: query['starts_trans'] = True if trans_id: query['in_trans'] = True query['alias'] = alias if 'iso_level' in query: query['iso_level'] = get_isolation_level_display(query['engine'], query['iso_level']) if 'trans_status' in query: query['trans_status'] = get_transaction_status_display(query['engine'], query['trans_status']) if query['sql']: query['sql'] = reformat_sql(query['sql']) query['rgb_color'] = self._databases[alias]['rgb_color'] try: query['width_ratio'] = (query['duration'] / self._sql_time) * 100 query['width_ratio_relative'] = 100.0 * query['width_ratio'] / (100.0 - width_ratio_tally) except ZeroDivisionError: query['width_ratio'] = 0 query['width_ratio_relative'] = 0 query['start_offset'] = width_ratio_tally query['end_offset'] = query['width_ratio'] + query['start_offset'] width_ratio_tally += query['width_ratio'] query['stacktrace'] = render_stacktrace(query['stacktrace']) i += 1 if trans_id: self._queries[(i - 1)][1]['ends_trans'] = True self.record_stats({ 'databases': sorted(self._databases.items(), key=lambda x: -x[1]['time_spent']), 'queries': [q for a, q in self._queries], 'sql_time': self._sql_time, })