rails_performance 0.0.1.19 → 0.9.0

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: 56c91669685f1dc4c4ee8830b921acde7a98642b7065c9ffbcb939fca355abcf
4
- data.tar.gz: 14d2bb35561e4af0a563791ae4efdae812e98235c7e692cf735346f4bd61e8f4
3
+ metadata.gz: fe073c7658af65303c6efc61dbaa973edba22d21c2991e715d523b6f4c96dc5f
4
+ data.tar.gz: bf7780ef55eab59d2974b990eba4e2afad26b78683f685fb8383b4df4d8ada30
5
5
  SHA512:
6
- metadata.gz: a9ab71a3a5140b1c1d403f08a6fe5c36a023b3c5839ed88b3976d0e35315364a7b335b5ec17b007b5fd2bf32067a1a7f687b6e8e356e44bd8ecd9d85af061162
7
- data.tar.gz: 7c956c17f1e3b4b24f715331c1df68afb8ea9f2a45876a6a8bf1bd097a17982035a2de528d18a7a7ca5becd63c06a0e6edd50aa7ee2f20e129c2c5a4acaee8fd
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 total time spent per request, views rendering, DB execution
13
- - simple crash reports
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
- - connected charts
98
- - ability to zoom to see requests withing specific datime range
99
- - better hint
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
- - 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
114
- - scroll to the top details
109
+ - collect deprecation.rails
110
+ - fix misspellings?
115
111
 
116
112
  ## Contributing
117
113
 
@@ -34,6 +34,7 @@ class RailsPerformanceController < BaseController
34
34
  end
35
35
 
36
36
  def trace
37
+ @record = RP::Models::Record.find_by(request_id: params[:id])
37
38
  @report = RP::Reports::TraceReport.new(request_id: params[:id])
38
39
  @data = @report.data
39
40
  respond_to do |format|
@@ -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-success">#{v}</span>
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>-</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/>
@@ -16,6 +16,12 @@
16
16
  </tr>
17
17
  </thead>
18
18
  <tbody>
19
+ <% if @data.empty? %>
20
+ <tr>
21
+ <td colspan="9">We are glad that this list is empty ;)</td>
22
+ </tr>
23
+ <% end %>
24
+
19
25
  <% @data.each do |e| %>
20
26
  <tr>
21
27
  <td><%= format_datetime e[:datetime] %></td>
@@ -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
- window.panel.header.html(window.panel.close);
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
- Thread.current["RP_request_info"] = record
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
- if record = Thread.current["RP_request_info"]
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
- Thread.current["RP_request_info"] = nil
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.1.19'
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.1.19
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-10 00:00:00.000000000 Z
11
+ date: 2020-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails