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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dffe7a004722639d7873e77a300ca3b62ea1c03d539975170e48a2491892093d
4
- data.tar.gz: ca03875ff577f34febab9fd8c091557790412fb6b5e36bc43c82941340390a68
3
+ metadata.gz: 7b526cdf667201a0ea200a83af542812f0be52724409ce9e2573ca878d2efd06
4
+ data.tar.gz: 26b5591a60b14647cdd713615e1d3e7163e840d1048466deba94241aab762544
5
5
  SHA512:
6
- metadata.gz: b907a6c5ace84663b4527744434c062673140d30d002b0b036542f72b67db1cfba1421b7261148fa0ae4f001491f0123243d21e3f547eef2e96abb67f512c6a3
7
- data.tar.gz: 85eb799be2eaadc0025768eb648db63f2a935dec20c097a2f37aca1b943ee07080adda2a27ee91652eff6cb2f3f317855185d2349c01389953127349217a9f9c
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><%= link_to e[:controller] + '#' + e[:action], rails_performance.rails_performance_summary_path({controller_eq: e[:controller], action_eq: e[:action]}), remote: true %></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>
@@ -8,7 +8,7 @@
8
8
  </div>
9
9
  <div class="column right-text is-size-5 has-text-right">
10
10
  <label id="autoupdate_label">
11
- <input id="autoupdate" type="checkbox" checked/>
11
+ <input id="autoupdate" type="checkbox"/>
12
12
  Auto-update
13
13
  </label>
14
14
  </div>
@@ -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).times do |e|
24
- RailsPerformance::DataSource.new(q: self.q.merge({ on: e.days.ago.to_date }), type: type).add_to(result)
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'
@@ -30,4 +30,4 @@ module RailsPerformance
30
30
 
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -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.current.utc_offset
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.current.utc_offset
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
@@ -31,4 +31,4 @@ module RailsPerformance
31
31
  end
32
32
 
33
33
  end
34
- end
34
+ end
@@ -1,4 +1,4 @@
1
1
  module RailsPerformance
2
- VERSION = '1.0.5.3'
2
+ VERSION = '1.2.0.alpha1'
3
3
  SCHEMA = '1.0.1'
4
4
  end
@@ -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.5.3
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 00:00:00.000000000 Z
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: '0'
334
+ version: 1.3.1
318
335
  requirements: []
319
- rubygems_version: 3.4.10
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