rails_performance 1.0.0.beta2 → 1.0.1

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: 136a862da6c0d5b7d7d458e6c5389314cfe776d0437272d319d89a95eeaa8a11
4
- data.tar.gz: 913394396bb6d45c8a9d12d8b2f115bc135cf9fe61eee19c79a3a88165c50551
3
+ metadata.gz: 372161a3472691a4bf4c51d4625fbdc743d3c307af1e98779af2838f8523418a
4
+ data.tar.gz: 7d3e7f3adc3b3fd55f80173796271f85c238f4a8a2c6fe69fa89791295b45b1b
5
5
  SHA512:
6
- metadata.gz: 4e07938ad437c12dfc911ca66d06717eded983694436b9936bc038876c685bcd9bc432c42ddc35279eb96e5511220781d790f3322f1f1acd6cfce4cce1fc27c2
7
- data.tar.gz: 6fd601401eba7c250a31481df0f4bf1bf92c5d856ea9f5c454f3eefd45fbccc669fb1f088538a2a56a0a0decf5627eb87b2e1e93557b0515fd34ee0b575608df
6
+ metadata.gz: b3212e91b066f04165c9dc8dd77c15c77ba38709ceda23056c11e4fc7a2b1bc4238f64a6bc819c84d83f487ff73d70a8b876ce0c2af252b1e8777a40df4bb48f
7
+ data.tar.gz: a5146bfc66664841d89e8e0e51c7d3f3a47207e00f821504cd97a635d503cd263d7f2b33d34ebdf5827a764f10d0ad74c7140481aff91f1ec01297704ce304ce
data/README.md CHANGED
@@ -119,7 +119,13 @@ Rails.application.routes.draw do
119
119
  end
