rails_performance 0.0.1.15 → 0.0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b34ea6487b91922afd52e68bbd16cb1b5c4b40abd319331d99582b1f9ce582a8
4
- data.tar.gz: 1ced2dab20079d409e3f16d4d87b551d732ab7cd793cbc53a3ff2f9aa7f407ba
3
+ metadata.gz: 2976dbd35d4929faa65ab1779fc84bdd8fbdaff9468c362db1cbe99d40d8067d
4
+ data.tar.gz: 2aba4eae55dec21500dcef2ab3fb80ddf3ff06858ab074d4f250e945603f84f2
5
5
  SHA512:
6
- metadata.gz: 4fe53e913ddfb6a592022040537f6633edbb9ade17e021b2533d3095092a23cfecd127f8ec6d819e7566854c8f4cc4e0562b88717ef2ab61ec6f6d3ff0bd0838
7
- data.tar.gz: 197b952a0d4144e01da79ed1315dab76adda1568f3078424c05f6c0b035196c7a827bd2d5d5384b23f8105eb5e93970772afaec59ba2b60d25bbddafffe60a2d
6
+ metadata.gz: fadbdb32d306a26c160c83c3e7976dc72b83665a98d2ceff97b36681258103f93fffcf12eff1124717c3e81207b9650addcdfbf3fbc2c413b86cd50d17376a15
7
+ data.tar.gz: e20f2d4a84a65299beff4b3d489db1af59c2dab792330ff8bacb7997970a159efeb4598ef15a8758b930c6eef3d3e7651239cb761844510b41c107f7b80f07ac
data/README.md CHANGED
@@ -25,7 +25,7 @@ Create `config/initializers/rails_performance.rb`
25
25
  ```ruby
26
26
  RailsPerformance.setup do |config|
27
27
  config.redis = Redis::Namespace.new("#{Rails.env}-rails-performance", redis: Redis.new)
28
- config.duration = 24.hours
28
+ config.duration = 4.hours
29
29
 
30
30
  config.debug = false # currently not used>
31
31
  config.enabled = true
@@ -106,6 +106,11 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
106
106
  - monitor active job (sidekiq)?
107
107
  - logo?
108
108
  - number of requests last 24 hours, hour, etc.
109
+ - integration with logger, to see the details of request?
110
+ - no results if empty table (on crash page)
111
+ - capture referal for 404 page?
112
+ - SQL
113
+ - Rendering
109
114
 
110
115
  ## Contributing
111
116
 
@@ -1,6 +1,7 @@
1
1
  class BaseController < ActionController::Base
2
2
  layout 'rails_performance/layouts/rails_performance'
3
3
 
4
+ before_action :leave_finger_print
4
5
  before_action :verify_access
5
6
 
6
7
  if RailsPerformance.http_basic_authentication_enabled
@@ -11,6 +12,10 @@ class BaseController < ActionController::Base
11
12
 
12
13
  private
13
14
 
15
+ def leave_finger_print
16
+ Thread.current[:in_rails_performance] = true
17
+ end
18
+
14
19
  def verify_access
15
20
  result = RailsPerformance.verify_access_proc.call(self)
16
21
  redirect_to('/', error: 'Access Denied', status: 401) unless result
@@ -33,6 +33,15 @@ class RailsPerformanceController < BaseController
33
33
  end
34
34
  end
35
35
 
36
+ def trace
37
+ @report = RP::Reports::TraceReport.new(request_id: params[:id])
38
+ @data = @report.data
39
+ respond_to do |format|
40
+ format.js {}
41
+ format.any { render plain: "Doesn't open in new window" }
42
+ end
43
+ end
44
+
36
45
  def crashes
37
46
  @datasource = RP::DataSource.new(prepare_query({status_eq: 500}))
38
47
  db = @datasource.db
@@ -0,0 +1,21 @@
1
+ <table class="table is-fullwidth is-hoverable is-narrow is-size-7">
2
+ <tbody>
3
+ <% @data.each do |e| %>
4
+ <tr>
5
+ <td><%= e["group"] %></td>
6
+ <% if e["group"] == 'db' %>
7
+ <td>
8
+ <%= e["duration"] %> ms
9
+ </td>
10
+ <td>
11
+ <%= e["sql"] %>
12
+ </td>
13
+ <% elsif e["group"] == 'view' %>
14
+ <td colspan="2">
15
+ <%= e["message"] %>
16
+ </td>
17
+ <% end %>
18
+ </tr>
19
+ <% end %>
20
+ </tbody>
21
+ </table>
@@ -15,6 +15,7 @@
15
15
  <th data-sort="float">Duration</th>
16
16
  <th data-sort="float">Views</th>
17
17
  <th data-sort="float">DB</th>
18
+ <th></th>
18
19
  </tr>
19
20
  </thead>
20
21
  <tbody>
@@ -29,6 +30,11 @@
29
30
  <td><%= ms e[:duration] %></td>
30
31
  <td><%= ms e[:view_runtime] %></td>
31
32
  <td><%= ms e[:db_runtime] %></td>
33
+ <td>
34
+ <%= link_to rails_performance.rails_performance_trace_path(id: e[:request_id]), remote: true do %>
35
+ <span class="stats_icon_max"><%= icon 'activity' %></span>
36
+ <% end %>
37
+ </td>
32
38
  </tr>
33
39
  <% end %>
34
40
  </tbody>
@@ -41,6 +41,11 @@
41
41
  height: 16px;
42
42
  }
43
43
 
44
+ .stats_icon_max svg {
45
+ width: 24px;
46
+ height: 24px;
47
+ }
48
+
44
49
  .home_icon svg {
45
50
  width: 24px;
46
51
  height: 24px;
@@ -0,0 +1,4 @@
1
+ window.panel.header.html(window.panel.close);
2
+ window.panel.content.html("<%= j render '/rails_performance/trace' %>");
3
+
4
+ showPanel();
data/config/routes.rb CHANGED
@@ -5,6 +5,7 @@ RailsPerformance::Engine.routes.draw do
5
5
  get '/crashes' => 'rails_performance#crashes', as: :rails_performance_crashes
6
6
  get '/recent' => 'rails_performance#recent', as: :rails_performance_recent
7
7
 
8
+ get '/trace/:id' => 'rails_performance#trace', as: :rails_performance_trace
8
9
  get '/summary' => 'rails_performance#summary', as: :rails_performance_summary
9
10
  end
10
11
 
@@ -13,8 +13,9 @@ require_relative "rails_performance/reports/response_time_report.rb"
13
13
  require_relative "rails_performance/reports/throughput_report.rb"
14
14
  require_relative "rails_performance/reports/recent_requests_report.rb"
15
15
  require_relative "rails_performance/reports/breakdown_report.rb"
16
-
17
- require "rails_performance/engine"
16
+ require_relative "rails_performance/reports/trace_report.rb"
17
+ require_relative "rails_performance/extensions/capture_everything.rb"
18
+ require_relative "rails_performance/models/current_request.rb"
18
19
 
19
20
  module RailsPerformance
20
21
  FORMAT = "%Y%m%dT%H%M"
@@ -23,7 +24,7 @@ module RailsPerformance
23
24
  @@redis = Redis::Namespace.new("#{::Rails.env}-rails-performance", redis: Redis.new)
24
25
 
25
26
  mattr_accessor :duration
26
- @@duration = 24.hours
27
+ @@duration = 4.hours
27
28
 
28
29
  mattr_accessor :debug
29
30
  @@debug = false
@@ -53,4 +54,6 @@ module RailsPerformance
53
54
 
54
55
  end
55
56
 
56
- RP = RailsPerformance
57
+ RP = RailsPerformance
58
+
59
+ require "rails_performance/engine"
@@ -5,21 +5,20 @@ require_relative './instrument/metrics_collector.rb'
5
5
  module RailsPerformance
6
6
  class Engine < ::Rails::Engine
7
7
 
8
- #config.app_middleware.use RailsPerformance::Middleware
9
- config.app_middleware.insert_after ActionDispatch::Executor, RailsPerformance::Rails::Middleware
8
+ if RailsPerformance.enabled
9
+ config.app_middleware.insert_after ActionDispatch::Executor, RailsPerformance::Rails::Middleware
10
+ initializer :configure_metrics, after: :initialize_logger do
11
+ ActiveSupport::Notifications.subscribe(
12
+ "process_action.action_controller",
13
+ RailsPerformance::Instrument::MetricsCollector.new
14
+ )
10
15
 
11
- initializer :configure_metrics, after: :initialize_logger do
12
- ActiveSupport::Notifications.subscribe(
13
- "process_action.action_controller",
14
- RailsPerformance::Instrument::MetricsCollector.new
15
- )
16
+ config.after_initialize do |app|
17
+ ActionView::LogSubscriber.send :prepend, RailsPerformance::Extensions::View
18
+ ActiveRecord::LogSubscriber.send :prepend, RailsPerformance::Extensions::Db
19
+ end
20
+ end
16
21
  end
17
22
 
18
- # initializer 'rails_performance.helpers' do
19
- # ActiveSupport.on_load :action_view do
20
- # ActionView::Base.send :include, RailsPerformance::RailsPerformanceHelper
21
- # end
22
- # end
23
-
24
23
  end
25
24
  end
@@ -0,0 +1,33 @@
1
+ module RailsPerformance
2
+ module Extensions
3
+ module View
4
+
5
+ def info(&block)
6
+ CurrentRequest.current.store({
7
+ group: :view,
8
+ message: block.call
9
+ })
10
+ super(&block)
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+
17
+ module RailsPerformance
18
+ module Extensions
19
+ module Db
20
+
21
+ def sql(event)
22
+ CurrentRequest.current.store({
23
+ group: :db,
24
+ duration: event.duration.round(2),
25
+ sql: event.payload[:sql]
26
+ })
27
+ super(event)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,27 @@
1
+ module RailsPerformance
2
+ class CurrentRequest
3
+ attr_reader :request_id, :storage
4
+
5
+ def CurrentRequest.init
6
+ Thread.current[:rp_current_request] ||= CurrentRequest.new(SecureRandom.hex(16))
7
+ end
8
+
9
+ def CurrentRequest.current
10
+ CurrentRequest.init
11
+ end
12
+
13
+ def CurrentRequest.cleanup
14
+ Thread.current[:rp_current_request] = nil
15
+ end
16
+
17
+ def initialize(request_id)
18
+ @request_id = request_id
19
+ @storage = []
20
+ end
21
+
22
+ def store(options = {})
23
+ @storage << options.merge(time: Time.now.to_i)
24
+ end
25
+
26
+ end
27
+ end
@@ -1,7 +1,7 @@
1
1
  module RailsPerformance
2
2
  module Models
3
3
  class Record
4
- attr_reader :controller, :action, :format, :status, :datetime, :datetimei, :method, :path
4
+ attr_reader :controller, :action, :format, :status, :datetime, :datetimei, :method, :path, :request_id
5
5
 
6
6
  # key = performance|
7
7
  # controller|HomeController|
@@ -12,6 +12,7 @@ module RailsPerformance
12
12
  # datetimei|1579861423|
13
13
  # method|GET|
14
14
  # path|/|
15
+ # request_id|454545454545454545|
15
16
  # END
16
17
  # = {"view_runtime":8.444603008683771,"db_runtime":0,"duration":9.216095000000001}
17
18
  # value = JSON
@@ -28,6 +29,7 @@ module RailsPerformance
28
29
  @datetimei = items[12]
29
30
  @method = items[14]
30
31
  @path = items[16]
32
+ @request_id = items[18]
31
33
  end
32
34
 
33
35
  def value
@@ -8,8 +8,9 @@ module RailsPerformance
8
8
  def call(env)
9
9
  @status, @headers, @response = @app.call(env)
10
10
 
11
- if record = Thread.current["RP_request_info"]
12
- record[:status] ||= @status
11
+ if !Thread.current[:in_rails_performance] && record = Thread.current["RP_request_info"]
12
+ record[:status] ||= @status
13
+ record[:request_id] = CurrentRequest.current.request_id
13
14
 
14
15
  # rand(500).times do |e|
15
16
  # finished = Time.now - rand(2000).minutes
@@ -18,12 +19,13 @@ module RailsPerformance
18
19
  # record[:duration] = 50 + rand(100) + rand(50.0) + rand(e)
19
20
  # record[:db_runtime] = rand(50.0)
20
21
  # record[:view_runtime] = rand(50.0)
21
- # RP::Utils.log_in_redis(record)
22
+ # RP::Utils.log_request_in_redis(record)
22
23
  # end
23
24
 
24
- RP::Utils.log_in_redis(record)
25
-
25
+ RP::Utils.log_trace_in_redis(CurrentRequest.current.request_id, CurrentRequest.current.storage)
26
+ RP::Utils.log_request_in_redis(record)
26
27
  Thread.current["RP_request_info"] = nil
28
+ CurrentRequest.cleanup
27
29
  end
28
30
 
29
31
  [@status, @headers, @response]
@@ -1,7 +1,7 @@
1
1
  module RailsPerformance
2
2
  module Reports
3
3
  class RecentRequestsReport < BaseReport
4
- TIME_WINDOW = 60 # 60 minutes
4
+ TIME_WINDOW = 60.minutes
5
5
 
6
6
  def set_defaults
7
7
  @sort ||= :datetime
@@ -16,13 +16,14 @@ module RailsPerformance
16
16
  status: record.status,
17
17
  method: record.method,
18
18
  path: record.path,
19
+ request_id: record.request_id,
19
20
  datetime: Time.at(record.datetimei.to_i),
20
21
  duration: record.value['duration'],
21
22
  db_runtime: record.value['db_runtime'],
22
23
  view_runtime: record.value['view_runtime'],
23
24
  }
24
25
  end
25
- .select{|e| e if e[:datetime] >= TIME_WINDOW.minutes.ago}
26
+ .select{|e| e if e[:datetime] >= TIME_WINDOW.ago}
26
27
  .sort{|a, b| b[sort] <=> a[sort]}
27
28
  end
28
29
  end
@@ -0,0 +1,18 @@
1
+ module RailsPerformance
2
+ module Reports
3
+ class TraceReport
4
+ attr_reader :request_id
5
+
6
+ def initialize(request_id:)
7
+ @request_id = request_id
8
+ end
9
+
10
+ def data
11
+ key = "trace|#{request_id}"
12
+ JSON.parse(RP.redis.get(key).presence || '[]')
13
+ end
14
+ end
15
+
16
+
17
+ end
18
+ end
@@ -12,9 +12,9 @@ module RailsPerformance
12
12
  now.strftime("%H:%M")
13
13
  end
14
14
 
15
- def Utils.log_in_redis(e)
15
+ def Utils.log_request_in_redis(e)
16
16
  value = e.slice(:view_runtime, :db_runtime, :duration)
17
- key = "performance|controller|#{e[:controller]}|action|#{e[:action]}|format|#{e[:format]}|status|#{e[:status]}|datetime|#{e[:datetime]}|datetimei|#{e[:datetimei]}|method|#{e[:method]}|path|#{e[:path]}|END"
17
+ key = "performance|controller|#{e[:controller]}|action|#{e[:action]}|format|#{e[:format]}|status|#{e[:status]}|datetime|#{e[:datetime]}|datetimei|#{e[:datetimei]}|method|#{e[:method]}|path|#{e[:path]}|request_id|#{e[:request_id]}|END"
18
18
 
19
19
  # puts " [SAVE] key ---> #{key}\n"
20
20
  # puts " value ---> #{value.to_json}\n\n"
@@ -25,6 +25,17 @@ module RailsPerformance
25
25
  true
26
26
  end
27
27
 
28
+ def Utils.log_trace_in_redis(request_id, value)
29
+ key = "trace|#{request_id}"
30
+
31
+ # puts " [SAVE] key ---> #{key}\n"
32
+ # puts " value ---> #{value.to_json}\n\n"
33
+ # pp value
34
+
35
+ RP.redis.set(key, value.to_json)
36
+ RP.redis.expire(key, RailsPerformance::Reports::RecentRequestsReport::TIME_WINDOW.to_i)
37
+ end
38
+
28
39
  def Utils.fetch_from_redis(query)
29
40
  #puts "\n\n [REDIS QUERY] --> #{query}\n\n"
30
41
 
@@ -1,3 +1,3 @@
1
1
  module RailsPerformance
2
- VERSION = '0.0.1.15'
2
+ VERSION = '0.0.1.16'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.15
4
+ version: 0.0.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
@@ -105,6 +105,7 @@ files:
105
105
  - app/helpers/rails_performance_helper.rb
106
106
  - app/views/rails_performance/_panel.html.erb
107
107
  - app/views/rails_performance/_summary.html.erb
108
+ - app/views/rails_performance/_trace.html.erb
108
109
  - app/views/rails_performance/crashes.html.erb
109
110
  - app/views/rails_performance/index.html.erb
110
111
  - app/views/rails_performance/javascripts/_javascripts.html.erb
@@ -123,12 +124,15 @@ files:
123
124
  - app/views/rails_performance/stylesheets/panel.css
124
125
  - app/views/rails_performance/stylesheets/style.css
125
126
  - app/views/rails_performance/summary.js.erb
127
+ - app/views/rails_performance/trace.js.erb
126
128
  - config/routes.rb
127
129
  - lib/rails_performance.rb
128
130
  - lib/rails_performance/data_source.rb
129
131
  - lib/rails_performance/engine.rb
132
+ - lib/rails_performance/extensions/capture_everything.rb
130
133
  - lib/rails_performance/instrument/metrics_collector.rb
131
134
  - lib/rails_performance/models/collection.rb
135
+ - lib/rails_performance/models/current_request.rb
132
136
  - lib/rails_performance/models/record.rb
133
137
  - lib/rails_performance/rails/middleware.rb
134
138
  - lib/rails_performance/rails/query_builder.rb
@@ -139,6 +143,7 @@ files:
139
143
  - lib/rails_performance/reports/requests_report.rb
140
144
  - lib/rails_performance/reports/response_time_report.rb
141
145
  - lib/rails_performance/reports/throughput_report.rb
146
+ - lib/rails_performance/reports/trace_report.rb
142
147
  - lib/rails_performance/utils.rb
143
148
  - lib/rails_performance/version.rb
144
149
  homepage: https://github.com/igorkasyanchuk/rails_performance
@@ -160,8 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
165
  - !ruby/object:Gem::Version
161
166
  version: '0'
162
167
  requirements: []
163
- rubyforge_project:
164
- rubygems_version: 2.7.6.2
168
+ rubygems_version: 3.0.6
165
169
  signing_key:
166
170
  specification_version: 4
167
171
  summary: Track number of requests to your app