From ac623f37359abc3537a50c6b156097a3873e2f42 Mon Sep 17 00:00:00 2001 From: ivanivanishuk Date: Thu, 13 Apr 2023 21:19:58 +0300 Subject: [PATCH 1/5] add --- debug_toolbar/toolbar.py | 1 + 1 file changed, 1 insertion(+) diff --git a/debug_toolbar/toolbar.py b/debug_toolbar/toolbar.py index 40e758107..51ac6634f 100644 --- a/debug_toolbar/toolbar.py +++ b/debug_toolbar/toolbar.py @@ -43,6 +43,7 @@ def __init__(self, request, get_response): self.stats = {} self.server_timing_stats = {} self.store_id = None + self._created.send(request, toolbar=self) # Manage panels From cd1e05438943708cbd8f8eb32e11348956055b4f Mon Sep 17 00:00:00 2001 From: ivanivanishuk Date: Thu, 13 Apr 2023 21:23:58 +0300 Subject: [PATCH 2/5] add redis history --- debug_toolbar/panels/history/panel.py | 5 ++- debug_toolbar/panels/history/views.py | 7 +++- debug_toolbar/settings.py | 1 + debug_toolbar/toolbar.py | 60 ++++++++++++++++++++++++--- debug_toolbar/views.py | 3 +- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/debug_toolbar/panels/history/panel.py b/debug_toolbar/panels/history/panel.py index 8bd0e8f65..4d0f25fdc 100644 --- a/debug_toolbar/panels/history/panel.py +++ b/debug_toolbar/panels/history/panel.py @@ -87,7 +87,10 @@ def content(self): Fetch every store for the toolbar and include it in the template. """ stores = {} - for id, toolbar in reversed(self.toolbar._store.items()): + + list_obj = self.toolbar.fetch_all(self.toolbar) + for id, toolbar in reversed(list_obj.items()): + stores[id] = { "toolbar": toolbar, "form": HistoryStoreForm( diff --git a/debug_toolbar/panels/history/views.py b/debug_toolbar/panels/history/views.py index 3fcbd9b32..165e13d9f 100644 --- a/debug_toolbar/panels/history/views.py +++ b/debug_toolbar/panels/history/views.py @@ -14,7 +14,8 @@ def history_sidebar(request): if form.is_valid(): store_id = form.cleaned_data["store_id"] - toolbar = DebugToolbar.fetch(store_id) + tb = DebugToolbar(request, request) + toolbar = DebugToolbar.fetch(tb, store_id) exclude_history = form.cleaned_data["exclude_history"] context = {} if toolbar is None: @@ -46,7 +47,9 @@ def history_refresh(request): if form.is_valid(): requests = [] # Convert to list to handle mutations happening in parallel - for id, toolbar in list(DebugToolbar._store.items()): + tb = DebugToolbar(request, request) + list_obj = DebugToolbar.fetch_all(tb) + for id, toolbar in list(list_obj.items()): requests.append( { "id": id, diff --git a/debug_toolbar/settings.py b/debug_toolbar/settings.py index bf534a7da..d7cfed2a6 100644 --- a/debug_toolbar/settings.py +++ b/debug_toolbar/settings.py @@ -42,6 +42,7 @@ "SQL_WARNING_THRESHOLD": 500, # milliseconds "OBSERVE_REQUEST_CALLBACK": "debug_toolbar.toolbar.observe_request", "TOOLBAR_LANGUAGE": None, + "CACHE_TIME": 100, } diff --git a/debug_toolbar/toolbar.py b/debug_toolbar/toolbar.py index 51ac6634f..26d5ca8c8 100644 --- a/debug_toolbar/toolbar.py +++ b/debug_toolbar/toolbar.py @@ -43,7 +43,7 @@ def __init__(self, request, get_response): self.stats = {} self.server_timing_stats = {} self.store_id = None - + self.cache_key = 'djangodebug_' self._created.send(request, toolbar=self) # Manage panels @@ -76,6 +76,8 @@ def render_toolbar(self): """ if not self.should_render_panels(): self.store() + if self.tests_run(): + return "" try: context = {"toolbar": self} lang = self.config["TOOLBAR_LANGUAGE"] or get_language() @@ -91,6 +93,9 @@ def render_toolbar(self): else: raise + def tests_run(self): + return self.config.get('TESTS_RUN', False) + def should_render_panels(self): """Determine whether the panels should be rendered during the request @@ -110,13 +115,56 @@ def store(self): if self.store_id: return self.store_id = uuid.uuid4().hex - self._store[self.store_id] = self - for _ in range(self.config["RESULTS_CACHE_SIZE"], len(self._store)): - self._store.popitem(last=False) + + from django.core.cache import cache + + data = { + 'stats': self.stats, + 'server_timing_stats': self.server_timing_stats, + } + + cache.set(f'{self.cache_key}{self.store_id}', data, self.config['CACHE_TIME']) + + # self._store[self.store_id] = self + # for _ in range(self.config["RESULTS_CACHE_SIZE"], len(self._store)): + # self._store.popitem(last=False) + + @classmethod + def fetch(cls, tb, store_id): + from django.core.cache import cache + + data = cache.get(f'{tb.cache_key}{store_id}') + if data: + tb.stats = data.get('stats', {}) + tb.server_timing_stats = data.get('server_timing_stats', {}) + + sql_plugin_data = tb.stats.get('SQLPanel') + if sql_plugin_data: + databases_data = sql_plugin_data.get('databases', [('default', {})])[0][1] + tb._panels.get('SQLPanel')._num_queries = databases_data.get('num_queries') + tb._panels.get('SQLPanel')._sql_time = sql_plugin_data.get('sql_time') + tb.store_id = store_id + return tb + # return cls._store.get(store_id) @classmethod - def fetch(cls, store_id): - return cls._store.get(store_id) + def fetch_all(cls, tb): + from django.core.cache import cache + import copy + + data_dict = {} + key_list = cache.keys(f'{tb.cache_key}*') + for key in key_list: + store_id = key.split('_')[1] + data = cache.get(key) + new_tb = copy.copy(tb) + new_tb.stats = data['stats'] + new_tb.server_timing_stats = data['server_timing_stats'] + new_tb.store_id = store_id + data_dict[store_id] = new_tb + + return data_dict + # Manually implement class-level caching of panel classes and url patterns # because it's more obvious than going through an abstraction. diff --git a/debug_toolbar/views.py b/debug_toolbar/views.py index b93acbeed..448ffb491 100644 --- a/debug_toolbar/views.py +++ b/debug_toolbar/views.py @@ -10,7 +10,8 @@ @render_with_toolbar_language def render_panel(request): """Render the contents of a panel""" - toolbar = DebugToolbar.fetch(request.GET["store_id"]) + tb = DebugToolbar(request, request) + toolbar = DebugToolbar.fetch(tb, request.GET["store_id"]) if toolbar is None: content = _( "Data for this panel isn't available anymore. " From 3b4f278f4c66f1f849d68a125db395b0aaa0484b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 18:26:39 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- debug_toolbar/panels/history/panel.py | 1 - debug_toolbar/toolbar.py | 40 +++++++++++++++------------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/debug_toolbar/panels/history/panel.py b/debug_toolbar/panels/history/panel.py index 4d0f25fdc..3a55c9d51 100644 --- a/debug_toolbar/panels/history/panel.py +++ b/debug_toolbar/panels/history/panel.py @@ -90,7 +90,6 @@ def content(self): list_obj = self.toolbar.fetch_all(self.toolbar) for id, toolbar in reversed(list_obj.items()): - stores[id] = { "toolbar": toolbar, "form": HistoryStoreForm( diff --git a/debug_toolbar/toolbar.py b/debug_toolbar/toolbar.py index 26d5ca8c8..9884e534a 100644 --- a/debug_toolbar/toolbar.py +++ b/debug_toolbar/toolbar.py @@ -43,7 +43,7 @@ def __init__(self, request, get_response): self.stats = {} self.server_timing_stats = {} self.store_id = None - self.cache_key = 'djangodebug_' + self.cache_key = "djangodebug_" self._created.send(request, toolbar=self) # Manage panels @@ -94,7 +94,7 @@ def render_toolbar(self): raise def tests_run(self): - return self.config.get('TESTS_RUN', False) + return self.config.get("TESTS_RUN", False) def should_render_panels(self): """Determine whether the panels should be rendered during the request @@ -119,11 +119,11 @@ def store(self): from django.core.cache import cache data = { - 'stats': self.stats, - 'server_timing_stats': self.server_timing_stats, + "stats": self.stats, + "server_timing_stats": self.server_timing_stats, } - cache.set(f'{self.cache_key}{self.store_id}', data, self.config['CACHE_TIME']) + cache.set(f"{self.cache_key}{self.store_id}", data, self.config["CACHE_TIME"]) # self._store[self.store_id] = self # for _ in range(self.config["RESULTS_CACHE_SIZE"], len(self._store)): @@ -133,39 +133,43 @@ def store(self): def fetch(cls, tb, store_id): from django.core.cache import cache - data = cache.get(f'{tb.cache_key}{store_id}') + data = cache.get(f"{tb.cache_key}{store_id}") if data: - tb.stats = data.get('stats', {}) - tb.server_timing_stats = data.get('server_timing_stats', {}) + tb.stats = data.get("stats", {}) + tb.server_timing_stats = data.get("server_timing_stats", {}) - sql_plugin_data = tb.stats.get('SQLPanel') + sql_plugin_data = tb.stats.get("SQLPanel") if sql_plugin_data: - databases_data = sql_plugin_data.get('databases', [('default', {})])[0][1] - tb._panels.get('SQLPanel')._num_queries = databases_data.get('num_queries') - tb._panels.get('SQLPanel')._sql_time = sql_plugin_data.get('sql_time') + databases_data = sql_plugin_data.get("databases", [("default", {})])[0][ + 1 + ] + tb._panels.get("SQLPanel")._num_queries = databases_data.get( + "num_queries" + ) + tb._panels.get("SQLPanel")._sql_time = sql_plugin_data.get("sql_time") tb.store_id = store_id return tb # return cls._store.get(store_id) @classmethod def fetch_all(cls, tb): - from django.core.cache import cache import copy + from django.core.cache import cache + data_dict = {} - key_list = cache.keys(f'{tb.cache_key}*') + key_list = cache.keys(f"{tb.cache_key}*") for key in key_list: - store_id = key.split('_')[1] + store_id = key.split("_")[1] data = cache.get(key) new_tb = copy.copy(tb) - new_tb.stats = data['stats'] - new_tb.server_timing_stats = data['server_timing_stats'] + new_tb.stats = data["stats"] + new_tb.server_timing_stats = data["server_timing_stats"] new_tb.store_id = store_id data_dict[store_id] = new_tb return data_dict - # Manually implement class-level caching of panel classes and url patterns # because it's more obvious than going through an abstraction. From bb0d39018a073b38b3f88dadd68ef2696b2eab30 Mon Sep 17 00:00:00 2001 From: ivanivanishuk Date: Fri, 14 Apr 2023 11:06:39 +0300 Subject: [PATCH 4/5] add redis history --- debug_toolbar/toolbar.py | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/debug_toolbar/toolbar.py b/debug_toolbar/toolbar.py index 9884e534a..47ba093c4 100644 --- a/debug_toolbar/toolbar.py +++ b/debug_toolbar/toolbar.py @@ -119,37 +119,28 @@ def store(self): from django.core.cache import cache data = { - "stats": self.stats, - "server_timing_stats": self.server_timing_stats, + 'stats': self.stats, + 'server_timing_stats': self.server_timing_stats, } - cache.set(f"{self.cache_key}{self.store_id}", data, self.config["CACHE_TIME"]) - - # self._store[self.store_id] = self - # for _ in range(self.config["RESULTS_CACHE_SIZE"], len(self._store)): - # self._store.popitem(last=False) + cache.set(f'{self.cache_key}{self.store_id}', data, self.config['CACHE_TIME']) @classmethod def fetch(cls, tb, store_id): from django.core.cache import cache - data = cache.get(f"{tb.cache_key}{store_id}") + data = cache.get(f'{tb.cache_key}{store_id}') if data: - tb.stats = data.get("stats", {}) - tb.server_timing_stats = data.get("server_timing_stats", {}) + tb.stats = data.get('stats', {}) + tb.server_timing_stats = data.get('server_timing_stats', {}) - sql_plugin_data = tb.stats.get("SQLPanel") + sql_plugin_data = tb.stats.get('SQLPanel') if sql_plugin_data: - databases_data = sql_plugin_data.get("databases", [("default", {})])[0][ - 1 - ] - tb._panels.get("SQLPanel")._num_queries = databases_data.get( - "num_queries" - ) - tb._panels.get("SQLPanel")._sql_time = sql_plugin_data.get("sql_time") + databases_data = sql_plugin_data.get('databases', [('default', {})])[0][1] + tb._panels.get('SQLPanel')._num_queries = databases_data.get('num_queries') + tb._panels.get('SQLPanel')._sql_time = sql_plugin_data.get('sql_time') tb.store_id = store_id return tb - # return cls._store.get(store_id) @classmethod def fetch_all(cls, tb): @@ -158,13 +149,13 @@ def fetch_all(cls, tb): from django.core.cache import cache data_dict = {} - key_list = cache.keys(f"{tb.cache_key}*") + key_list = cache.keys(f'{tb.cache_key}*') for key in key_list: - store_id = key.split("_")[1] + store_id = key.split('_')[1] data = cache.get(key) new_tb = copy.copy(tb) - new_tb.stats = data["stats"] - new_tb.server_timing_stats = data["server_timing_stats"] + new_tb.stats = data['stats'] + new_tb.server_timing_stats = data['server_timing_stats'] new_tb.store_id = store_id data_dict[store_id] = new_tb From 29a26b3546936cfb0b092ab108de7e2e3dee843d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:06:56 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- debug_toolbar/toolbar.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/debug_toolbar/toolbar.py b/debug_toolbar/toolbar.py index 47ba093c4..ceaa8a8be 100644 --- a/debug_toolbar/toolbar.py +++ b/debug_toolbar/toolbar.py @@ -119,26 +119,30 @@ def store(self): from django.core.cache import cache data = { - 'stats': self.stats, - 'server_timing_stats': self.server_timing_stats, + "stats": self.stats, + "server_timing_stats": self.server_timing_stats, } - cache.set(f'{self.cache_key}{self.store_id}', data, self.config['CACHE_TIME']) + cache.set(f"{self.cache_key}{self.store_id}", data, self.config["CACHE_TIME"]) @classmethod def fetch(cls, tb, store_id): from django.core.cache import cache - data = cache.get(f'{tb.cache_key}{store_id}') + data = cache.get(f"{tb.cache_key}{store_id}") if data: - tb.stats = data.get('stats', {}) - tb.server_timing_stats = data.get('server_timing_stats', {}) + tb.stats = data.get("stats", {}) + tb.server_timing_stats = data.get("server_timing_stats", {}) - sql_plugin_data = tb.stats.get('SQLPanel') + sql_plugin_data = tb.stats.get("SQLPanel") if sql_plugin_data: - databases_data = sql_plugin_data.get('databases', [('default', {})])[0][1] - tb._panels.get('SQLPanel')._num_queries = databases_data.get('num_queries') - tb._panels.get('SQLPanel')._sql_time = sql_plugin_data.get('sql_time') + databases_data = sql_plugin_data.get("databases", [("default", {})])[0][ + 1 + ] + tb._panels.get("SQLPanel")._num_queries = databases_data.get( + "num_queries" + ) + tb._panels.get("SQLPanel")._sql_time = sql_plugin_data.get("sql_time") tb.store_id = store_id return tb @@ -149,13 +153,13 @@ def fetch_all(cls, tb): from django.core.cache import cache data_dict = {} - key_list = cache.keys(f'{tb.cache_key}*') + key_list = cache.keys(f"{tb.cache_key}*") for key in key_list: - store_id = key.split('_')[1] + store_id = key.split("_")[1] data = cache.get(key) new_tb = copy.copy(tb) - new_tb.stats = data['stats'] - new_tb.server_timing_stats = data['server_timing_stats'] + new_tb.stats = data["stats"] + new_tb.server_timing_stats = data["server_timing_stats"] new_tb.store_id = store_id data_dict[store_id] = new_tb