rails_performance 0.0.1.15 → 0.0.1.16

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: 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