120
120
  ```
121
121
 
122
+ ### Custom events
122
123
 
124
+ ```ruby
125
+ RailsPerformance.measure("some label", "some namespace") do
126
+ # your code
127
+ end
128
+ ```
123
129
 
124
130
  ## How it works
125
131
 
@@ -6,20 +6,20 @@ module RailsPerformance
6
6
 
7
7
  if RailsPerformance.enabled
8
8
  def index
9
- @datasource = RP::DataSource.new(**prepare_query, type: :requests)
9
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
10
10
  db = @datasource.db
11
11
 
12
- @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
13
- @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
12
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
13
+ @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
14
14
  end
15
15
 
16
16
  def summary
17
- @datasource = RP::DataSource.new(**prepare_query, type: :requests)
17
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
18
18
  db = @datasource.db
19
19
 
20
- @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
21
- @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
22
- @data = RP::Reports::BreakdownReport.new(db, title: "Requests").data
20
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
21
+ @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
22
+ @data = RailsPerformance::Reports::BreakdownReport.new(db, title: "Requests").data
23
23
 
24
24
  respond_to do |format|
25
25
  format.js {}
@@ -28,8 +28,8 @@ module RailsPerformance
28
28
  end
29
29
 
30
30
  def trace
31
- @record = RP::Models::RequestRecord.find_by(request_id: params[:id])
32
- @data = RP::Reports::TraceReport.new(request_id: params[:id]).data
31
+ @record = RailsPerformance::Models::RequestRecord.find_by(request_id: params[:id])
32
+ @data = RailsPerformance::Reports::TraceReport.new(request_id: params[:id]).data
33
33
  respond_to do |format|
34
34
  format.js {}
35
35
  format.any { render plain: "Doesn't open in new window. Wait until full page load." }
@@ -37,65 +37,65 @@ module RailsPerformance
37
37
  end
38
38
 
39
39
  def crashes
40
- @datasource = RP::DataSource.new(**prepare_query({status_eq: 500}), type: :requests)
40
+ @datasource = RailsPerformance::DataSource.new(**prepare_query({status_eq: 500}), type: :requests)
41
41
  db = @datasource.db
42
- @data = RP::Reports::CrashReport.new(db).data
42
+ @data = RailsPerformance::Reports::CrashReport.new(db).data
43
43
  end
44
44
 
45
45
  def requests
46
- @datasource = RP::DataSource.new(**prepare_query, type: :requests)
46
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
47
47
  db = @datasource.db
48
- @data = RP::Reports::RequestsReport.new(db, group: :controller_action_format, sort: :count).data
48
+ @data = RailsPerformance::Reports::RequestsReport.new(db, group: :controller_action_format, sort: :count).data
49
49
  end
50
50
 
51
51
  def recent
52
- @datasource = RP::DataSource.new(**prepare_query, type: :requests)
52
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :requests)
53
53
  db = @datasource.db
54
- @data = RP::Reports::RecentRequestsReport.new(db).data
54
+ @data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
55
55
  end
56
56
 
57
57
  def sidekiq
58
- @datasource = RP::DataSource.new(**prepare_query, type: :sidekiq)
58
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :sidekiq)
59
59
  db = @datasource.db
60
- @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
61
- @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
62
- @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
60
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
61
+ @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
62
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
63
63
  end
64
64
 
65
65
  def delayed_job
66
- @datasource = RP::DataSource.new(**prepare_query, type: :delayed_job)
66
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :delayed_job)
67
67
  db = @datasource.db
68
- @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
69
- @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
70
- @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
68
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
69
+ @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
70
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
71
71
  end
72
72
 
73
73
  def custom
74
- @datasource = RP::DataSource.new(**prepare_query, type: :custom)
74
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :custom)
75
75
  db = @datasource.db
76
- @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
77
- @response_time_report_data = RP::Reports::ResponseTimeReport.new(db).data
78
- @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
76
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
77
+ @response_time_report_data = RailsPerformance::Reports::ResponseTimeReport.new(db).data
78
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
79
79
  end
80
80
 
81
81
  def grape
82
- @datasource = RP::DataSource.new(**prepare_query, type: :grape)
82
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :grape)
83
83
  db = @datasource.db
84
- @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
85
- @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
84
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
85
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
86
86
  end
87
87
 
88
88
  def rake
89
- @datasource = RP::DataSource.new(**prepare_query, type: :rake)
89
+ @datasource = RailsPerformance::DataSource.new(**prepare_query, type: :rake)
90
90
  db = @datasource.db
91
- @throughput_report_data = RP::Reports::ThroughputReport.new(db).data
92
- @recent_report_data = RP::Reports::RecentRequestsReport.new(db).data
91
+ @throughput_report_data = RailsPerformance::Reports::ThroughputReport.new(db).data
92
+ @recent_report_data = RailsPerformance::Reports::RecentRequestsReport.new(db).data
93
93
  end
94
94
 
95
95
  private
96
96
 
97
97
  def prepare_query(query = params)
98
- RP::Rails::QueryBuilder.compose_from(query)
98
+ RailsPerformance::Rails::QueryBuilder.compose_from(query)
99
99
  end
100
100
  end
101
101
 
@@ -19,7 +19,7 @@
19
19
  <%= yield %>
20
20
  <div class="footer-box">
21
21
  © Rails Performance <span class='red'><i class="fas fa-heart"></i></span> <%= link_to 'https://github.com/igorkasyanchuk/rails_performance', 'https://github.com/igorkasyanchuk/rails_performance', target: '_blank' %>
22
- <div class="is-pulled-right">v.<%= RP::VERSION %></div>
22
+ <div class="is-pulled-right">v.<%= RailsPerformance::VERSION %></div>
23
23
  </div>
24
24
  </div>
25
25
  </section>
@@ -9,6 +9,8 @@
9
9
  <th data-sort="string">Method</th>
10
10
  <th data-sort="string">Format</th>
11
11
  <th data-sort="string">Path</th>
12
+ <th data-sort="string">Exception</th>
13
+ <th data-sort="string">Backtrace</th>
12
14
  <th data-sort="string">Status</th>
13
15
  <th data-sort="float">Duration</th>
14
16
  <th data-sort="float">Views</th>
@@ -29,6 +31,10 @@
29
31
  <td><%= e[:method] %></td>
30
32
  <td><%= e[:format] %></td>
31
33
  <td><%= link_to_path(e) %></td>
34
+ <td><%= e[:exception] %></td>
35
+ <td class="very-small-text">
36
+ <%= raw e[:backtrace]&.join("<br/>") %>
37
+ </td>
32
38
  <td><%= status_tag e[:status] %></td>
33
39
  <td class="nowrap"><%= ms e[:duration] %></td>
34
40
  <td class="nowrap"><%= ms e[:view_runtime] %></td>
@@ -84,4 +84,8 @@
84
84
 
85
85
  table th[data-sort] {
86
86
  cursor: pointer;
87
+ }
88
+
89
+ .very-small-text {
90
+ font-size: 8px;
87
91
  }
@@ -69,11 +69,11 @@ module RailsPerformance
69
69
  mattr_accessor :skip
70
70
  @@skip = false
71
71
 
72
- def self.setup
72
+ def RailsPerformance.setup
73
73
  yield(self)
74
74
  end
75
75
 
76
- def self.log(message)
76
+ def RailsPerformance.log(message)
77
77
  return
78
78
 
79
79
  if ::Rails.logger
@@ -86,8 +86,6 @@ module RailsPerformance
86
86
 
87
87
  end
88
88
 
89
- RP = RailsPerformance
90
-
91
89
  require "rails_performance/engine"
92
90
 
93
91
  require_relative './rails_performance/gems/custom_ext.rb'
@@ -19,9 +19,9 @@ module RailsPerformance
19
19
  end
20
20
 
21
21
  def db
22
- result = RP::Models::Collection.new
23
- (RP::Utils.days + 1).times do |e|
24
- RP::DataSource.new(q: self.q.merge({ on: e.days.ago.to_date }), type: type).add_to(result)
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)
25
25
  end
26
26
  result
27
27
  end
@@ -30,7 +30,7 @@ module RailsPerformance
30
30
  @q.keys == [:on]
31
31
  end
32
32
 
33
- def add_to(storage = RP::Models::Collection.new)
33
+ def add_to(storage = RailsPerformance::Models::Collection.new)
34
34
  store do |record|
35
35
  storage.add(record)
36
36
  end
@@ -13,7 +13,11 @@ module RailsPerformance
13
13
  if ::Rails::VERSION::MAJOR.to_i >= 5
14
14
  app.middleware.insert_after ActionDispatch::Executor, RailsPerformance::Rails::Middleware
15
15
  else
16
- app.middleware.insert_after ActionDispatch::Static, RailsPerformance::Rails::Middleware
16
+ begin
17
+ app.middleware.insert_after ActionDispatch::Static, RailsPerformance::Rails::Middleware
18
+ rescue
19
+ app.middleware.insert_after Rack::SendFile, RailsPerformance::Rails::Middleware
20
+ end
17
21
  end
18
22
  # look like it works in reverse order?
19
23
  app.middleware.insert_before RailsPerformance::Rails::Middleware, RailsPerformance::Rails::MiddlewareTraceStorerAndCleanup
@@ -52,11 +56,11 @@ module RailsPerformance
52
56
 
53
57
  ActionView::LogSubscriber.send :prepend, RailsPerformance::Extensions::View
54
58
  ActiveRecord::LogSubscriber.send :prepend, RailsPerformance::Extensions::Db
55
- end
56
59
 
57
- if defined?(::Rake::Task)
58
- require_relative './gems/rake_ext.rb'
59
- RailsPerformance::Gems::RakeExt.init
60
+ if defined?(::Rake::Task)
61
+ require_relative './gems/rake_ext.rb'
62
+ RailsPerformance::Gems::RakeExt.init
63
+ end
60
64
  end
61
65
  end
62
66
  end
@@ -7,7 +7,7 @@ module RailsPerformance
7
7
 
8
8
  def call(worker, msg, queue)
9
9
  now = Time.now
10
- record = RP::Models::SidekiqRecord.new(
10
+ record = RailsPerformance::Models::SidekiqRecord.new(
11
11
  enqueued_ati: msg['enqueued_at'].to_i,
12
12
  datetimei: msg['created_at'].to_i,
13
13
  jid: msg['jid'],
@@ -17,6 +17,8 @@ module RailsPerformance
17
17
 
18
18
  def call(event_name, started, finished, event_id, payload)
19
19
  return if RailsPerformance.skip
20
+ return if CurrentRequest.current.data
21
+
20
22
  # TODO do we need this new?
21
23
  event = ActiveSupport::Notifications::Event.new(event_name, started, finished, event_id, payload)
22
24
 
@@ -33,9 +35,13 @@ module RailsPerformance
33
35
  path: event.payload[:path],
34
36
  view_runtime: event.payload[:view_runtime],
35
37
  db_runtime: event.payload[:db_runtime],
36
- duration: event.duration
38
+ duration: event.duration,
39
+ exception: event.payload[:exception],
40
+ exception_object: event.payload[:exception_object]
37
41
  }
38
42
 
43
+ # pass the record to Thread.current
44
+ # and saves later in middleware
39
45
  CurrentRequest.current.data = record
40
46
  end
41
47
  end
@@ -3,14 +3,15 @@ module RailsPerformance
3
3
  class RequestRecord < BaseRecord
4
4
  attr_accessor :controller, :action, :format, :status, :datetime, :datetimei, :method, :path, :request_id, :json
5
5
  attr_accessor :view_runtime, :db_runtime, :duration, :http_referer
6
+ attr_accessor :exception, :exception_object
6
7
 
7
8
  def RequestRecord.find_by(request_id:)
8
- keys, values = RP::Utils.fetch_from_redis("performance|*|request_id|#{request_id}|*")
9
+ keys, values = RailsPerformance::Utils.fetch_from_redis("performance|*|request_id|#{request_id}|*")
9
10
 
10
11
  return nil if keys.blank?
11
12
  return nil if values.blank?
12
13
 
13
- RP::Models::RequestRecord.from_db(keys[0], values[0])
14
+ RailsPerformance::Models::RequestRecord.from_db(keys[0], values[0])
14
15
  end
15
16
 
16
17
  # key = performance|
@@ -24,7 +25,7 @@ module RailsPerformance
24
25
  # path|/|
25
26
  # request_id|454545454545454545|
26
27
  # END|1.0.0
27
- # = {"view_runtime":8.444603008683771,"db_runtime":0,"duration":9.216095000000001}
28
+ # = {"view_runtime":null,"db_runtime":0,"duration":27.329741000000002,"http_referer":null,"exception":"ZeroDivisionError divided by 0","backtrace":["/root/projects/rails_performance/test/dummy/app/controllers/account/site_controller.rb:17:in `/'","/root/projects/rails_performance/test/dummy/app/controllers/account/site_controller.rb:17:in `crash'","/usr/local/rvm/gems/ruby-2.6.3/gems/actionpack-6.1.3.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'"]}
28
29
  # value = JSON
