rails_profiler 0.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/app/assets/javascripts/rails_profiler.js +13 -0
- data/app/assets/javascripts/rails_profiler/loader.js.erb +37 -0
- data/app/assets/javascripts/rails_profiler_widget.js +11 -0
- data/app/assets/javascripts/reqwest.min.js +6 -0
- data/app/assets/stylesheets/rails_profiler.css +39 -0
- data/app/controllers/rails_profiler/application_controller.rb +4 -0
- data/app/controllers/rails_profiler/widget_controller.rb +9 -0
- data/app/helpers/rails_profiler/application_helper.rb +4 -0
- data/app/views/layouts/rails_profiler/application.html.erb +14 -0
- data/app/views/rails_profiler/widget/index.html.erb +12 -0
- data/config/routes.rb +4 -0
- data/lib/rails_profiler.rb +4 -0
- data/lib/rails_profiler/engine.rb +18 -0
- data/lib/rails_profiler/middleware.rb +39 -0
- data/lib/rails_profiler/profiler.rb +49 -0
- data/lib/rails_profiler/version.rb +3 -0
- data/lib/tasks/rails_profiler_tasks.rake +4 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 86ea72530c346bfc4fcddd43cd7f9ef0e229c242
|
4
|
+
data.tar.gz: 6d9629eb902e2cabdc93e4ede66a035fae7a9a61
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cd8ddebf758e499d212a3795be68e71fbcde49611669100b32b649b195fead3b8a0cb03fdee48ee24a9fb650676c6f218c149520aa23f9418acd68dd78cf112b
|
7
|
+
data.tar.gz: ce88f2f03a81044dfd3e4167a2308edaf50319a9bfa7e81701a6eb8842857a2397155aacc1d738619e832646bdafacfd1b0718448ab4d1aca106d246710b093c
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 Emil Soman
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree ./rails_profiler
|
@@ -0,0 +1,37 @@
|
|
1
|
+
function loadWidget() {
|
2
|
+
var iframe = document.createElement('iframe');
|
3
|
+
iframe.src = '/rails_profiler/widget';
|
4
|
+
iframe.frameBorder= 0;
|
5
|
+
iframe.className = 'rails-profiler-frame';
|
6
|
+
iframe.width='100%';
|
7
|
+
iframe.height='50px';
|
8
|
+
iframe.style="width=100%"
|
9
|
+
document.getElementsByTagName('body')[0].appendChild(iframe);
|
10
|
+
}
|
11
|
+
|
12
|
+
function setPageChangeCookie() {
|
13
|
+
var value = 0;
|
14
|
+
if(getCookie('rails-profiler-page-id')) {
|
15
|
+
value = parseInt(getCookie('rails-profiler-page-id'));
|
16
|
+
}
|
17
|
+
document.cookie="rails-profiler-page-id=" + (value+1) ;
|
18
|
+
}
|
19
|
+
|
20
|
+
function getCookie(cname) {
|
21
|
+
var name = cname + "=";
|
22
|
+
var ca = document.cookie.split(';');
|
23
|
+
for(var i=0; i<ca.length; i++) {
|
24
|
+
var c = ca[i];
|
25
|
+
while (c.charAt(0)==' ') c = c.substring(1);
|
26
|
+
if (c.indexOf(name) != -1) return c.substring(name.length,c.length);
|
27
|
+
}
|
28
|
+
return "";
|
29
|
+
}
|
30
|
+
|
31
|
+
if(window.attachEvent) {
|
32
|
+
window.attachEvent('onload', loadWidget);
|
33
|
+
window.attachEvent('onload', setPageChangeCookie);
|
34
|
+
} else {
|
35
|
+
window.addEventListener('load', loadWidget, false);
|
36
|
+
window.addEventListener('unload', setPageChangeCookie, false);
|
37
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
//= require reqwest.min
|
2
|
+
|
3
|
+
function updateResult() {
|
4
|
+
reqwest("/rails_profiler/result.json", function (res) {
|
5
|
+
document.getElementsByClassName('rails-profiler-total-memgrowth')[0].innerHTML = res.total_memory_growth;
|
6
|
+
});
|
7
|
+
}
|
8
|
+
|
9
|
+
function startUpdating() {
|
10
|
+
setInterval(updateResult, 4000);
|
11
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
/*!
|
2
|
+
* Reqwest! A general purpose XHR connection manager
|
3
|
+
* license MIT (c) Dustin Diaz 2014
|
4
|
+
* https://github.com/ded/reqwest
|
5
|
+
*/
|
6
|
+
!function(e,t,n){typeof module!="undefined"&&module.exports?module.exports=n():typeof define=="function"&&define.amd?define(n):t[e]=n()}("reqwest",this,function(){function succeed(e){var t=protocolRe.exec(e.url);return t=t&&t[1]||window.location.protocol,httpsRe.test(t)?twoHundo.test(e.request.status):!!e.request.response}function handleReadyState(e,t,n){return function(){if(e._aborted)return n(e.request);if(e._timedOut)return n(e.request,"Request is aborted: timeout");e.request&&e.request[readyState]==4&&(e.request.onreadystatechange=noop,succeed(e)?t(e.request):n(e.request))}}function setHeaders(e,t){var n=t.headers||{},r;n.Accept=n.Accept||defaultHeaders.accept[t.type]||defaultHeaders.accept["*"];var i=typeof FormData=="function"&&t.data instanceof FormData;!t.crossOrigin&&!n[requestedWith]&&(n[requestedWith]=defaultHeaders.requestedWith),!n[contentType]&&!i&&(n[contentType]=t.contentType||defaultHeaders.contentType);for(r in n)n.hasOwnProperty(r)&&"setRequestHeader"in e&&e.setRequestHeader(r,n[r])}function setCredentials(e,t){typeof t.withCredentials!="undefined"&&typeof e.withCredentials!="undefined"&&(e.withCredentials=!!t.withCredentials)}function generalCallback(e){lastValue=e}function urlappend(e,t){return e+(/\?/.test(e)?"&":"?")+t}function handleJsonp(e,t,n,r){var i=uniqid++,s=e.jsonpCallback||"callback",o=e.jsonpCallbackName||reqwest.getcallbackPrefix(i),u=new RegExp("((^|\\?|&)"+s+")=([^&]+)"),a=r.match(u),f=doc.createElement("script"),l=0,c=navigator.userAgent.indexOf("MSIE 10.0")!==-1;return a?a[3]==="?"?r=r.replace(u,"$1="+o):o=a[3]:r=urlappend(r,s+"="+o),win[o]=generalCallback,f.type="text/javascript",f.src=r,f.async=!0,typeof f.onreadystatechange!="undefined"&&!c&&(f.htmlFor=f.id="_reqwest_"+i),f.onload=f.onreadystatechange=function(){if(f[readyState]&&f[readyState]!=="complete"&&f[readyState]!=="loaded"||l)return!1;f.onload=f.onreadystatechange=null,f.onclick&&f.onclick(),t(lastValue),lastValue=undefined,head.removeChild(f),l=1},head.appendChild(f),{abort:function(){f.onload=f.onreadystatechange=null,n({},"Request is aborted: timeout",{}),lastValue=undefined,head.removeChild(f),l=1}}}function getRequest(e,t){var n=this.o,r=(n.method||"GET").toUpperCase(),i=typeof n=="string"?n:n.url,s=n.processData!==!1&&n.data&&typeof n.data!="string"?reqwest.toQueryString(n.data):n.data||null,o,u=!1;return(n["type"]=="jsonp"||r=="GET")&&s&&(i=urlappend(i,s),s=null),n["type"]=="jsonp"?handleJsonp(n,e,t,i):(o=n.xhr&&n.xhr(n)||xhr(n),o.open(r,i,n.async===!1?!1:!0),setHeaders(o,n),setCredentials(o,n),win[xDomainRequest]&&o instanceof win[xDomainRequest]?(o.onload=e,o.onerror=t,o.onprogress=function(){},u=!0):o.onreadystatechange=handleReadyState(this,e,t),n.before&&n.before(o),u?setTimeout(function(){o.send(s)},200):o.send(s),o)}function Reqwest(e,t){this.o=e,this.fn=t,init.apply(this,arguments)}function setType(e){if(e.match("json"))return"json";if(e.match("javascript"))return"js";if(e.match("text"))return"html";if(e.match("xml"))return"xml"}function init(o,fn){function complete(e){o.timeout&&clearTimeout(self.timeout),self.timeout=null;while(self._completeHandlers.length>0)self._completeHandlers.shift()(e)}function success(resp){var type=o.type||resp&&setType(resp.getResponseHeader("Content-Type"));resp=type!=="jsonp"?self.request:resp;var filteredResponse=globalSetupOptions.dataFilter(resp.responseText,type),r=filteredResponse;try{resp.responseText=r}catch(e){}if(r)switch(type){case"json":try{resp=win.JSON?win.JSON.parse(r):eval("("+r+")")}catch(err){return error(resp,"Could not parse JSON in response",err)}break;case"js":resp=eval(r);break;case"html":resp=r;break;case"xml":resp=resp.responseXML&&resp.responseXML.parseError&&resp.responseXML.parseError.errorCode&&resp.responseXML.parseError.reason?null:resp.responseXML}self._responseArgs.resp=resp,self._fulfilled=!0,fn(resp),self._successHandler(resp);while(self._fulfillmentHandlers.length>0)resp=self._fulfillmentHandlers.shift()(resp);complete(resp)}function timedOut(){self._timedOut=!0,self.request.abort()}function error(e,t,n){e=self.request,self._responseArgs.resp=e,self._responseArgs.msg=t,self._responseArgs.t=n,self._erred=!0;while(self._errorHandlers.length>0)self._errorHandlers.shift()(e,t,n);complete(e)}this.url=typeof o=="string"?o:o.url,this.timeout=null,this._fulfilled=!1,this._successHandler=function(){},this._fulfillmentHandlers=[],this._errorHandlers=[],this._completeHandlers=[],this._erred=!1,this._responseArgs={};var self=this;fn=fn||function(){},o.timeout&&(this.timeout=setTimeout(function(){timedOut()},o.timeout)),o.success&&(this._successHandler=function(){o.success.apply(o,arguments)}),o.error&&this._errorHandlers.push(function(){o.error.apply(o,arguments)}),o.complete&&this._completeHandlers.push(function(){o.complete.apply(o,arguments)}),this.request=getRequest.call(this,success,error)}function reqwest(e,t){return new Reqwest(e,t)}function normalize(e){return e?e.replace(/\r?\n/g,"\r\n"):""}function serial(e,t){var n=e.name,r=e.tagName.toLowerCase(),i=function(e){e&&!e.disabled&&t(n,normalize(e.attributes.value&&e.attributes.value.specified?e.value:e.text))},s,o,u,a;if(e.disabled||!n)return;switch(r){case"input":/reset|button|image|file/i.test(e.type)||(s=/checkbox/i.test(e.type),o=/radio/i.test(e.type),u=e.value,(!s&&!o||e.checked)&&t(n,normalize(s&&u===""?"on":u)));break;case"textarea":t(n,normalize(e.value));break;case"select":if(e.type.toLowerCase()==="select-one")i(e.selectedIndex>=0?e.options[e.selectedIndex]:null);else for(a=0;e.length&&a<e.length;a++)e.options[a].selected&&i(e.options[a])}}function eachFormElement(){var e=this,t,n,r=function(t,n){var r,i,s;for(r=0;r<n.length;r++){s=t[byTag](n[r]);for(i=0;i<s.length;i++)serial(s[i],e)}};for(n=0;n<arguments.length;n++)t=arguments[n],/input|select|textarea/i.test(t.tagName)&&serial(t,e),r(t,["input","select","textarea"])}function serializeQueryString(){return reqwest.toQueryString(reqwest.serializeArray.apply(null,arguments))}function serializeHash(){var e={};return eachFormElement.apply(function(t,n){t in e?(e[t]&&!isArray(e[t])&&(e[t]=[e[t]]),e[t].push(n)):e[t]=n},arguments),e}function buildParams(e,t,n,r){var i,s,o,u=/\[\]$/;if(isArray(t))for(s=0;t&&s<t.length;s++)o=t[s],n||u.test(e)?r(e,o):buildParams(e+"["+(typeof o=="object"?s:"")+"]",o,n,r);else if(t&&t.toString()==="[object Object]")for(i in t)buildParams(e+"["+i+"]",t[i],n,r);else r(e,t)}var win=window,doc=document,httpsRe=/^http/,protocolRe=/(^\w+):\/\//,twoHundo=/^(20\d|1223)$/,byTag="getElementsByTagName",readyState="readyState",contentType="Content-Type",requestedWith="X-Requested-With",head=doc[byTag]("head")[0],uniqid=0,callbackPrefix="reqwest_"+ +(new Date),lastValue,xmlHttpRequest="XMLHttpRequest",xDomainRequest="XDomainRequest",noop=function(){},isArray=typeof Array.isArray=="function"?Array.isArray:function(e){return e instanceof Array},defaultHeaders={contentType:"application/x-www-form-urlencoded",requestedWith:xmlHttpRequest,accept:{"*":"text/javascript, text/html, application/xml, text/xml, */*",xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript",js:"application/javascript, text/javascript"}},xhr=function(e){if(e.crossOrigin===!0){var t=win[xmlHttpRequest]?new XMLHttpRequest:null;if(t&&"withCredentials"in t)return t;if(win[xDomainRequest])return new XDomainRequest;throw new Error("Browser does not support cross-origin requests")}return win[xmlHttpRequest]?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP")},globalSetupOptions={dataFilter:function(e){return e}};return Reqwest.prototype={abort:function(){this._aborted=!0,this.request.abort()},retry:function(){init.call(this,this.o,this.fn)},then:function(e,t){return e=e||function(){},t=t||function(){},this._fulfilled?this._responseArgs.resp=e(this._responseArgs.resp):this._erred?t(this._responseArgs.resp,this._responseArgs.msg,this._responseArgs.t):(this._fulfillmentHandlers.push(e),this._errorHandlers.push(t)),this},always:function(e){return this._fulfilled||this._erred?e(this._responseArgs.resp):this._completeHandlers.push(e),this},fail:function(e){return this._erred?e(this._responseArgs.resp,this._responseArgs.msg,this._responseArgs.t):this._errorHandlers.push(e),this},"catch":function(e){return this.fail(e)}},reqwest.serializeArray=function(){var e=[];return eachFormElement.apply(function(t,n){e.push({name:t,value:n})},arguments),e},reqwest.serialize=function(){if(arguments.length===0)return"";var e,t,n=Array.prototype.slice.call(arguments,0);return e=n.pop(),e&&e.nodeType&&n.push(e)&&(e=null),e&&(e=e.type),e=="map"?t=serializeHash:e=="array"?t=reqwest.serializeArray:t=serializeQueryString,t.apply(null,n)},reqwest.toQueryString=function(e,t){var n,r,i=t||!1,s=[],o=encodeURIComponent,u=function(e,t){t="function"==typeof t?t():t==null?"":t,s[s.length]=o(e)+"="+o(t)};if(isArray(e))for(r=0;e&&r<e.length;r++)u(e[r].name,e[r].value);else for(n in e)e.hasOwnProperty(n)&&buildParams(n,e[n],i,u);return s.join("&").replace(/%20/g,"+")},reqwest.getcallbackPrefix=function(){return callbackPrefix},reqwest.compat=function(e,t){return e&&(e.type&&(e.method=e.type)&&delete e.type,e.dataType&&(e.type=e.dataType),e.jsonpCallback&&(e.jsonpCallbackName=e.jsonpCallback)&&delete e.jsonpCallback,e.jsonp&&(e.jsonpCallback=e.jsonp)),new Reqwest(e,t)},reqwest.ajaxSetup=function(e){e=e||{};for(var t in e)globalSetupOptions[t]=e[t]},reqwest})
|
@@ -0,0 +1,39 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree ./rails_profiler
|
14
|
+
*= require_self
|
15
|
+
*/
|
16
|
+
|
17
|
+
.rails-profiler-container {
|
18
|
+
background-color: rgba(255, 255, 255, 1);
|
19
|
+
padding: 1px;
|
20
|
+
font-family: monospace;
|
21
|
+
height: 40px;
|
22
|
+
}
|
23
|
+
|
24
|
+
.rails-profiler-container > ul > li {
|
25
|
+
list-style: none;
|
26
|
+
width: 320px;
|
27
|
+
}
|
28
|
+
|
29
|
+
.rails-profiler-measure {
|
30
|
+
width: 160px;
|
31
|
+
position: relative;
|
32
|
+
}
|
33
|
+
|
34
|
+
.rails-profiler-total-memgrowth {
|
35
|
+
width: 160px;
|
36
|
+
position: relative;
|
37
|
+
left: 160px;
|
38
|
+
top: -14px;
|
39
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>RailsProfiler</title>
|
5
|
+
<%= stylesheet_link_tag "rails_profiler", media: "all" %>
|
6
|
+
<%= javascript_include_tag "rails_profiler_widget" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div id="rails-profiler-container" class="rails-profiler-container">
|
2
|
+
<ul>
|
3
|
+
<li >
|
4
|
+
<div class="rails-profiler-measure">Toal memory growth :</div>
|
5
|
+
<div class="rails-profiler-total-memgrowth"> <%= RailsProfiler::Profiler.result[:total_memory_growth] %> </div>
|
6
|
+
</li>
|
7
|
+
</ul>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<script type="text/javascript" charset="utf-8">
|
11
|
+
startUpdating();
|
12
|
+
</script>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rails_profiler/middleware'
|
2
|
+
module RailsProfiler
|
3
|
+
class Engine < ::Rails::Engine
|
4
|
+
isolate_namespace RailsProfiler
|
5
|
+
|
6
|
+
initializer "rails_profiler.add_middleware" do |app|
|
7
|
+
app.middleware.insert(0, RailsProfiler::Middleware)
|
8
|
+
end
|
9
|
+
if config.respond_to? (:assets)
|
10
|
+
config.assets.precompile += %w{ rails_profiler.js rails_profiler.css rails_profiler_widget.js }
|
11
|
+
end
|
12
|
+
config.after_initialize do |app|
|
13
|
+
app.routes.prepend do
|
14
|
+
mount RailsProfiler::Engine => '/rails_profiler'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rails_profiler/profiler'
|
2
|
+
|
3
|
+
module RailsProfiler
|
4
|
+
class Middleware
|
5
|
+
@@previous_page_id = 0
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
request = Rack::Request.new(env)
|
12
|
+
if(skip_request?(request))
|
13
|
+
status,headers,body = @app.call(env)
|
14
|
+
return [status,headers,body]
|
15
|
+
end
|
16
|
+
if request.cookies['rails-profiler-page-id'] != @@previous_page_id
|
17
|
+
@@previous_page_id = request.cookies['rails-profiler-page-id']
|
18
|
+
Profiler.clear_results
|
19
|
+
end
|
20
|
+
status, headers, body = nil
|
21
|
+
Profiler.profile(request) do
|
22
|
+
status,headers,body = @app.call(env)
|
23
|
+
end
|
24
|
+
[status, headers, body]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Skip all rails_profiler related request from profiling
|
28
|
+
def skip_request?(request)
|
29
|
+
case request.path
|
30
|
+
when '/rails_profiler/result.json'
|
31
|
+
return true
|
32
|
+
when '/rails_profiler/widget'
|
33
|
+
return true
|
34
|
+
else
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'objspace'
|
2
|
+
|
3
|
+
module RailsProfiler
|
4
|
+
class Profiler
|
5
|
+
@@result = {
|
6
|
+
total_memory_growth: 0,
|
7
|
+
total_wall_time: 0,
|
8
|
+
total_cpu_time: 0
|
9
|
+
}
|
10
|
+
@@perform_gc = false
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def set_result(url, measure, value)
|
14
|
+
@@result[url] ||= {}
|
15
|
+
@@result[url][measure] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def result
|
19
|
+
@@result
|
20
|
+
end
|
21
|
+
|
22
|
+
def clear_results
|
23
|
+
@@result = {}
|
24
|
+
end
|
25
|
+
|
26
|
+
def profile(request)
|
27
|
+
url = request.url
|
28
|
+
if /rp-gc=/ === request.query_string
|
29
|
+
@@perform_gc = (/rp-gc=true/ === request.query_string)
|
30
|
+
end
|
31
|
+
GC.start if @@perform_gc
|
32
|
+
prev_mem = ObjectSpace.memsize_of_all
|
33
|
+
|
34
|
+
yield
|
35
|
+
|
36
|
+
GC.start if @@perform_gc
|
37
|
+
new_mem = ObjectSpace.memsize_of_all
|
38
|
+
mem_growth = (new_mem - prev_mem)/1000000.0
|
39
|
+
@@result[:total_memory_growth] ||= 0
|
40
|
+
@@result[:total_memory_growth] += mem_growth
|
41
|
+
if @@result[url] && @@result[url][:memory_growth]
|
42
|
+
@@result[url][:memory_growth] += mem_growth
|
43
|
+
else
|
44
|
+
set_result(url, :memory_growth, mem_growth)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails_profiler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Emil Soman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Rails engine that reveals high level profiling information of your Rails
|
56
|
+
pages
|
57
|
+
email:
|
58
|
+
- emil.soman@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- MIT-LICENSE
|
64
|
+
- app/assets/javascripts/rails_profiler.js
|
65
|
+
- app/assets/javascripts/rails_profiler/loader.js.erb
|
66
|
+
- app/assets/javascripts/rails_profiler_widget.js
|
67
|
+
- app/assets/javascripts/reqwest.min.js
|
68
|
+
- app/assets/stylesheets/rails_profiler.css
|
69
|
+
- app/controllers/rails_profiler/application_controller.rb
|
70
|
+
- app/controllers/rails_profiler/widget_controller.rb
|
71
|
+
- app/helpers/rails_profiler/application_helper.rb
|
72
|
+
- app/views/layouts/rails_profiler/application.html.erb
|
73
|
+
- app/views/rails_profiler/widget/index.html.erb
|
74
|
+
- config/routes.rb
|
75
|
+
- lib/rails_profiler.rb
|
76
|
+
- lib/rails_profiler/engine.rb
|
77
|
+
- lib/rails_profiler/middleware.rb
|
78
|
+
- lib/rails_profiler/profiler.rb
|
79
|
+
- lib/rails_profiler/version.rb
|
80
|
+
- lib/tasks/rails_profiler_tasks.rake
|
81
|
+
homepage: https://github.com/emilsoman/rails_profiler
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">"
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 1.3.1
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.2.2
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Rails engine that reveals high level profiling information of your Rails
|
105
|
+
pages
|
106
|
+
test_files: []
|
107
|
+
has_rdoc:
|