rails_performance 0.0.1.19 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -19
- data/app/controllers/rails_performance_controller.rb +1 -0
- data/app/helpers/rails_performance_helper.rb +27 -2
- data/app/views/rails_performance/_trace.html.erb +7 -4
- data/app/views/rails_performance/crashes.html.erb +6 -0
- data/app/views/rails_performance/recent.html.erb +6 -1
- data/app/views/rails_performance/trace.js.erb +6 -1
- data/lib/rails_performance/engine.rb +5 -1
- data/lib/rails_performance/instrument/metrics_collector.rb +3 -1
- data/lib/rails_performance/models/current_request.rb +2 -0
- data/lib/rails_performance/models/record.rb +35 -0
- data/lib/rails_performance/rails/middleware.rb +14 -3
- data/lib/rails_performance/utils.rb +1 -1
- data/lib/rails_performance/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe073c7658af65303c6efc61dbaa973edba22d21c2991e715d523b6f4c96dc5f
|
4
|
+
data.tar.gz: bf7780ef55eab59d2974b990eba4e2afad26b78683f685fb8383b4df4d8ada30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b223eb60dc1dc48c64a577d39d2bf34073ff916d0b73ad5f507a74bedc0f9a2aa5af5cc33ec9bc063b12cc441a572f99d4e8c68362935f74f2f9084c6d8b6ca0
|
7
|
+
data.tar.gz: 7b030743ca075f02c38b4448ec0c1ad369a09d094dc381aba5c834c40ee245ccfe9511c939fa7d08e0e42d253c9b06817d4b6bc7d80c6b9d5f8bab7835472e7e
|
data/README.md
CHANGED
@@ -6,11 +6,12 @@ This is **simple and free alternative** to New Relic, Datadog or other similar s
|
|
6
6
|
|
7
7
|
It allows you to track:
|
8
8
|
|
9
|
-
- throughput report (see amount of requests per minute)
|
9
|
+
- throughput report (see amount of RPM (requests per minute))
|
10
10
|
- an average response time
|
11
11
|
- the slowest controllers & actions
|
12
|
-
- duration of
|
13
|
-
-
|
12
|
+
- total duration of time spent per request, views rendering, DB
|
13
|
+
- SQL queries, rendering log in recent requests
|
14
|
+
- simple 500-crashes reports
|
14
15
|
|
15
16
|
All data is stored in local Redis and not sent to 3rd party servers.
|
16
17
|
|
@@ -83,6 +84,8 @@ Like a regular web development.
|
|
83
84
|
|
84
85
|
Please note that to simplify integration with other apps all CSS/JS are bundled inside, and delivered in body of the request. This is to avoid integration with assets pipeline or webpacker.
|
85
86
|
|
87
|
+
For UI changes you need to use Bulma CSS (https://bulma.io/documentation).
|
88
|
+
|
86
89
|
## Why
|
87
90
|
|
88
91
|
The idea of this gem grew from curriosity how many RPM my app receiving per day. Later it evolutionated to something more powerful.
|
@@ -91,27 +94,20 @@ The idea of this gem grew from curriosity how many RPM my app receiving per day.
|
|
91
94
|
|
92
95
|
- documentation in Readme
|
93
96
|
- generator for initial config
|
94
|
-
- gif with demo
|
95
|
-
- time/zone config?
|
96
97
|
- CI for tests
|
97
|
-
-
|
98
|
-
-
|
99
|
-
-
|
98
|
+
- time/zone config?
|
99
|
+
- connected charts on dashboard, when zoom, when hover?
|
100
|
+
- ability to zoom to see requests withing specific datetime range
|
101
|
+
- better hints?
|
100
102
|
- export to csv
|
101
|
-
- http basic auth config
|
102
|
-
- current_user auth config
|
103
103
|
- better stats tooltip, do not show if nothing to show
|
104
|
-
- dark mode toggle? save to the cookies
|
105
|
-
- integration with elastic search
|
104
|
+
- dark mode toggle? save to the cookies?
|
105
|
+
- integration with elastic search? or other?
|
106
106
|
- monitor active job (sidekiq)?
|
107
|
-
- logo?
|
107
|
+
- better logo?
|
108
108
|
- number of requests last 24 hours, hour, etc.
|
109
|
-
-
|
110
|
-
-
|
111
|
-
- capture referal for 404 page?
|
112
|
-
- SQL
|
113
|
-
- Rendering
|
114
|
-
- scroll to the top details
|
109
|
+
- collect deprecation.rails
|
110
|
+
- fix misspellings?
|
115
111
|
|
116
112
|
## Contributing
|
117
113
|
|
@@ -6,6 +6,29 @@ module RailsPerformanceHelper
|
|
6
6
|
value.nan? ? nil : value.round(1)
|
7
7
|
end
|
8
8
|
|
9
|
+
def duraction_alert_class(duration_str)
|
10
|
+
if duration_str.to_s =~ /(\d+.?\d+?)/
|
11
|
+
duration = $1.to_f
|
12
|
+
if duration >= 100
|
13
|
+
'has-background-danger has-text-white-bis'
|
14
|
+
elsif duration >= 200
|
15
|
+
'has-background-warning has-text-black-ter'
|
16
|
+
else
|
17
|
+
'has-background-success has-text-white-bis'
|
18
|
+
end
|
19
|
+
else
|
20
|
+
'has-background-light'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def extract_duration(str)
|
25
|
+
if (str =~ /Duration: (\d+.?\d+?ms)/i)
|
26
|
+
$1
|
27
|
+
else
|
28
|
+
'-'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
9
32
|
def ms(value)
|
10
33
|
result = round_it(value)
|
11
34
|
result && result != 0 ? "#{result} ms" : '-'
|
@@ -27,14 +50,16 @@ module RailsPerformanceHelper
|
|
27
50
|
|
28
51
|
def report_name(h)
|
29
52
|
h.except(:on).collect do |k, v|
|
53
|
+
next if v.blank?
|
54
|
+
|
30
55
|
%Q{
|
31
56
|
<div class="control">
|
32
57
|
<span class="tags has-addons">
|
33
58
|
<span class="tag">#{k}</span>
|
34
|
-
<span class="tag is-
|
59
|
+
<span class="tag is-info is-light">#{v}</span>
|
35
60
|
</span>
|
36
61
|
</div>}
|
37
|
-
end.join.html_safe
|
62
|
+
end.compact.join.html_safe
|
38
63
|
end
|
39
64
|
|
40
65
|
def status_tag(status)
|
@@ -2,16 +2,17 @@
|
|
2
2
|
<tbody>
|
3
3
|
<% @data.each do |e| %>
|
4
4
|
<tr>
|
5
|
-
<td><%= e["group"] %></td>
|
6
5
|
<% if e["group"] == 'db' %>
|
7
|
-
<td class="nowrap">
|
6
|
+
<td class="nowrap has-text-right <%= duraction_alert_class(e['duration']) %>">
|
8
7
|
<%= e["duration"] %> ms
|
9
8
|
</td>
|
10
9
|
<td>
|
11
10
|
<%= e["sql"] %>
|
12
11
|
</td>
|
13
12
|
<% elsif e["group"] == 'view' %>
|
14
|
-
<td
|
13
|
+
<td class="nowrap has-text-right <%= duraction_alert_class(extract_duration(e['message'])) %>">
|
14
|
+
<%= extract_duration(e["message"]) %>
|
15
|
+
</td>
|
15
16
|
<td>
|
16
17
|
<%= e["message"] %>
|
17
18
|
</td>
|
@@ -19,4 +20,6 @@
|
|
19
20
|
</tr>
|
20
21
|
<% end %>
|
21
22
|
</tbody>
|
22
|
-
</table>
|
23
|
+
</table>
|
24
|
+
|
25
|
+
<br/>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="card">
|
2
2
|
<div class="card-content">
|
3
3
|
|
4
|
-
<h2 class="subtitle">Recent Requests (last <%= RailsPerformance::Reports::RecentRequestsReport::TIME_WINDOW %> minutes)<h2>
|
4
|
+
<h2 class="subtitle">Recent Requests (last <%= RailsPerformance::Reports::RecentRequestsReport::TIME_WINDOW / 60 %> minutes)<h2>
|
5
5
|
|
6
6
|
<table class="table is-fullwidth is-hoverable is-narrow">
|
7
7
|
<thead>
|
@@ -19,6 +19,11 @@
|
|
19
19
|
</tr>
|
20
20
|
</thead>
|
21
21
|
<tbody>
|
22
|
+
<% if @data.empty? %>
|
23
|
+
<tr>
|
24
|
+
<td colspan="10">Nothing to show here. Try to make a few requests in main app.</td>
|
25
|
+
</tr>
|
26
|
+
<% end %>
|
22
27
|
<% @data.each do |e| %>
|
23
28
|
<tr>
|
24
29
|
<td><%= format_datetime e[:datetime] %></td>
|
@@ -1,4 +1,9 @@
|
|
1
|
-
|
1
|
+
<% if @record %>
|
2
|
+
window.panel.header.html(window.panel.close + "<%= j report_name(@record.to_h) %>");
|
3
|
+
<% else %>
|
4
|
+
window.panel.header.html(window.panel.close);
|
5
|
+
<% end %>
|
6
|
+
|
2
7
|
window.panel.content.html("<%= j render '/rails_performance/trace' %>");
|
3
8
|
|
4
9
|
showPanel();
|
@@ -5,8 +5,10 @@ require_relative './instrument/metrics_collector.rb'
|
|
5
5
|
module RailsPerformance
|
6
6
|
class Engine < ::Rails::Engine
|
7
7
|
|
8
|
-
if RailsPerformance.enabled
|
8
|
+
if RailsPerformance.try(:enabled) # for rails c
|
9
|
+
|
9
10
|
config.app_middleware.insert_after ActionDispatch::Executor, RailsPerformance::Rails::Middleware
|
11
|
+
|
10
12
|
initializer :configure_metrics, after: :initialize_logger do
|
11
13
|
ActiveSupport::Notifications.subscribe(
|
12
14
|
"process_action.action_controller",
|
@@ -17,7 +19,9 @@ module RailsPerformance
|
|
17
19
|
ActionView::LogSubscriber.send :prepend, RailsPerformance::Extensions::View
|
18
20
|
ActiveRecord::LogSubscriber.send :prepend, RailsPerformance::Extensions::Db
|
19
21
|
end
|
22
|
+
|
20
23
|
end
|
24
|
+
|
21
25
|
end
|
22
26
|
|
23
27
|
end
|
@@ -18,6 +18,8 @@ module RailsPerformance
|
|
18
18
|
def call(event_name, started, finished, event_id, payload)
|
19
19
|
event = ActiveSupport::Notifications::Event.new(event_name, started, finished, event_id, payload)
|
20
20
|
|
21
|
+
return if event.payload[:path] =~ /^\/rails\/performance/
|
22
|
+
|
21
23
|
record = {
|
22
24
|
controller: event.payload[:controller],
|
23
25
|
action: event.payload[:action],
|
@@ -32,7 +34,7 @@ module RailsPerformance
|
|
32
34
|
duration: event.duration
|
33
35
|
}
|
34
36
|
|
35
|
-
|
37
|
+
CurrentRequest.current.record = record
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module RailsPerformance
|
2
2
|
class CurrentRequest
|
3
3
|
attr_reader :request_id, :storage
|
4
|
+
attr_accessor :record
|
4
5
|
|
5
6
|
def CurrentRequest.init
|
6
7
|
Thread.current[:rp_current_request] ||= CurrentRequest.new(SecureRandom.hex(16))
|
@@ -17,6 +18,7 @@ module RailsPerformance
|
|
17
18
|
def initialize(request_id)
|
18
19
|
@request_id = request_id
|
19
20
|
@storage = []
|
21
|
+
@record = nil
|
20
22
|
end
|
21
23
|
|
22
24
|
def store(options = {})
|
@@ -3,6 +3,16 @@ module RailsPerformance
|
|
3
3
|
class Record
|
4
4
|
attr_reader :controller, :action, :format, :status, :datetime, :datetimei, :method, :path, :request_id
|
5
5
|
|
6
|
+
|
7
|
+
def Record.find_by(request_id:)
|
8
|
+
keys, values = RP::Utils.fetch_from_redis("performance|*|request_id|#{request_id}|*")
|
9
|
+
|
10
|
+
return nil if keys.blank?
|
11
|
+
return nil if values.blank?
|
12
|
+
|
13
|
+
RP::Models::Record.new(keys[0], values[0])
|
14
|
+
end
|
15
|
+
|
6
16
|
# key = performance|
|
7
17
|
# controller|HomeController|
|
8
18
|
# action|index|
|
@@ -43,6 +53,31 @@ module RailsPerformance
|
|
43
53
|
def controller_action_format
|
44
54
|
"#{controller}##{action}|#{format}"
|
45
55
|
end
|
56
|
+
|
57
|
+
def to_h
|
58
|
+
{
|
59
|
+
controller: controller,
|
60
|
+
action: action,
|
61
|
+
format: format,
|
62
|
+
method: method,
|
63
|
+
path: path,
|
64
|
+
duration: ms(value['duration']),
|
65
|
+
view_runtime: ms(value['view_runtime']),
|
66
|
+
db_runtime: ms(value['db_runtime']),
|
67
|
+
HTTP_REFERER: value['HTTP_REFERER']
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def ms(e)
|
74
|
+
if e
|
75
|
+
e.to_f.round(1).to_s + " ms"
|
76
|
+
else
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
46
81
|
end
|
47
82
|
end
|
48
83
|
end
|
@@ -8,17 +8,28 @@ module RailsPerformance
|
|
8
8
|
def call(env)
|
9
9
|
@status, @headers, @response = @app.call(env)
|
10
10
|
|
11
|
-
|
11
|
+
#t = Time.now
|
12
|
+
if record = CurrentRequest.current.record
|
12
13
|
begin
|
13
|
-
record[:status] ||= @status
|
14
|
+
record[:status] ||= @status # for 500 errors
|
14
15
|
record[:request_id] = CurrentRequest.current.request_id
|
16
|
+
|
17
|
+
# capture referer from where this page was opened
|
18
|
+
if record[:status] == 404
|
19
|
+
record[:HTTP_REFERER] = env["HTTP_REFERER"]
|
20
|
+
end
|
21
|
+
|
22
|
+
# store for section "recent requests"
|
15
23
|
RP::Utils.log_trace_in_redis(CurrentRequest.current.request_id, CurrentRequest.current.storage)
|
24
|
+
|
25
|
+
# store request information
|
16
26
|
RP::Utils.log_request_in_redis(record)
|
17
27
|
ensure
|
18
|
-
|
28
|
+
# we don't want to have a memory leak
|
19
29
|
CurrentRequest.cleanup
|
20
30
|
end
|
21
31
|
end
|
32
|
+
#puts "==> store performance data: #{(Time.now - t).round(3)}ms"
|
22
33
|
|
23
34
|
[@status, @headers, @response]
|
24
35
|
end
|
@@ -13,7 +13,7 @@ module RailsPerformance
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def Utils.log_request_in_redis(e)
|
16
|
-
value = e.slice(:view_runtime, :db_runtime, :duration)
|
16
|
+
value = e.slice(:view_runtime, :db_runtime, :duration, :HTTP_REFERER)
|
17
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"
|
@@ -1,3 +1,3 @@
|
|
1
1
|
module RailsPerformance
|
2
|
-
VERSION = '0.0
|
3
|
-
end
|
2
|
+
VERSION = '0.9.0'
|
3
|
+
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: 0.0
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|