29
30
  def RequestRecord.from_db(key, value)
30
31
  items = key.split("|")
@@ -43,7 +44,7 @@ module RailsPerformance
43
44
  )
44
45
  end
45
46
 
46
- def initialize(controller:, action:, format:, status:, datetime:, datetimei:, method:, path:, request_id:, view_runtime: nil, db_runtime: nil, duration: nil, http_referer: nil, json: '{}')
47
+ def initialize(controller:, action:, format:, status:, datetime:, datetimei:, method:, path:, request_id:, view_runtime: nil, db_runtime: nil, duration: nil, http_referer: nil, exception: nil, exception_object: nil, json: '{}')
47
48
  @controller = controller
48
49
  @action = action
49
50
  @format = format
@@ -59,6 +60,9 @@ module RailsPerformance
59
60
  @duration = duration
60
61
  @http_referer = http_referer
61
62
 
63
+ @exception = Array.wrap(exception).compact.join(" ")
64
+ @exception_object = exception_object
65
+
62
66
  @json = json
63
67
  end
64
68
 
@@ -84,12 +88,21 @@ module RailsPerformance
84
88
  duration: self.value['duration'],
85
89
  db_runtime: self.value['db_runtime'],
86
90
  view_runtime: self.value['view_runtime'],
91
+ exception: self.value['exception'],
92
+ backtrace: self.value['backtrace']
87
93
  }
