rails_performance 1.0.5.3 → 1.2.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -1
- data/app/controllers/rails_performance/rails_performance_controller.rb +7 -1
- data/app/helpers/rails_performance/application_helper.rb +8 -2
- data/app/views/rails_performance/javascripts/_javascripts.html.erb +1 -0
- data/app/views/rails_performance/javascripts/app.js +13 -0
- data/app/views/rails_performance/javascripts/local-time.es2017-umd.js +1 -0
- data/app/views/rails_performance/rails_performance/_recent_row.html.erb +5 -2
- data/app/views/rails_performance/rails_performance/_trace.html.erb +6 -0
- data/app/views/rails_performance/rails_performance/recent.html.erb +1 -1
- data/app/views/rails_performance/rails_performance/slow.html.erb +39 -0
- data/app/views/rails_performance/shared/_header.html.erb +1 -0
- data/config/routes.rb +1 -0
- data/lib/rails_performance/data_source.rb +3 -3
- data/lib/rails_performance/engine.rb +1 -1
- data/lib/rails_performance/gems/custom_ext.rb +1 -1
- data/lib/rails_performance/reports/response_time_report.rb +2 -2
- data/lib/rails_performance/reports/slow_requests_report.rb +24 -0
- data/lib/rails_performance/reports/throughput_report.rb +2 -2
- data/lib/rails_performance/thread/current_request.rb +1 -1
- data/lib/rails_performance/version.rb +1 -1
- data/lib/rails_performance.rb +11 -0
- metadata +22 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b526cdf667201a0ea200a83af542812f0be52724409ce9e2573ca878d2efd06
|
4
|
+
data.tar.gz: 26b5591a60b14647cdd713615e1d3e7163e840d1048466deba94241aab762544
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0acf1b56c93e1bfb3085fccf239839a96e92a4f92eb55633fbeaca3371a33427bbcbc97091124c864fb2ca8743a338c33fd77c95ece6d85982c9e276bb12bc5f
|
7
|
+
data.tar.gz: b2a8d5c8460c047f0614f6bae5124512e892e21d88f58c45578ce838dfefe16cd8aff3fce1c7838e5061d090e1df88047ea52ec6d8ce38f36346e1ce65d0b82b
|
data/README.md
CHANGED
@@ -14,6 +14,7 @@ This is a **simple and free alternative** to the New Relic APM, Datadog or other
|
|
14
14
|
It allows you to track:
|
15
15
|
|
16
16
|
- real-time monitoring on the Recent tab
|
17
|
+
- monitor slow requests
|
17
18
|
- throughput report (see amount of RPM (requests per minute))
|
18
19
|
- an average response time
|
19
20
|
- the slowest controllers & actions
|
@@ -59,7 +60,12 @@ RailsPerformance.setup do |config|
|
|
59
60
|
|
60
61
|
# configure Recent tab (time window and limit of requests)
|
61
62
|
# config.recent_requests_time_window = 60.minutes
|
62
|
-
# config.recent_requests_limit = nil
|
63
|
+
# config.recent_requests_limit = nil # or 1000
|
64
|
+
|
65
|
+
# configure Slow Requests tab (time window, limit of requests and threshold)
|
66
|
+
# config.slow_requests_time_window = 4.hours # time window for slow requests
|
67
|
+
# config.slow_requests_limit = 500 # number of max rows
|
68
|
+
# config.slow_requests_threshold = 500 # number of ms
|
63
69
|
|
64
70
|
# default path where to mount gem,
|
65
71
|
# alternatively you can mount the RailsPerformance::Engine in your routes.rb
|
@@ -234,6 +240,9 @@ If "schema" how records are stored i Redis is changed, and this is a breacking c
|
|
234
240
|
- https://github.com/D1ceWard
|
235
241
|
- https://github.com/carl-printreleaf
|
236
242
|
|
243
|
+
[<img src="https://opensource-heroes.com/svg/embed/igorkasyanchuk/rails_performance"
|
244
|
+
/>](https://opensource-heroes.com/r/igorkasyanchuk/rails_performance)
|
245
|
+
|
237
246
|
## License
|
238
247
|
|
239
248
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -61,6 +61,12 @@ module RailsPerformance
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
def slow
|
65
|
+
@datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
|
66
|
+
db = @datasource.db
|
67
|
+
@data = RailsPerformance::Reports::SlowRequestsReport.new(db).data
|
68
|
+
end
|
69
|
+
|
64
70
|
def sidekiq
|
65
71
|
@datasource = RailsPerformance::DataSource.new(**prepare_query, type: :sidekiq)
|
66
72
|
db = @datasource.db
|
@@ -107,4 +113,4 @@ module RailsPerformance
|
|
107
113
|
end
|
108
114
|
|
109
115
|
end
|
110
|
-
end
|
116
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module RailsPerformance
|
2
2
|
module ApplicationHelper
|
3
|
+
include LocalTimeHelper
|
4
|
+
|
3
5
|
def round_it(value, limit = 1)
|
4
6
|
return nil unless value
|
5
7
|
return value if value.is_a?(Integer)
|
@@ -49,7 +51,7 @@ module RailsPerformance
|
|
49
51
|
|
50
52
|
def link_to_path(e)
|
51
53
|
if e[:method] == 'GET'
|
52
|
-
link_to(short_path(e[:path]), e[:path], target: '_blank')
|
54
|
+
link_to(short_path(e[:path]), e[:path], target: '_blank', title: short_path(e[:path]))
|
53
55
|
else
|
54
56
|
short_path(e[:path])
|
55
57
|
end
|
@@ -105,7 +107,9 @@ module RailsPerformance
|
|
105
107
|
end
|
106
108
|
|
107
109
|
def format_datetime(e)
|
108
|
-
e.strftime("%Y-%m-%d %H:%M:%S")
|
110
|
+
#e.strftime("%Y-%m-%d %H:%M:%S")
|
111
|
+
# I18n.l(e, format: "%Y-%m-%d %H:%M:%S")
|
112
|
+
local_time(e, "%Y-%m-%d %H:%M:%S")
|
109
113
|
end
|
110
114
|
|
111
115
|
def active?(section)
|
@@ -118,6 +122,8 @@ module RailsPerformance
|
|
118
122
|
"is-active" if controller_name == "rails_performance" && action_name == "requests"
|
119
123
|
when :recent
|
120
124
|
"is-active" if controller_name == "rails_performance" && action_name == "recent"
|
125
|
+
when :slow
|
126
|
+
"is-active" if controller_name == "rails_performance" && action_name == "slow"
|
121
127
|
when :sidekiq
|
122
128
|
"is-active" if controller_name == "rails_performance" && action_name == "sidekiq"
|
123
129
|
when :delayed_job
|
@@ -1,6 +1,7 @@
|
|
1
1
|
<%= insert_js_file 'jquery-3.4.1.min.js' %>
|
2
2
|
<%= insert_js_file 'rails.js' %>
|
3
3
|
<%= insert_js_file 'stupidtable.min.js' %>
|
4
|
+
<%= insert_js_file 'local-time.es2017-umd.js' %>
|
4
5
|
|
5
6
|
<%= javascript_include_tag 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/js/all.min.js' %>
|
6
7
|
<%= javascript_include_tag 'https://code.highcharts.com/highcharts.js' %>
|
@@ -170,6 +170,17 @@ function showRTChart(div, data) {
|
|
170
170
|
const recent = document.getElementById("recent")
|
171
171
|
const autoupdate = document.getElementById("autoupdate")
|
172
172
|
|
173
|
+
if(autoupdate) {
|
174
|
+
// set autoupdate checked from localStorage is missing
|
175
|
+
if (localStorage.getItem("autoupdate") === null) {
|
176
|
+
localStorage.setItem("autoupdate", "true");
|
177
|
+
}
|
178
|
+
autoupdate.checked = localStorage.getItem("autoupdate") === "true";
|
179
|
+
autoupdate.addEventListener('change', () => {
|
180
|
+
localStorage.setItem("autoupdate", autoupdate.checked);
|
181
|
+
});
|
182
|
+
}
|
183
|
+
|
173
184
|
if(recent) {
|
174
185
|
const tbody = recent.querySelector("tbody")
|
175
186
|
|
@@ -192,3 +203,5 @@ if(recent) {
|
|
192
203
|
})
|
193
204
|
}, 3000);
|
194
205
|
}
|
206
|
+
|
207
|
+
LocalTime.start()
|
@@ -0,0 +1 @@
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LocalTime=e()}(this,(function(){"use strict";var t;t={config:{},run:function(){return this.getController().processElements()},process:function(...t){var e,r,a;for(r=0,a=t.length;r<a;r++)e=t[r],this.getController().processElement(e);return t.length},getController:function(){return null!=this.controller?this.controller:this.controller=new t.Controller}};var e,r,a,n,s,i,o,u,l,c,d,m,h,f,g,y,p,v,b,S,M,T,D,E,w,A,N,O,$,C=t;return C.config.i18n={en:{date:{dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbrDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbrMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],yesterday:"yesterday",today:"today",tomorrow:"tomorrow",on:"on {date}",formats:{default:"%b %e, %Y",thisYear:"%b %e"}},time:{am:"am",pm:"pm",singular:"a {time}",singularAn:"an {time}",elapsed:"{time} ago",second:"second",seconds:"seconds",minute:"minute",minutes:"minutes",hour:"hour",hours:"hours",formats:{default:"%l:%M%P"}},datetime:{at:"{date} at {time}",formats:{default:"%B %e, %Y at %l:%M%P %Z"}}}},C.config.locale="en",C.config.defaultLocale="en",C.config.timerInterval=6e4,a=!isNaN(Date.parse("2011-01-01T12:00:00-05:00")),C.parseDate=function(t){return t=t.toString(),a||(t=r(t)),new Date(Date.parse(t))},e=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|[-+]?[\d:]+)$/,r=function(t){var r,a,n,s,i,o,u,l,c,d;if(s=t.match(e))return[r,c,o,a,n,i,l,d]=s,"Z"!==d&&(u=d.replace(":","")),`${c}/${o}/${a} ${n}:${i}:${l} GMT${[u]}`},C.elementMatchesSelector=(n=document.documentElement,s=null!=(i=null!=(o=null!=(u=null!=(l=n.matches)?l:n.matchesSelector)?u:n.webkitMatchesSelector)?o:n.mozMatchesSelector)?i:n.msMatchesSelector,function(t,e){if((null!=t?t.nodeType:void 0)===Node.ELEMENT_NODE)return s.call(t,e)}),({config:c}=C),({i18n:m}=c),C.getI18nValue=function(t="",{locale:e}={locale:c.locale}){var r;return null!=(r=d(m[e],t))?r:e!==c.defaultLocale?C.getI18nValue(t,{locale:c.defaultLocale}):void 0},C.translate=function(t,e={},r){var a,n,s;for(a in s=C.getI18nValue(t,r),e)n=e[a],s=s.replace(`{${a}}`,n);return s},d=function(t,e){var r,a,n,s,i;for(i=t,r=0,n=(s=e.split(".")).length;r<n;r++){if(null==i[a=s[r]])return null;i=i[a]}return i},({getI18nValue:h,translate:p}=C),C.strftime=y=function(t,e){var r,a,n,s,i,o,u;return a=t.getDay(),r=t.getDate(),i=t.getMonth(),u=t.getFullYear(),n=t.getHours(),s=t.getMinutes(),o=t.getSeconds(),e.replace(/%(-?)([%aAbBcdeHIlmMpPSwyYZ])/g,(function(e,l,c){switch(c){case"%":return"%";case"a":return h("date.abbrDayNames")[a];case"A":return h("date.dayNames")[a];case"b":return h("date.abbrMonthNames")[i];case"B":return h("date.monthNames")[i];case"c":return t.toString();case"d":return f(r,l);case"e":return r;case"H":return f(n,l);case"I":return f(y(t,"%l"),l);case"l":return 0===n||12===n?12:(n+12)%12;case"m":return f(i+1,l);case"M":return f(s,l);case"p":return p("time."+(n>11?"pm":"am")).toUpperCase();case"P":return p("time."+(n>11?"pm":"am"));case"S":return f(o,l);case"w":return a;case"y":return f(u%100,l);case"Y":return u;case"Z":return g(t)}}))},f=function(t,e){return"-"===e?t:`0${t}`.slice(-2)},g=function(t){var e,r,a,n,s;return(e=null!=(r=(s=t.toString()).match(/\(([\w\s]+)\)$/))?r[1]:void 0)?/\s/.test(e)?e.match(/\b(\w)/g).join(""):e:(e=null!=(a=s.match(/(\w{3,4})\s\d{4}$/))?a[1]:void 0)||(e=null!=(n=s.match(/(UTC[\+\-]\d+)/))?n[1]:void 0)?e:""},C.CalendarDate=class{static fromDate(t){return new this(t.getFullYear(),t.getMonth()+1,t.getDate())}static today(){return this.fromDate(new Date)}constructor(t,e,r){this.date=new Date(Date.UTC(t,e-1)),this.date.setUTCDate(r),this.year=this.date.getUTCFullYear(),this.month=this.date.getUTCMonth()+1,this.day=this.date.getUTCDate(),this.value=this.date.getTime()}equals(t){return(null!=t?t.value:void 0)===this.value}is(t){return this.equals(t)}isToday(){return this.is(this.constructor.today())}occursOnSameYearAs(t){return this.year===(null!=t?t.year:void 0)}occursThisYear(){return this.occursOnSameYearAs(this.constructor.today())}daysSince(t){if(t)return(this.date-t.date)/864e5}daysPassed(){return this.constructor.today().daysSince(this)}},({strftime:b,translate:S,getI18nValue:v}=C),C.RelativeTime=class{constructor(t){this.date=t,this.calendarDate=C.CalendarDate.fromDate(this.date)}toString(){var t,e;return(e=this.toTimeElapsedString())?S("time.elapsed",{time:e}):(t=this.toWeekdayString())?(e=this.toTimeString(),S("datetime.at",{date:t,time:e})):S("date.on",{date:this.toDateString()})}toTimeOrDateString(){return this.calendarDate.isToday()?this.toTimeString():this.toDateString()}toTimeElapsedString(){var t,e,r,a,n;return r=(new Date).getTime()-this.date.getTime(),a=Math.round(r/1e3),e=Math.round(a/60),t=Math.round(e/60),r<0?null:a<10?(n=S("time.second"),S("time.singular",{time:n})):a<45?`${a} ${S("time.seconds")}`:a<90?(n=S("time.minute"),S("time.singular",{time:n})):e<45?`${e} ${S("time.minutes")}`:e<90?(n=S("time.hour"),S("time.singularAn",{time:n})):t<24?`${t} ${S("time.hours")}`:""}toWeekdayString(){switch(this.calendarDate.daysPassed()){case 0:return S("date.today");case 1:return S("date.yesterday");case-1:return S("date.tomorrow");case 2:case 3:case 4:case 5:case 6:return b(this.date,"%A");default:return""}}toDateString(){var t;return t=this.calendarDate.occursThisYear()?v("date.formats.thisYear"):v("date.formats.default"),b(this.date,t)}toTimeString(){return b(this.date,v("time.formats.default"))}},({elementMatchesSelector:M}=C),C.PageObserver=class{constructor(t,e){this.processMutations=this.processMutations.bind(this),this.processInsertion=this.processInsertion.bind(this),this.selector=t,this.callback=e}start(){if(!this.started)return this.observeWithMutationObserver()||this.observeWithMutationEvent(),this.started=!0}observeWithMutationObserver(){if("undefined"!=typeof MutationObserver&&null!==MutationObserver)return new MutationObserver(this.processMutations).observe(document.documentElement,{childList:!0,subtree:!0}),!0}observeWithMutationEvent(){return addEventListener("DOMNodeInserted",this.processInsertion,!1),!0}findSignificantElements(t){var e;return e=[],(null!=t?t.nodeType:void 0)===Node.ELEMENT_NODE&&(M(t,this.selector)&&e.push(t),e.push(...t.querySelectorAll(this.selector))),e}processMutations(t){var e,r,a,n,s,i,o,u;for(e=[],r=0,n=t.length;r<n;r++)if("childList"===(i=t[r]).type)for(a=0,s=(u=i.addedNodes).length;a<s;a++)o=u[a],e.push(...this.findSignificantElements(o));return this.notify(e)}processInsertion(t){var e;return e=this.findSignificantElements(t.target),this.notify(e)}notify(t){if(null!=t?t.length:void 0)return"function"==typeof this.callback?this.callback(t):void 0}},({parseDate:E,strftime:w,getI18nValue:D,config:T}=C),C.Controller=function(){var t,e,r;return t="time[data-local]:not([data-localized])",e=function(t){return t.setAttribute("data-localized","")},r=function(t){return new C.RelativeTime(t)},class{constructor(){this.processElements=this.processElements.bind(this),this.pageObserver=new C.PageObserver(t,this.processElements)}start(){if(!this.started)return this.processElements(),this.startTimer(),this.pageObserver.start(),this.started=!0}startTimer(){var t;if(t=T.timerInterval)return null!=this.timer?this.timer:this.timer=setInterval(this.processElements,t)}processElements(e=document.querySelectorAll(t)){var r,a,n;for(a=0,n=e.length;a<n;a++)r=e[a],this.processElement(r);return e.length}processElement(t){var a,n,s,i,o,u;if(n=t.getAttribute("datetime"),s=t.getAttribute("data-format"),i=t.getAttribute("data-local"),o=E(n),!isNaN(o))return t.hasAttribute("title")||(u=w(o,D("datetime.formats.default")),t.setAttribute("title",u)),t.textContent=a=function(){switch(i){case"time":return e(t),w(o,s);case"date":return e(t),r(o).toDateString();case"time-ago":return r(o).toString();case"time-or-date":return r(o).toTimeOrDateString();case"weekday":return r(o).toWeekdayString();case"weekday-or-date":return r(o).toWeekdayString()||r(o).toDateString()}}(),t.hasAttribute("aria-label")?void 0:t.setAttribute("aria-label",a)}}}.call(window),$=!1,A=function(){return document.attachEvent?"complete"===document.readyState:"loading"!==document.readyState},N=function(t){var e;return null!=(e="function"==typeof requestAnimationFrame?requestAnimationFrame(t):void 0)?e:setTimeout(t,17)},O=function(){return C.getController().start()},C.start=function(){if(!$)return $=!0,"undefined"!=typeof MutationObserver&&null!==MutationObserver||A()?O():N(O)},window.LocalTime===C&&C.start(),C}));
|
@@ -7,7 +7,10 @@
|
|
7
7
|
<% end %>
|
8
8
|
</td>
|
9
9
|
<td><%= format_datetime e[:datetime] %></td>
|
10
|
-
<td
|
10
|
+
<td>
|
11
|
+
<% controller_action_info = e[:controller] + '#' + e[:action]%>
|
12
|
+
<%= link_to truncate(controller_action_info, length: 40), rails_performance.rails_performance_summary_path({controller_eq: e[:controller], action_eq: e[:action]}), remote: true, title: controller_action_info %>
|
13
|
+
</td>
|
11
14
|
<td><%= e[:method] %></td>
|
12
15
|
<td><%= e[:format] %></td>
|
13
16
|
<td><%= link_to_path(e) %></td>
|
@@ -22,4 +25,4 @@
|
|
22
25
|
<% end %>
|
23
26
|
<% end %>
|
24
27
|
</td>
|
25
|
-
</tr>
|
28
|
+
</tr>
|
@@ -19,5 +19,11 @@
|
|
19
19
|
<% end %>
|
20
20
|
</tr>
|
21
21
|
<% end %>
|
22
|
+
|
23
|
+
<% if @data.empty? %>
|
24
|
+
<tr>
|
25
|
+
<td>Nothing to show here. Perphaps details about the requests already expired. Setting "slow_requests_time_window" should be equal to "duration".</td>
|
26
|
+
</td>
|
27
|
+
<% end %>
|
22
28
|
</tbody>
|
23
29
|
</table>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<title>Slow Requests</title>
|
2
|
+
|
3
|
+
<div class="card">
|
4
|
+
<div class="card-content">
|
5
|
+
<div class="columns">
|
6
|
+
<div class="column">
|
7
|
+
<h2 class="subtitle">Slow Requests (last <%= RailsPerformance.slow_requests_time_window / 60 %> minutes + slower then <%= RailsPerformance.slow_requests_threshold %>ms)<h2>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<table id="recent" class="table is-fullwidth is-hoverable is-narrow">
|
12
|
+
<thead>
|
13
|
+
<tr>
|
14
|
+
<th data-sort="string"></th>
|
15
|
+
<th data-sort="string">Datetime</th>
|
16
|
+
<th data-sort="string">Controller#action</th>
|
17
|
+
<th data-sort="string">Method</th>
|
18
|
+
<th data-sort="string">Format</th>
|
19
|
+
<th data-sort="string">Path</th>
|
20
|
+
<th data-sort="string">Status</th>
|
21
|
+
<th data-sort="float">Duration</th>
|
22
|
+
<th data-sort="float">Views</th>
|
23
|
+
<th data-sort="float">DB</th>
|
24
|
+
<th></th>
|
25
|
+
</tr>
|
26
|
+
</thead>
|
27
|
+
<tbody>
|
28
|
+
<% if @data.empty? %>
|
29
|
+
<tr>
|
30
|
+
<td colspan="10">Nothing to show here. Try to make a few requests in the main app.</td>
|
31
|
+
</tr>
|
32
|
+
<% end %>
|
33
|
+
<% @data.each do |e| %>
|
34
|
+
<%= render 'recent_row', e: e %>
|
35
|
+
<% end %>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
</div>
|
39
|
+
</div>
|
@@ -18,6 +18,7 @@
|
|
18
18
|
<%= link_to 'Requests Analysis', rails_performance.rails_performance_requests_url, class: "navbar-item #{active?(:requests)}" %>
|
19
19
|
<%= link_to '500 Errors', rails_performance.rails_performance_crashes_url, class: "navbar-item #{active?(:crashes)}" %>
|
20
20
|
<%= link_to 'Recent Requests', rails_performance.rails_performance_recent_url, class: "navbar-item #{active?(:recent)}" %>
|
21
|
+
<%= link_to 'Slow Requests', rails_performance.rails_performance_slow_url, class: "navbar-item #{active?(:slow)}" %>
|
21
22
|
<% if defined?(Sidekiq) %>
|
22
23
|
<%= link_to 'Sidekiq', rails_performance.rails_performance_sidekiq_url, class: "navbar-item #{active?(:sidekiq)}" %>
|
23
24
|
<% end %>
|
data/config/routes.rb
CHANGED
@@ -4,6 +4,7 @@ RailsPerformance::Engine.routes.draw do
|
|
4
4
|
get '/requests' => 'rails_performance#requests', as: :rails_performance_requests
|
5
5
|
get '/crashes' => 'rails_performance#crashes', as: :rails_performance_crashes
|
6
6
|
get '/recent' => 'rails_performance#recent', as: :rails_performance_recent
|
7
|
+
get '/slow' => 'rails_performance#slow', as: :rails_performance_slow
|
7
8
|
|
8
9
|
get '/trace/:id' => 'rails_performance#trace', as: :rails_performance_trace
|
9
10
|
get '/summary' => 'rails_performance#summary', as: :rails_performance_summary
|
@@ -20,8 +20,8 @@ module RailsPerformance
|
|
20
20
|
|
21
21
|
def db
|
22
22
|
result = RailsPerformance::Models::Collection.new
|
23
|
-
(RailsPerformance::Utils.days + 1).
|
24
|
-
RailsPerformance::DataSource.new(q: self.q.merge({ on: e.days.
|
23
|
+
(0..(RailsPerformance::Utils.days + 1)).to_a.reverse.each do |e|
|
24
|
+
RailsPerformance::DataSource.new(q: self.q.merge({ on: (Time.now - e.days).to_date }), type: type).add_to(result)
|
25
25
|
end
|
26
26
|
result
|
27
27
|
end
|
@@ -118,4 +118,4 @@ module RailsPerformance
|
|
118
118
|
end
|
119
119
|
|
120
120
|
end
|
121
|
-
end
|
121
|
+
end
|
@@ -55,7 +55,7 @@ module RailsPerformance
|
|
55
55
|
next unless RailsPerformance.enabled
|
56
56
|
|
57
57
|
ActionView::LogSubscriber.send :prepend, RailsPerformance::Extensions::View
|
58
|
-
ActiveRecord::LogSubscriber.send :prepend, RailsPerformance::Extensions::Db
|
58
|
+
ActiveRecord::LogSubscriber.send :prepend, RailsPerformance::Extensions::Db if defined?(ActiveRecord)
|
59
59
|
|
60
60
|
if defined?(::Rake::Task)
|
61
61
|
require_relative './gems/rake_ext.rb'
|
@@ -10,7 +10,7 @@ module RailsPerformance
|
|
10
10
|
stop = Time.at(60 * (Time.now.to_i / 60))
|
11
11
|
current = stop - RailsPerformance.duration
|
12
12
|
@data = []
|
13
|
-
offset = Time.
|
13
|
+
offset = Time.now.utc_offset
|
14
14
|
|
15
15
|
# puts "current: #{current}"
|
16
16
|
# puts "stop: #{stop}"
|
@@ -34,4 +34,4 @@ module RailsPerformance
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RailsPerformance
|
2
|
+
module Reports
|
3
|
+
class SlowRequestsReport < BaseReport
|
4
|
+
def set_defaults
|
5
|
+
@sort ||= :datetimei
|
6
|
+
end
|
7
|
+
|
8
|
+
def data
|
9
|
+
db.data
|
10
|
+
.collect{|e| e.record_hash}
|
11
|
+
.select{|e| e if e[sort] > RailsPerformance.slow_requests_time_window.ago.to_i}
|
12
|
+
.sort{|a, b| b[sort] <=> a[sort]}
|
13
|
+
.filter{|e| e[:duration] > RailsPerformance.slow_requests_threshold.to_i}
|
14
|
+
.first(limit)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def limit
|
20
|
+
RailsPerformance.slow_requests_limit ? RailsPerformance.slow_requests_limit.to_i : 100_000
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -11,7 +11,7 @@ module RailsPerformance
|
|
11
11
|
stop = Time.at(60 * (Time.now.to_i / 60))
|
12
12
|
current = stop - RailsPerformance.duration
|
13
13
|
@data = []
|
14
|
-
offset = Time.
|
14
|
+
offset = Time.now.utc_offset
|
15
15
|
|
16
16
|
# puts "current: #{current}"
|
17
17
|
# puts "stop: #{stop}"
|
@@ -34,4 +34,4 @@ module RailsPerformance
|
|
34
34
|
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
data/lib/rails_performance.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "redis"
|
2
2
|
require "redis-namespace"
|
3
|
+
require "local_time"
|
3
4
|
require_relative "./rails_performance/version.rb"
|
4
5
|
require_relative "rails_performance/rails/query_builder.rb"
|
5
6
|
require_relative "rails_performance/rails/middleware.rb"
|
@@ -19,6 +20,7 @@ require_relative "rails_performance/reports/crash_report.rb"
|
|
19
20
|
require_relative "rails_performance/reports/response_time_report.rb"
|
20
21
|
require_relative "rails_performance/reports/throughput_report.rb"
|
21
22
|
require_relative "rails_performance/reports/recent_requests_report.rb"
|
23
|
+
require_relative "rails_performance/reports/slow_requests_report.rb"
|
22
24
|
require_relative "rails_performance/reports/breakdown_report.rb"
|
23
25
|
require_relative "rails_performance/reports/trace_report.rb"
|
24
26
|
require_relative "rails_performance/extensions/trace.rb"
|
@@ -39,6 +41,15 @@ module RailsPerformance
|
|
39
41
|
mattr_accessor :recent_requests_limit
|
40
42
|
@@recent_requests_limit = nil
|
41
43
|
|
44
|
+
mattr_accessor :slow_requests_time_window
|
45
|
+
@@slow_requests_time_window = 4.hours
|
46
|
+
|
47
|
+
mattr_accessor :slow_requests_limit
|
48
|
+
@@recent_requests_limit = 500
|
49
|
+
|
50
|
+
mattr_accessor :slow_requests_threshold
|
51
|
+
@@slow_requests_threshold = 500
|
52
|
+
|
42
53
|
mattr_accessor :debug
|
43
54
|
@@debug = false
|
44
55
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_performance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.2.0.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: local_time
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: sqlite3
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -234,6 +248,7 @@ files:
|
|
234
248
|
- app/views/rails_performance/javascripts/_javascripts.html.erb
|
235
249
|
- app/views/rails_performance/javascripts/app.js
|
236
250
|
- app/views/rails_performance/javascripts/jquery-3.4.1.min.js
|
251
|
+
- app/views/rails_performance/javascripts/local-time.es2017-umd.js
|
237
252
|
- app/views/rails_performance/javascripts/navbar.js
|
238
253
|
- app/views/rails_performance/javascripts/panel.js
|
239
254
|
- app/views/rails_performance/javascripts/rails.js
|
@@ -253,6 +268,7 @@ files:
|
|
253
268
|
- app/views/rails_performance/rails_performance/recent.js.erb
|
254
269
|
- app/views/rails_performance/rails_performance/requests.html.erb
|
255
270
|
- app/views/rails_performance/rails_performance/sidekiq.html.erb
|
271
|
+
- app/views/rails_performance/rails_performance/slow.html.erb
|
256
272
|
- app/views/rails_performance/rails_performance/summary.js.erb
|
257
273
|
- app/views/rails_performance/rails_performance/trace.js.erb
|
258
274
|
- app/views/rails_performance/shared/_header.html.erb
|
@@ -292,6 +308,7 @@ files:
|
|
292
308
|
- lib/rails_performance/reports/recent_requests_report.rb
|
293
309
|
- lib/rails_performance/reports/requests_report.rb
|
294
310
|
- lib/rails_performance/reports/response_time_report.rb
|
311
|
+
- lib/rails_performance/reports/slow_requests_report.rb
|
295
312
|
- lib/rails_performance/reports/throughput_report.rb
|
296
313
|
- lib/rails_performance/reports/trace_report.rb
|
297
314
|
- lib/rails_performance/thread/current_request.rb
|
@@ -312,11 +329,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
312
329
|
version: '0'
|
313
330
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
314
331
|
requirements:
|
315
|
-
- - "
|
332
|
+
- - ">"
|
316
333
|
- !ruby/object:Gem::Version
|
317
|
-
version:
|
334
|
+
version: 1.3.1
|
318
335
|
requirements: []
|
319
|
-
rubygems_version: 3.4.
|
336
|
+
rubygems_version: 3.4.13
|
320
337
|
signing_key:
|
321
338
|
specification_version: 4
|
322
339
|
summary: Simple Rails Performance tracker. Alternative to the NewRelic, Datadog or
|