Example #1
0
    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)
        })
Example #2
0
    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
        })
Example #4
0
 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
     })
Example #5
0
    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">&lt;frozen importlib._bootstrap&gt;</span> in',
            result,
        )
Example #8
0
    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})
Example #9
0
    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,
            }
        )
Example #10
0
    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,
            }
        )
Example #12
0
    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,
            }
        )
Example #13
0
    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,
        })
Example #14
0
    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,
        })
Example #15
0
 def stacktrace(self):
     return render_stacktrace(self.raw_stacktrace)
Example #16
0
    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,
            }
        )
Example #17
0
    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,
            }
        )
Example #18
0
    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,
        })
Example #19
0
    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,
        })