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 +4 -4
- data/README.md +6 -1
- data/app/controllers/base_controller.rb +5 -0
- data/app/controllers/rails_performance_controller.rb +9 -0
- data/app/views/rails_performance/_trace.html.erb +21 -0
- data/app/views/rails_performance/recent.html.erb +6 -0
- data/app/views/rails_performance/stylesheets/style.css +5 -0
- data/app/views/rails_performance/trace.js.erb +4 -0
- data/config/routes.rb +1 -0
- data/lib/rails_performance.rb +7 -4
- data/lib/rails_performance/engine.rb +12 -13
- data/lib/rails_performance/extensions/capture_everything.rb +33 -0
- data/lib/rails_performance/models/current_request.rb +27 -0
- data/lib/rails_performance/models/record.rb +3 -1
- data/lib/rails_performance/rails/middleware.rb +7 -5
- data/lib/rails_performance/reports/recent_requests_report.rb +3 -2
- data/lib/rails_performance/reports/trace_report.rb +18 -0
- data/lib/rails_performance/utils.rb +13 -2
- data/lib/rails_performance/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2976dbd35d4929faa65ab1779fc84bdd8fbdaff9468c362db1cbe99d40d8067d
|
4
|
+
data.tar.gz: 2aba4eae55dec21500dcef2ab3fb80ddf3ff06858ab074d4f250e945603f84f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =
|
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>
|
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
|
|
data/lib/rails_performance.rb
CHANGED
@@ -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
|
-
|
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 =
|
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
|
-
|
9
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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]
|
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.
|
22
|
+
# RP::Utils.log_request_in_redis(record)
|
22
23
|
# end
|
23
24
|
|
24
|
-
RP::Utils.
|
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
|
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.
|
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.
|
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
|
|
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.
|
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
|
-
|
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
|