[debug-toolbar/rql] add RQL panel
authorLaurent Peuch <cortex@worlddomination.be>
Wed, 31 Jul 2019 04:16:20 +0200
changeset 12760 d5ae5abd0876
parent 12759 ec834074ea25
child 12761 10b8352b0208
[debug-toolbar/rql] add RQL panel Closes #17219673
cubicweb/pyramid/debug_toolbar_templates/rql.dbtmako
cubicweb/pyramid/debugtoolbar_panels.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cubicweb/pyramid/debug_toolbar_templates/rql.dbtmako	Wed Jul 31 04:16:20 2019 +0200
@@ -0,0 +1,119 @@
+<table id="rql-table" class="table table-striped table-condensed">
+    <thead>
+        <tr>
+            <th class="table-col-1">#</th>
+            <th class="table-col-2">Time (ms)</th>
+            <th class="table-col-3">RQL</th>
+            <th class="table-col-5">Result</th>
+            <th class="table-col-7">Description</th>
+            <th class="table-col-8">Stack</th>
+        </tr>
+    </thead>
+    <tbody>
+        % for i, query in enumerate(rql_queries):
+            <tr>
+                <th class="table-col-1">${1 + i}</th>
+                <td class="table-col-2">${'%.2f' % query["time"]}</td>
+                <td class="table-col-3">${highlight(query["rql"], "RQL") | n}<br>${highlight(query["args"], "python3") | n}</td>
+                % if len(str(query["result"])) > 50:
+                <td id="result-${i}" class="table-col-5">
+                    <span id="result-${i}-short">
+                    ${highlight(str(query["result"])[:50], "python3") | n}...
+                    <a title="display more" href="javascript:show_result(${i})"><span class="badge progress-bar-default">+</span></a>
+                    </span>
+                    <span id="result-${i}-long" style="display: none">
+                    ${highlight(query["result"], "python3") | n}
+                    <a title="display less" href="javascript:hide_result(${i})"><span class="badge progress-bar-warning">←</span></a>
+                    </span>
+                </td>
+                % else:
+                <td class="table-col-5">${highlight(query["result"], "python3") | n}</td>
+                % endif
+                <td class="table-col-7">${highlight(query["description"], "python3") | n}</td>
+                <td class="table-col-8">
+                    <a class="btn btn-default" id="show-stack-${i}" href="javascript:show_stack(${i})">show stack</a>
+                    <a class="btn btn-default" id="hide-stack-${i}" href="javascript:hide_stack(${i})" style="display: none">hide stack</a>
+                </td>
+            </tr>
+            <tr style="display: none" id="stack-${i}">
+                <td colspan="7">
+                    <pre>${highlight(query["callstack"], "py3tb", linenos="inline") | n}</pre>
+                </td>
+            </tr>
+            <tr style="display: none"></tr> <!-- css hack because of previous hidden tr for -stripped -->
+        % endfor
+    </tbody>
+</table>
+
+<script type="text/javascript" charset="utf-8">
+    function show_result(result_id) {
+        element = document.querySelector("#result-" + result_id + "-long");
+        element.style.setProperty("display", "inline");
+
+        element = document.querySelector("#result-" + result_id + "-short");
+        element.style.setProperty("display", "none");
+    }
+
+    function hide_result(result_id) {
+        element = document.querySelector("#result-" + result_id + "-short");
+        element.style.setProperty("display", "inline");
+
+        element = document.querySelector("#result-" + result_id + "-long");
+        element.style.setProperty("display", "none");
+    }
+
+    function show_stack(stack_id) {
+        element = document.querySelector("#stack-" + stack_id);
+        element.style.setProperty("display", "table-row");
+
+        element = document.querySelector("#show-stack-" + stack_id);
+        element.style.setProperty("display", "none");
+
+        element = document.querySelector("#hide-stack-" + stack_id);
+        element.style.setProperty("display", "inline");
+    }
+
+    function hide_stack(stack_id) {
+        element = document.querySelector("#stack-" + stack_id);
+        element.style.setProperty("display", "none");
+
+        element = document.querySelector("#show-stack-" + stack_id);
+        element.style.setProperty("display", "inline");
+
+        element = document.querySelector("#hide-stack-" + stack_id);
+        element.style.setProperty("display", "none");
+    }
+</script>
+
+<style>
+#rql-table {
+    table-layout: fixed;
+}
+
+#rql-table .table-col-1 {
+    text-align: right;
+    width: 30px;
+}
+
+#rql-table .table-col-2 {
+    white-space: nowrap;
+    width: 73px;
+    text-align: center;
+}
+
+#rql-table .table-col-8 {
+    padding: 8px;
+    width: 110px;
+    text-align: center;
+}
+
+${generate_css() | n}
+
+.highlight > pre {
+    word-break: unset;
+    border: none;
+    margin: 0;
+    padding: 0;
+    background-color: unset;
+}
+</style>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cubicweb/pyramid/debugtoolbar_panels.py	Wed Jul 31 04:16:20 2019 +0200
@@ -0,0 +1,56 @@
+# copyright 2019 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+
+from pyramid_debugtoolbar.panels import DebugPanel
+from cubicweb.debug import subscribe_to_debug_channel, unsubscribe_to_debug_channel
+from cubicweb.misc.source_highlight import highlight_html, generate_css
+
+
+class RQLDebugPanel(DebugPanel):
+    """
+    CubicWeb RQL debug panel
+    """
+    name = 'RQL'
+    title = 'RQL queries'
+    nav_title = 'RQL'
+    nav_subtitle_style = 'progress-bar-info'
+
+    has_content = True
+    template = 'cubicweb.pyramid:debug_toolbar_templates/rql.dbtmako'
+
+    def __init__(self, request):
+        self.data = {
+            'rql_queries': [],
+            'highlight': highlight_html,
+            'generate_css': generate_css,
+        }
+        subscribe_to_debug_channel("rql", self.collect_rql_queries)
+
+    @property
+    def nav_subtitle(self):
+        return '%d' % len(self.data['rql_queries'])
+
+    def collect_rql_queries(self, rql_query):
+        self.data["rql_queries"].append(rql_query)
+
+    def process_response(self, response):
+        unsubscribe_to_debug_channel("rql", self.collect_rql_queries)
+
+
+def includeme(config):
+    config.add_debugtoolbar_panel(RQLDebugPanel)