88
94
  end
89
95
 
90
96
  def save
91
- value = { view_runtime: view_runtime, db_runtime: db_runtime, duration: duration, http_referer: http_referer }
92
97
  key = "performance|controller|#{controller}|action|#{action}|format|#{format}|status|#{status}|datetime|#{datetime}|datetimei|#{datetimei}|method|#{method}|path|#{path}|request_id|#{request_id}|END|#{RailsPerformance::SCHEMA}"
98
+ value = {
99
+ view_runtime: view_runtime,
100
+ db_runtime: db_runtime,
101
+ duration: duration,
102
+ http_referer: http_referer,
103
+ }
104
+ value[:exception] = exception if exception.present?
105
+ value[:backtrace] = exception_object.backtrace.take(3) if exception_object
93
106
  Utils.save_to_redis(key, value)
94
107
  end
95
108
 
@@ -9,7 +9,7 @@ module RailsPerformance
9
9
 
10
10
  def data
11
11
  key = "trace|#{request_id}|END|#{RailsPerformance::SCHEMA}"
12
- JSON.parse(RP.redis.get(key).presence || '[]')
12
+ JSON.parse(RailsPerformance.redis.get(key).presence || '[]')
13
13
  end
14
14
  end
15
15
 
@@ -1,4 +1,4 @@
1
1
  module RailsPerformance
2
- VERSION = '1.0.0.beta2'
3
- SCHEMA = '1.0.0'
2
+ VERSION = '1.0.1'
3
+ SCHEMA = '1.0.1'
4
4
  end
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.0.beta2
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-21 00:00:00.000000000 Z
11
+ date: 2021-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -266,11 +266,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
266
266
  version: '0'
267
267
  required_rubygems_version: !ruby/object:Gem::Requirement
268
268
  requirements:
269
- - - ">"
269
+ - - ">="
270
270
  - !ruby/object:Gem::Version
271
- version: 1.3.1
271
+ version: '0'
272
272
  requirements: []
273
- rubygems_version: 3.2.3
273
+ rubygems_version: 3.0.3
274
274
  signing_key:
275
275
  specification_version: 4
276
276
  summary: Simple Rails Performance tracker. Alternative to the NewRelic, Datadog or