diff options
| author | Dave McLain | 2011-04-22 01:24:57 -0500 |
|---|---|---|
| committer | Dave McLain | 2011-04-22 01:30:19 -0500 |
| commit | 3929bf2066e108695546e2dd8db14579a8710126 (patch) | |
| tree | b556973e93cd569a9b184731db1b30fc975b4b73 | |
| parent | dfee3848866f2193576d2bdd44f0c8bcd10c63a4 (diff) | |
| download | django-debug-toolbar-3929bf2066e108695546e2dd8db14579a8710126.tar.bz2 | |
first pass at a profiler panel
| -rw-r--r-- | debug_toolbar/media/debug_toolbar/css/toolbar.min.css | 2 | ||||
| -rw-r--r-- | debug_toolbar/media/debug_toolbar/js/toolbar.js | 18 | ||||
| -rw-r--r-- | debug_toolbar/media/debug_toolbar/js/toolbar.min.js | 2 | ||||
| -rw-r--r-- | debug_toolbar/panels/profiling.py | 169 | ||||
| -rw-r--r-- | debug_toolbar/templates/debug_toolbar/panels/profiling.html | 23 |
5 files changed, 179 insertions, 35 deletions
diff --git a/debug_toolbar/media/debug_toolbar/css/toolbar.min.css b/debug_toolbar/media/debug_toolbar/css/toolbar.min.css index 0913bfb..38b00e8 100644 --- a/debug_toolbar/media/debug_toolbar/css/toolbar.min.css +++ b/debug_toolbar/media/debug_toolbar/css/toolbar.min.css @@ -1 +1 @@ -#djDebug{color:#000;background:#FFF;}#djDebug,#djDebug div,#djDebug span,#djDebug applet,#djDebug object,#djDebug iframe,#djDebug h1,#djDebug h2,#djDebug h3,#djDebug h4,#djDebug h5,#djDebug h6,#djDebug p,#djDebug blockquote,#djDebug pre,#djDebug a,#djDebug abbr,#djDebug acronym,#djDebug address,#djDebug big,#djDebug cite,#djDebug code,#djDebug del,#djDebug dfn,#djDebug em,#djDebug font,#djDebug img,#djDebug ins,#djDebug kbd,#djDebug q,#djDebug s,#djDebug samp,#djDebug small,#djDebug strike,#djDebug strong,#djDebug sub,#djDebug sup,#djDebug tt,#djDebug var,#djDebug b,#djDebug u,#djDebug i,#djDebug center,#djDebug dl,#djDebug dt,#djDebug dd,#djDebug ol,#djDebug ul,#djDebug li,#djDebug fieldset,#djDebug form,#djDebug label,#djDebug legend,#djDebug table,#djDebug caption,#djDebug tbody,#djDebug tfoot,#djDebug thead,#djDebug tr,#djDebug th,#djDebug td{margin:0;padding:0;border:0;outline:0;font-size:12px;line-height:1.5em;color:#000;vertical-align:baseline;background:transparent;font-family:sans-serif;text-align:left;}#djDebug #djDebugToolbar{background:#111;width:200px;z-index:100000000;position:fixed;top:0;bottom:0;right:0;opacity:.9;}#djDebug #djDebugToolbar small{color:#999;}#djDebug #djDebugToolbar ul{margin:0;padding:0;list-style:none;}#djDebug #djDebugToolbar li{border-bottom:1px solid #222;color:#fff;display:block;font-weight:bold;float:none;margin:0;padding:0;position:relative;width:auto;}#djDebug #djDebugToolbar li>a,#djDebug #djDebugToolbar li>div.contentless{font-weight:normal;font-style:normal;text-decoration:none;display:block;font-size:16px;padding:10px 10px 5px 25px;color:#fff;}#djDebug #djDebugToolbar li a:hover{color:#111;background-color:#ffc;}#djDebug #djDebugToolbar li.active{background-image:url(../img/indicator.png);background-repeat:no-repeat;background-position:left center;background-color:#333;padding-left:10px;}#djDebug #djDebugToolbar li.active a:hover{color:#b36a60;background-color:transparent;}#djDebug #djDebugToolbar li small{font-size:12px;color:#999;font-style:normal;text-decoration:none;font-variant:small-caps;}#djDebug #djDebugToolbarHandle{position:fixed;background:#fff;border:1px solid #111;top:30px;right:0;z-index:100000000;opacity:.75;}#djDebug a#djShowToolBarButton{display:block;height:75px;width:30px;border-right:none;border-bottom:4px solid #fff;border-top:4px solid #fff;border-left:4px solid #fff;color:#fff;font-size:10px;font-weight:bold;text-decoration:none;text-align:center;text-indent:-999999px;background:#000 url(../img/djdt_vertical.png) no-repeat left center;opacity:.5;}#djDebug a#djShowToolBarButton:hover{background-color:#111;padding-right:6px;border-top-color:#FFE761;border-left-color:#FFE761;border-bottom-color:#FFE761;opacity:1.0;}#djDebug code{display:block;font-family:Consolas,Monaco,"Bitstream Vera Sans Mono","Lucida Console",monospace;white-space:pre;overflow:auto;}#djDebug tr.djDebugOdd{background-color:#f5f5f5;}#djDebug .panelContent{display:none;position:fixed;margin:0;top:0;right:200px;bottom:0;left:0;background-color:#eee;color:#666;z-index:100000000;}#djDebug .panelContent>div{border-bottom:1px solid #ddd;}#djDebug .djDebugPanelTitle{position:absolute;background-color:#ffc;color:#666;padding-left:20px;top:0;right:0;left:0;height:50px;}#djDebug .djDebugPanelTitle code{display:inline;font-size:inherit;}#djDebug .djDebugPanelContent{position:absolute;top:50px;right:0;bottom:0;left:0;height:auto;padding:0 0 0 20px;}#djDebug .djDebugPanelContent .scroll{height:100%;overflow:auto;display:block;padding:0 10px 0 0;}#djDebug h3{font-size:24px;font-weight:normal;line-height:50px;}#djDebug h4{font-size:20px;font-weight:bold;margin-top:.8em;}#djDebug .panelContent table{border:1px solid #ccc;border-collapse:collapse;width:100%;background-color:#fff;display:block;margin-top:.8em;overflow:auto;}#djDebug .panelContent tbody td,#djDebug .panelContent tbody th{vertical-align:top;padding:2px 3px;}#djDebug .panelContent thead th{padding:1px 6px 1px 3px;text-align:left;font-weight:bold;font-size:14px;}#djDebug .panelContent tbody th{width:12em;text-align:right;color:#666;padding-right:.5em;}#djDebug .djTemplateHideContextDiv{background-color:#fff;}#djDebug .panelContent .djDebugClose{text-indent:-9999999px;display:block;position:absolute;top:4px;right:15px;height:40px;width:40px;background:url(../img/close.png) no-repeat center center;}#djDebug .panelContent .djDebugClose:hover{background-image:url(../img/close_hover.png);}#djDebug .panelContent .djDebugClose.djDebugBack{background-image:url(../img/back.png);}#djDebug .panelContent .djDebugClose.djDebugBack:hover{background-image:url(../img/back_hover.png);}#djDebug .panelContent dt,#djDebug .panelContent dd{display:block;}#djDebug .panelContent dt{margin-top:.75em;}#djDebug .panelContent dd{margin-left:10px;}#djDebug a.toggleTemplate{padding:4px;background-color:#bbb;-moz-border-radius:3px;-webkit-border-radius:3px;}#djDebug a.toggleTemplate:hover{padding:4px;background-color:#444;color:#ffe761;-moz-border-radius:3px;-webkit-border-radius:3px;}#djDebug a.djTemplateShowContext,#djDebug a.djTemplateShowContext span.toggleArrow{color:#999;}#djDebug a.djTemplateShowContext:hover,#djDebug a.djTemplateShowContext:hover span.toggleArrow{color:#000;cursor:pointer;}#djDebug .djDebugSqlWrap{position:relative;}#djDebug .djDebugSql{z-index:100000002;}#djDebug .djSQLHideStacktraceDiv tbody th{text-align:left;}#djDebug .djSqlExplain td{white-space:pre;}#djDebug span.djDebugLineChart{background-color:#777;height:3px;position:absolute;bottom:0;top:0;left:0;display:block;z-index:1000000001;}#djDebug span.djDebugLineChartWarning{background-color:#900;}#djDebug .highlight{color:#000;}#djDebug .highlight .err{color:#000;}#djDebug .highlight .g{color:#000;}#djDebug .highlight .k{color:#000;font-weight:bold;}#djDebug .highlight .o{color:#000;}#djDebug .highlight .n{color:#000;}#djDebug .highlight .mi{color:#000;font-weight:bold;}#djDebug .highlight .l{color:#000;}#djDebug .highlight .x{color:#000;}#djDebug .highlight .p{color:#000;}#djDebug .highlight .m{color:#000;font-weight:bold;}#djDebug .highlight .s{color:#333;}#djDebug .highlight .w{color:#888;}#djDebug .highlight .il{color:#000;font-weight:bold;}#djDebug .highlight .na{color:#333;}#djDebug .highlight .nt{color:#000;font-weight:bold;}#djDebug .highlight .nv{color:#333;}#djDebug .highlight .s2{color:#333;}#djDebug .highlight .cp{color:#333;}@media print{#djDebug{display:none;}}
\ No newline at end of file +#djDebug{color:#000;background:#FFF}#djDebug,#djDebug div,#djDebug span,#djDebug applet,#djDebug object,#djDebug iframe,#djDebug h1,#djDebug h2,#djDebug h3,#djDebug h4,#djDebug h5,#djDebug h6,#djDebug p,#djDebug blockquote,#djDebug pre,#djDebug a,#djDebug abbr,#djDebug acronym,#djDebug address,#djDebug big,#djDebug cite,#djDebug code,#djDebug del,#djDebug dfn,#djDebug em,#djDebug font,#djDebug img,#djDebug ins,#djDebug kbd,#djDebug q,#djDebug s,#djDebug samp,#djDebug small,#djDebug strike,#djDebug strong,#djDebug sub,#djDebug sup,#djDebug tt,#djDebug var,#djDebug b,#djDebug u,#djDebug i,#djDebug center,#djDebug dl,#djDebug dt,#djDebug dd,#djDebug ol,#djDebug ul,#djDebug li,#djDebug fieldset,#djDebug form,#djDebug label,#djDebug legend,#djDebug table,#djDebug caption,#djDebug tbody,#djDebug tfoot,#djDebug thead,#djDebug tr,#djDebug th,#djDebug td{margin:0;padding:0;border:0;outline:0;font-size:12px;line-height:1.5em;color:#000;vertical-align:baseline;background:transparent;font-family:sans-serif;text-align:left}#djDebug #djDebugToolbar{background:#111;width:200px;z-index:100000000;position:fixed;top:0;bottom:0;right:0;opacity:.9}#djDebug #djDebugToolbar small{color:#999}#djDebug #djDebugToolbar ul{margin:0;padding:0;list-style:none}#djDebug #djDebugToolbar li{border-bottom:1px solid #222;color:#fff;display:block;font-weight:bold;float:none;margin:0;padding:0;position:relative;width:auto}#djDebug #djDebugToolbar li>a,#djDebug #djDebugToolbar li>div.contentless{font-weight:normal;font-style:normal;text-decoration:none;display:block;font-size:16px;padding:10px 10px 5px 25px;color:#fff}#djDebug #djDebugToolbar li a:hover{color:#111;background-color:#ffc}#djDebug #djDebugToolbar li.active{background-image:url(../img/indicator.png);background-repeat:no-repeat;background-position:left center;background-color:#333;padding-left:10px}#djDebug #djDebugToolbar li.active a:hover{color:#b36a60;background-color:transparent}#djDebug #djDebugToolbar li small{font-size:12px;color:#999;font-style:normal;text-decoration:none;font-variant:small-caps}#djDebug #djDebugToolbarHandle{position:fixed;background:#fff;border:1px solid #111;top:30px;right:0;z-index:100000000;opacity:.75}#djDebug a#djShowToolBarButton{display:block;height:75px;width:30px;border-right:0;border-bottom:4px solid #fff;border-top:4px solid #fff;border-left:4px solid #fff;color:#fff;font-size:10px;font-weight:bold;text-decoration:none;text-align:center;text-indent:-999999px;background:#000 url(../img/djdt_vertical.png) no-repeat left center;opacity:.5}#djDebug a#djShowToolBarButton:hover{background-color:#111;padding-right:6px;border-top-color:#ffe761;border-left-color:#ffe761;border-bottom-color:#ffe761;opacity:1.0}#djDebug code{display:block;font-family:Consolas,Monaco,"Bitstream Vera Sans Mono","Lucida Console",monospace;white-space:pre;overflow:auto}#djDebug tr.djDebugOdd{background-color:#f5f5f5}#djDebug .panelContent{display:none;position:fixed;margin:0;top:0;right:200px;bottom:0;left:0;background-color:#eee;color:#666;z-index:100000000}#djDebug .panelContent>div{border-bottom:1px solid #ddd}#djDebug .djDebugPanelTitle{position:absolute;background-color:#ffc;color:#666;padding-left:20px;top:0;right:0;left:0;height:50px}#djDebug .djDebugPanelTitle code{display:inline;font-size:inherit}#djDebug .djDebugPanelContent{position:absolute;top:50px;right:0;bottom:0;left:0;height:auto;padding:0 0 0 20px}#djDebug .djDebugPanelContent .scroll{height:100%;overflow:auto;display:block;padding:0 10px 0 0}#djDebug h3{font-size:24px;font-weight:normal;line-height:50px}#djDebug h4{font-size:20px;font-weight:bold;margin-top:.8em}#djDebug .panelContent table{border:1px solid #ccc;border-collapse:collapse;width:100%;background-color:#fff;display:block;margin-top:.8em;overflow:auto}#djDebug .panelContent tbody td,#djDebug .panelContent tbody th{vertical-align:top;padding:2px 3px}#djDebug .panelContent thead th{padding:1px 6px 1px 3px;text-align:left;font-weight:bold;font-size:14px}#djDebug .panelContent tbody th{width:12em;text-align:right;color:#666;padding-right:.5em}#djDebug .djTemplateHideContextDiv{background-color:#fff}#djDebug .panelContent .djDebugClose{text-indent:-9999999px;display:block;position:absolute;top:4px;right:15px;height:40px;width:40px;background:url(../img/close.png) no-repeat center center}#djDebug .panelContent .djDebugClose:hover{background-image:url(../img/close_hover.png)}#djDebug .panelContent .djDebugClose.djDebugBack{background-image:url(../img/back.png)}#djDebug .panelContent .djDebugClose.djDebugBack:hover{background-image:url(../img/back_hover.png)}#djDebug .panelContent dt,#djDebug .panelContent dd{display:block}#djDebug .panelContent dt{margin-top:.75em}#djDebug .panelContent dd{margin-left:10px}#djDebug a.toggleTemplate{padding:4px;background-color:#bbb;-moz-border-radius:3px;-webkit-border-radius:3px}#djDebug a.toggleTemplate:hover{padding:4px;background-color:#444;color:#ffe761;-moz-border-radius:3px;-webkit-border-radius:3px}#djDebug a.djTemplateShowContext,#djDebug a.djTemplateShowContext span.toggleArrow{color:#999}#djDebug a.djTemplateShowContext:hover,#djDebug a.djTemplateShowContext:hover span.toggleArrow{color:#000;cursor:pointer}#djDebug .djDebugSqlWrap{position:relative}#djDebug .djDebugSql{z-index:100000002}#djDebug .djSQLHideStacktraceDiv tbody th{text-align:left}#djDebug .djSqlExplain td{white-space:pre}#djDebug span.djDebugLineChart{background-color:#777;height:3px;position:absolute;bottom:0;top:0;left:0;display:block;z-index:1000000001}#djDebug span.djDebugLineChartWarning{background-color:#900}#djDebug .highlight{color:#000}#djDebug .highlight .err{color:#000}#djDebug .highlight .g{color:#000}#djDebug .highlight .k{color:#000;font-weight:bold}#djDebug .highlight .o{color:#000}#djDebug .highlight .n{color:#000}#djDebug .highlight .mi{color:#000;font-weight:bold}#djDebug .highlight .l{color:#000}#djDebug .highlight .x{color:#000}#djDebug .highlight .p{color:#000}#djDebug .highlight .m{color:#000;font-weight:bold}#djDebug .highlight .s{color:#333}#djDebug .highlight .w{color:#888}#djDebug .highlight .il{color:#000;font-weight:bold}#djDebug .highlight .na{color:#333}#djDebug .highlight .nt{color:#000;font-weight:bold}#djDebug .highlight .nv{color:#333}#djDebug .highlight .s2{color:#333}#djDebug .highlight .cp{color:#333}@media print{#djDebug{display:none}}
\ No newline at end of file diff --git a/debug_toolbar/media/debug_toolbar/js/toolbar.js b/debug_toolbar/media/debug_toolbar/js/toolbar.js index a43d834..ca34b64 100644 --- a/debug_toolbar/media/debug_toolbar/js/toolbar.js +++ b/debug_toolbar/media/debug_toolbar/js/toolbar.js @@ -66,6 +66,24 @@ djdt.toggle_content($('.djSQLHideStacktraceDiv', $(this).parents('tr'))); return false; }); + function getSubcalls(row) { + id = row.attr('id'); + return $('.djDebugProfileRow[id^="'+id+'_"]'); + } + function getDirectSubcalls(row) { + subcalls = getSubcalls(row); + depth = parseInt(row.attr('depth')) + 1; + return subcalls.filter('[depth='+depth+']'); + } + $('.djDebugProfileRow .djDebugProfileToggle').click(function(){ + row = $(this).closest('.djDebugProfileRow') + subcalls = getSubcalls(row); + if (subcalls.css('display')=='none') { + getDirectSubcalls(row).show(); + } else { + subcalls.hide(); + } + }); $('#djHideToolBarButton').click(function() { djdt.hide_toolbar(true); return false; diff --git a/debug_toolbar/media/debug_toolbar/js/toolbar.min.js b/debug_toolbar/media/debug_toolbar/js/toolbar.min.js index 73c01b8..4467de2 100644 --- a/debug_toolbar/media/debug_toolbar/js/toolbar.min.js +++ b/debug_toolbar/media/debug_toolbar/js/toolbar.min.js @@ -1 +1 @@ -(function(g,a,b,i){var f,h;var e=false;if(!(f=g.jQuery)||b>f.fn.jquery||i(f)){var c=a.createElement("script");c.type="text/javascript";c.src=DEBUG_TOOLBAR_MEDIA_URL+"js/jquery.js";c.onload=c.onreadystatechange=function(){if(!e&&(!(h=this.readyState)||h=="loaded"||h=="complete")){i((f=g.jQuery).noConflict(1),e=true);f(c).remove()}};a.documentElement.childNodes[0].appendChild(c)}})(window,document,"1.3",function(b,a){b.cookie=function(f,n,q){if(typeof n!="undefined"){q=q||{};if(n===null){n="";q.expires=-1}var j="";if(q.expires&&(typeof q.expires=="number"||q.expires.toUTCString)){var k;if(typeof q.expires=="number"){k=new Date();k.setTime(k.getTime()+(q.expires*24*60*60*1000))}else{k=q.expires}j="; expires="+k.toUTCString()}var p=q.path?"; path="+(q.path):"";var l=q.domain?"; domain="+(q.domain):"";var e=q.secure?"; secure":"";document.cookie=[f,"=",encodeURIComponent(n),j,p,l,e].join("")}else{var h=null;if(document.cookie&&document.cookie!=""){var o=document.cookie.split(";");for(var m=0;m<o.length;m++){var g=b.trim(o[m]);if(g.substring(0,f.length+1)==(f+"=")){h=decodeURIComponent(g.substring(f.length+1));break}}}return h}};b("head").append('<link rel="stylesheet" href="'+DEBUG_TOOLBAR_MEDIA_URL+'css/toolbar.min.css" type="text/css" />');var d="djdt";var c={init:function(){b("#djDebug").show();var e=null;b("#djDebugPanelList li a").click(function(){if(!this.className){return false}e=b("#djDebug #"+this.className);if(e.is(":visible")){b(document).trigger("close.djDebug");b(this).parent().removeClass("active")}else{b(".panelContent").hide();e.show();b("#djDebugToolbar li").removeClass("active");b(this).parent().addClass("active")}return false});b("#djDebug a.djDebugClose").click(function(){b(document).trigger("close.djDebug");b("#djDebugToolbar li").removeClass("active");return false});b("#djDebug a.remoteCall").click(function(){b("#djDebugWindow").load(this.href,function(g,f,i){if(f=="error"){var h='<div class="djDebugPanelTitle"><a class="djDebugClose djDebugBack" href="">Back</a><h3>'+i.status+": "+i.statusText+"</h3></div>";b("#djDebugWindow").html(h)}b("#djDebugWindow a.djDebugBack").click(function(){b(this).parent().parent().hide();return false})});b("#djDebugWindow").show();return false});b("#djDebugTemplatePanel a.djTemplateShowContext").click(function(){c.toggle_arrow(b(this).children(".toggleArrow"));c.toggle_content(b(this).parent().next());return false});b("#djDebugSQLPanel a.djSQLShowStacktrace").click(function(){c.toggle_content(b(".djSQLHideStacktraceDiv",b(this).parents("tr")));return false});b("#djHideToolBarButton").click(function(){c.hide_toolbar(true);return false});b("#djShowToolBarButton").click(function(){c.show_toolbar();return false});b(document).bind("close.djDebug",function(){if(b("#djDebugWindow").is(":visible")){b("#djDebugWindow").hide();return}if(b(".panelContent").is(":visible")){b(".panelContent").hide();return}if(b("#djDebugToolbar").is(":visible")){c.hide_toolbar(true);return}});if(b.cookie(d)){c.hide_toolbar(false)}else{c.show_toolbar(false)}},toggle_content:function(e){if(e.is(":visible")){e.hide()}else{e.show()}},close:function(){b(document).trigger("close.djDebug");return false},hide_toolbar:function(e){b("#djDebugWindow").hide();b(".panelContent").hide();b("#djDebugToolbar li").removeClass("active");b("#djDebugToolbar").hide("fast");b("#djDebugToolbarHandle").show();b(document).unbind("keydown.djDebug");if(e){b.cookie(d,"hide",{path:"/",expires:10})}},show_toolbar:function(e){b(document).bind("keydown.djDebug",function(f){if(f.keyCode==27){c.close()}});b("#djDebugToolbarHandle").hide();if(e){b("#djDebugToolbar").show("fast")}else{b("#djDebugToolbar").show()}b.cookie(d,null,{path:"/",expires:-1})},toggle_arrow:function(f){var e=String.fromCharCode(9654);var g=String.fromCharCode(9660);f.html(f.html()==e?g:e)}};b(document).ready(function(){c.init()})});
\ No newline at end of file +(function(g,a,b,i){var f,h;var e=false;if(!(f=g.jQuery)||b>f.fn.jquery||i(f)){var c=a.createElement("script");c.type="text/javascript";c.src=DEBUG_TOOLBAR_MEDIA_URL+"js/jquery.js";c.onload=c.onreadystatechange=function(){if(!e&&(!(h=this.readyState)||h=="loaded"||h=="complete")){i((f=g.jQuery).noConflict(1),e=true);f(c).remove()}};a.documentElement.childNodes[0].appendChild(c)}})(window,document,"1.3",function(b,a){b.cookie=function(f,n,q){if(typeof n!="undefined"){q=q||{};if(n===null){n="";q.expires=-1}var j="";if(q.expires&&(typeof q.expires=="number"||q.expires.toUTCString)){var k;if(typeof q.expires=="number"){k=new Date();k.setTime(k.getTime()+(q.expires*24*60*60*1000))}else{k=q.expires}j="; expires="+k.toUTCString()}var p=q.path?"; path="+(q.path):"";var l=q.domain?"; domain="+(q.domain):"";var e=q.secure?"; secure":"";document.cookie=[f,"=",encodeURIComponent(n),j,p,l,e].join("")}else{var h=null;if(document.cookie&&document.cookie!=""){var o=document.cookie.split(";");for(var m=0;m<o.length;m++){var g=b.trim(o[m]);if(g.substring(0,f.length+1)==(f+"=")){h=decodeURIComponent(g.substring(f.length+1));break}}}return h}};b("head").append('<link rel="stylesheet" href="'+DEBUG_TOOLBAR_MEDIA_URL+'css/toolbar.min.css" type="text/css" />');var d="djdt";var c={init:function(){b("#djDebug").show();var g=null;b("#djDebugPanelList li a").click(function(){if(!this.className){return false}g=b("#djDebug #"+this.className);if(g.is(":visible")){b(document).trigger("close.djDebug");b(this).parent().removeClass("active")}else{b(".panelContent").hide();g.show();b("#djDebugToolbar li").removeClass("active");b(this).parent().addClass("active")}return false});b("#djDebug a.djDebugClose").click(function(){b(document).trigger("close.djDebug");b("#djDebugToolbar li").removeClass("active");return false});b("#djDebug a.remoteCall").click(function(){b("#djDebugWindow").load(this.href,function(i,h,k){if(h=="error"){var j='<div class="djDebugPanelTitle"><a class="djDebugClose djDebugBack" href="">Back</a><h3>'+k.status+": "+k.statusText+"</h3></div>";b("#djDebugWindow").html(j)}b("#djDebugWindow a.djDebugBack").click(function(){b(this).parent().parent().hide();return false})});b("#djDebugWindow").show();return false});b("#djDebugTemplatePanel a.djTemplateShowContext").click(function(){c.toggle_arrow(b(this).children(".toggleArrow"));c.toggle_content(b(this).parent().next());return false});b("#djDebugSQLPanel a.djSQLShowStacktrace").click(function(){c.toggle_content(b(".djSQLHideStacktraceDiv",b(this).parents("tr")));return false});function e(h){id=h.attr("id");return b('.djDebugProfileRow[id^="'+id+'_"]')}function f(h){subcalls=e(h);depth=parseInt(h.attr("depth"))+1;return subcalls.filter("[depth="+depth+"]")}b(".djDebugProfileRow .djDebugProfileToggle").click(function(){row=b(this).closest(".djDebugProfileRow");subcalls=e(row);if(subcalls.css("display")=="none"){f(row).show()}else{subcalls.hide()}});b("#djHideToolBarButton").click(function(){c.hide_toolbar(true);return false});b("#djShowToolBarButton").click(function(){c.show_toolbar();return false});b(document).bind("close.djDebug",function(){if(b("#djDebugWindow").is(":visible")){b("#djDebugWindow").hide();return}if(b(".panelContent").is(":visible")){b(".panelContent").hide();return}if(b("#djDebugToolbar").is(":visible")){c.hide_toolbar(true);return}});if(b.cookie(d)){c.hide_toolbar(false)}else{c.show_toolbar(false)}},toggle_content:function(e){if(e.is(":visible")){e.hide()}else{e.show()}},close:function(){b(document).trigger("close.djDebug");return false},hide_toolbar:function(e){b("#djDebugWindow").hide();b(".panelContent").hide();b("#djDebugToolbar li").removeClass("active");b("#djDebugToolbar").hide("fast");b("#djDebugToolbarHandle").show();b(document).unbind("keydown.djDebug");if(e){b.cookie(d,"hide",{path:"/",expires:10})}},show_toolbar:function(e){b(document).bind("keydown.djDebug",function(f){if(f.keyCode==27){c.close()}});b("#djDebugToolbarHandle").hide();if(e){b("#djDebugToolbar").show("fast")}else{b("#djDebugToolbar").show()}b.cookie(d,null,{path:"/",expires:-1})},toggle_arrow:function(f){var e=String.fromCharCode(9654);var g=String.fromCharCode(9660);f.html(f.html()==e?g:e)}};b(document).ready(function(){c.init()})});
\ No newline at end of file diff --git a/debug_toolbar/panels/profiling.py b/debug_toolbar/panels/profiling.py index 302f444..af7137f 100644 --- a/debug_toolbar/panels/profiling.py +++ b/debug_toolbar/panels/profiling.py @@ -1,15 +1,120 @@ -import sys - import django from django.conf import settings from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ - +from django.utils.safestring import mark_safe import debug_toolbar from debug_toolbar.panels import DebugPanel +import sys +import cProfile +from pstats import Stats, f8, func_std_string +from cStringIO import StringIO +from django.conf import settings +from colorsys import hsv_to_rgb + +class DjangoDebugToolbarStats(Stats): + __root = None + + def get_root_func(self): + if self.__root is None: + for func, (cc, nc, tt, ct, callers) in self.stats.iteritems(): + if len(callers) == 0: + self.__root = func + break + return self.__root + + def print_call_tree_node(self, function, depth, max_depth, cum_filter=0.1): + self.print_line(function, depth=depth) + if depth < max_depth: + for called in self.all_callees[function].keys(): + if self.stats[called][3] >= cum_filter: + self.print_call_tree_node(called, depth+1, max_depth, cum_filter=cum_filter) -class VersionDebugPanel(DebugPanel): +class FunctionCall(object): + def __init__(self, statobj, func, depth=0, stats=None, css_id='djDebugProfileCall_0', hsv=(0,0.5,1)): + self.statobj = statobj + self.func = func + if stats: + self.stats = stats + else: + self.stats = statobj.stats[func][:4] + self.depth = depth + self.id = css_id + self.hsv=hsv + + def parent_classes(self): + return self.parent_classes + + def background(self): + print self.hsv + r,g,b = hsv_to_rgb(*self.hsv) + return 'rgb(%f%%,%f%%,%f%%)' %(r*100, g*100, b*100) + + def func_std_string(self): # match what old profile produced + func_name = self.func + if func_name[:2] == ('~', 0): + # special case for built-in functions + name = func_name[2] + if name.startswith('<') and name.endswith('>'): + return '{%s}' % name[1:-1] + else: + return name + else: + file_name, line_num, method = self.func + if file_name.startswith(settings.PROJECT_ROOT): + file_name='PROJECT' + file_name[len(settings.PROJECT_ROOT):] + idx = file_name.find('/site-packages/') + if idx > -1: + file_name=file_name[idx+14:] + return "%s:%d(%s)" % (file_name, line_num, method) + + def subfuncs(self): + i=0 + h,s,v = self.hsv + count = len(self.statobj.all_callees[self.func]) + for func, stats in self.statobj.all_callees[self.func].iteritems(): + i += 1 + h1 = h + (i/count)/(self.depth+1) + if stats[3] == 0: + s1 = 0 + else: + s1 = s*(stats[3]/self.stats[3]) + yield FunctionCall(self.statobj, + func, + self.depth+1, + stats=stats, + css_id=self.id + '_' + str(i), + hsv=(h1,s1,1)) + + def as_row(self): + cc, nc, tt, ct = self.stats + if nc != cc: + c = str(nc) + '/' + str(cc) + else: + c = str(nc) + + if nc != 0: + ttdivnc = tt/nc + else: + ttdivnc = 0 + + if cc == 0: + ctdivcc = 0 + else: + ctdivcc = ct/cc + indent = 5*self.depth + funcstr = self.func_std_string() + out = """ + <td>%(c)s</td> + <td>%(tt)8.3f<br/>(%(ttdivnc)8.3f)</td> + <td>%(ct)8.3f<br/>(%(ctdivcc)8.3f)</td> + <td style='padding-left:%(indent)ipx'>%(funcstr)s</td> + """ % locals() + return mark_safe(out) + + +class ProfilingDebugPanel(DebugPanel): """ Panel that displays the Django version. """ @@ -17,43 +122,41 @@ class VersionDebugPanel(DebugPanel): has_content = True def nav_title(self): - return _('Versions') - - def nav_subtitle(self): - return 'Django %s' % django.get_version() + return _('Profiling') def url(self): return '' def title(self): - return _('Versions') + return _('Profiling') - def content(self): - versions = {} - for app in settings.INSTALLED_APPS + ['django']: - name = app.split('.')[-1].replace('_', ' ').capitalize() - __import__(app) - app = sys.modules[app] - if hasattr(app, 'get_version'): - get_version = app.get_version - if callable(get_version): - version = get_version() - else: - version = get_version - elif hasattr(app, 'VERSION'): - version = app.VERSION - elif hasattr(app, '__version__'): - version = app.__version__ - else: - continue - if isinstance(version, (list, tuple)): - version = '.'.join(str(o) for o in version) - versions[name] = version + def process_view(self, request, view_func, view_args, view_kwargs): + self.profiler = cProfile.Profile() + args = (request,) + view_args + return self.profiler.runcall(view_func, *args, **view_kwargs) + + def process_response(self, request, response): + self.profiler.create_stats() + self.stats = DjangoDebugToolbarStats(self.profiler) + return response + def add_node(self, func_list, func, max_depth, cum_time=0.1): + func_list.append(func) + if func.depth < max_depth: + for subfunc in func.subfuncs(): + if subfunc.stats[3] >= cum_time: + self.add_node(func_list, subfunc, max_depth, cum_time=cum_time) + + def content(self): + + self.stats.calc_callees() + root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0) + + func_list = [] + self.add_node(func_list, root, 10, root.stats[3]/8) context = self.context.copy() context.update({ - 'versions': versions, - 'paths': sys.path, + 'func_list': func_list, }) - return render_to_string('debug_toolbar/panels/versions.html', context) + return render_to_string('debug_toolbar/panels/profiling.html', context) diff --git a/debug_toolbar/templates/debug_toolbar/panels/profiling.html b/debug_toolbar/templates/debug_toolbar/panels/profiling.html new file mode 100644 index 0000000..95af495 --- /dev/null +++ b/debug_toolbar/templates/debug_toolbar/panels/profiling.html @@ -0,0 +1,23 @@ +{% load i18n %} + + + +<table width="100%"> + <thead> + <tr> + <th>{% trans "ncalls" %}</th> + <th>{% trans "tottime" %}<br/>({% trans "percall" %})</th> + <th>{% trans "cumtime" %}<br/>({% trans "percall" %})</th> + <th>{% trans "filename:lineno(function)" %}</th> + <th>{% trans "toggle" %}</th> + </tr> + </thead> + <tbody> + {% for call in func_list %} + <tr id="{{ call.id }}" class="djDebugProfileRow" style="background:{{ call.background }}" depth="{{ call.depth }}"> + {{ call.as_row }} + <td><a class="djDebugProfileToggle">Toggle Subcalls</a></td> + </tr> + {% endfor %} + </tbody> +</table> |
