dial 0.1.2 → 0.1.3

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: c1ac4b6e83d9c20da87125b635bb0d9e98d71147d1fa0490606bc7f5431aa171
4
- data.tar.gz: ad2c423d69ade789af8cb6c52776d1688607a6a97c04215c231f26931a986f0d
3
+ metadata.gz: dcc8b8f15acf035328c3330930476af9621529608cabcb511b240cc7da9a9ecf
4
+ data.tar.gz: 05b4c3610edad8e1b6b4cb1cad387ea962d7e250c8cb165a845926bbd668e37c
5
5
  SHA512:
6
- metadata.gz: 957163d6a4b723704c6956d0056f6f36a67f1ce07415b5e39ae84be396ca58a77cb5fd076ce8dec8471e019e10d7fb516594cb8c9ea5806b7c80f15af8063c17
7
- data.tar.gz: df6125c631c2948aa24cc03508f951b47bc198c39ecc34d4a1a091eb265c0b6aa572f75d8e6b4883d6856b2bf830ba1bd7617e6e0fb5bacd924c7475876302fd
6
+ metadata.gz: 9bf37053b4f2bc59bd322646d7485326378c6d234d822571e59f14530ea4382830a6b842f514bef3f9fc7d6719b9b212251023b5c6a214304fb920aac0c4abd3
7
+ data.tar.gz: c5688daab1bd6d82310bab1270a243e507eb54bbc12cbf187c2d3237e43fe1d5022df34fa7f105b642ca563f10f7b343181a74bc5c1864a1dd36d5cca6d15f85
data/CHANGELOG.md CHANGED
@@ -1,13 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.3] - 2024-11-14
4
+
5
+ - Enable allocation profiling by default
6
+
3
7
  ## [0.1.2] - 2024-11-10
4
8
 
5
9
  - Add support for request profiling with vernier
6
10
 
7
11
  ## [0.1.1] - 2024-11-08
8
12
 
9
- - Set upper bound on dependencies
10
-
11
- ## [0.1.0] - 2024-11-08
12
-
13
13
  - Initial release
data/README.md CHANGED
@@ -7,17 +7,8 @@ WIP
7
7
 
8
8
  A modern profiler for Rails applications.
9
9
 
10
- <details>
11
- <summary>POC</summary>
12
-
13
- ![Snapshot 1](https://github.com/user-attachments/assets/904daaf5-3f18-4c94-a7e4-9418539a19f3)
14
-
15
- ![Snapshot 2](https://github.com/user-attachments/assets/eb6ed9f5-b258-42df-8901-222c7d969fdd)
16
-
17
10
  https://github.com/user-attachments/assets/bae59681-ebeb-42b3-9489-9692c072c3dc
18
11
 
19
- </details>
20
-
21
12
  ## Installation
22
13
 
23
14
  Install the gem and add it to your Rails application's Gemfile by executing:
@@ -3,7 +3,7 @@
3
3
  Dial::Engine.routes.draw do
4
4
  scope path: "/dial", as: "dial" do
5
5
  get "profile", to: lambda { |env|
6
- uuid = env[Rack::QUERY_STRING].sub("uuid=", "")
6
+ uuid = env[::Rack::QUERY_STRING].sub "uuid=", ""
7
7
  path = String ::Rails.root.join Dial::PROFILE_OUT_RELATIVE_DIRNAME, "#{uuid}.json"
8
8
 
9
9
  if File.exist? path
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "cgi"
4
-
5
- require_relative "constants"
3
+ require "uri"
6
4
 
7
5
  module Dial
8
6
  class Panel
@@ -14,9 +12,9 @@ module Dial
14
12
  <div id="dial">
15
13
  <div id="dial-preview">
16
14
  <span>
17
- #{formatted_rails_route_info(env)} |
18
- #{formatted_request_timing(env)} |
19
- #{formatted_profile_ouput(env, profile_out_filename)}
15
+ #{formatted_rails_route_info env} |
16
+ #{formatted_request_timing env} |
17
+ #{formatted_profile_output env, profile_out_filename}
20
18
  </span>
21
19
  <span>#{formatted_rails_version}</span>
22
20
  <span>#{formatted_rack_version}</span>
@@ -27,30 +25,30 @@ module Dial
27
25
  <hr>
28
26
 
29
27
  <details>
30
- <summary>RubyVM stat</summary>
28
+ <summary>Server timing</summary>
31
29
  <div class="section">
32
- #{formatted_ruby_vm_stat(ruby_vm_stat)}
30
+ #{formatted_server_timing server_timing}
33
31
  </div>
34
32
  </details>
35
33
 
36
34
  <details>
37
- <summary>GC stat</summary>
35
+ <summary>RubyVM stat</summary>
38
36
  <div class="section">
39
- #{formatted_gc_stat(gc_stat)}
37
+ #{formatted_ruby_vm_stat ruby_vm_stat}
40
38
  </div>
41
39
  </details>
42
40
 
43
41
  <details>
44
- <summary>GC stat heap</summary>
42
+ <summary>GC stat</summary>
45
43
  <div class="section">
46
- #{formatted_gc_stat_heap(gc_stat_heap)}
44
+ #{formatted_gc_stat gc_stat}
47
45
  </div>
48
46
  </details>
49
47
 
50
48
  <details>
51
- <summary>Server timing</summary>
49
+ <summary>GC stat heap</summary>
52
50
  <div class="section">
53
- #{formatted_server_timing(server_timing)}
51
+ #{formatted_gc_stat_heap gc_stat_heap}
54
52
  </div>
55
53
  </details>
56
54
  </div>
@@ -77,42 +75,41 @@ module Dial
77
75
  padding: 0.5rem;
78
76
  font-size: 0.85rem;
79
77
  color: black;
80
- cursor: pointer;
81
- }
82
-
83
- #dial-preview {
84
- display: flex;
85
- flex-direction: column;
86
- cursor: pointer;
87
- }
88
-
89
- #dial-details {
90
- display: none;
91
- }
92
-
93
- .section {
94
- display: flex;
95
- flex-direction: column;
96
- margin-top: 0.5rem;
97
- }
98
-
99
- span {
100
- text-align: left;
101
- }
102
-
103
- hr {
104
- width: -moz-available;
105
- margin-top: 0.5rem;
106
- }
107
78
 
108
- details {
109
- margin-top: 0.5rem;
110
- text-align: left;
111
- }
112
-
113
- summary {
114
- margin-bottom: 0.25rem;
115
- cursor: pointer;
79
+ #dial-preview {
80
+ display: flex;
81
+ flex-direction: column;
82
+ cursor: pointer;
83
+ }
84
+
85
+ #dial-details {
86
+ display: none;
87
+ }
88
+
89
+ .section {
90
+ display: flex;
91
+ flex-direction: column;
92
+ margin: 0.25rem 0 0 0;
93
+ }
94
+
95
+ span {
96
+ text-align: left;
97
+ }
98
+
99
+ hr {
100
+ width: -moz-available;
101
+ margin: 0.65rem 0 0 0;
102
+ }
103
+
104
+ details {
105
+ margin: 0.5rem 0 0 0;
106
+ text-align: left;
107
+ }
108
+
109
+ summary {
110
+ margin: 0.25rem 0 0 0;
111
+ cursor: pointer;
112
+ }
116
113
  }
117
114
  CSS
118
115
  end
@@ -142,15 +139,13 @@ module Dial
142
139
  "<b>Request timing:</b> #{env[REQUEST_TIMING_HEADER]}ms"
143
140
  end
144
141
 
145
- def formatted_profile_ouput env, profile_out_filename
146
- uuid = profile_out_filename.sub ".json", ""
147
- path = "dial/profile?uuid=#{uuid}"
142
+ def formatted_profile_output env, profile_out_filename
143
+ uuid = profile_out_filename.delete_suffix ".json"
148
144
  host = env[::Rack::HTTP_HOST]
149
145
  base_url = ::Rails.application.routes.url_helpers.dial_url host: host
150
- profile_out_url = CGI.escape base_url + path
151
- url = "https://vernier.prof/from-url/#{profile_out_url}"
146
+ profile_out_url = URI.encode_www_form_component base_url + "dial/profile?uuid=#{uuid}"
152
147
 
153
- "<a href='#{url}' target='_blank'>View profile</a>"
148
+ "<a href='https://vernier.prof/from-url/#{profile_out_url}' target='_blank'>View profile</a>"
154
149
  end
155
150
 
156
151
  def formatted_rails_version
@@ -162,7 +157,18 @@ module Dial
162
157
  end
163
158
 
164
159
  def formatted_ruby_version
165
- "<b>Ruby version:</b> #{RUBY_DESCRIPTION}"
160
+ "<b>Ruby version:</b> #{::RUBY_DESCRIPTION}"
161
+ end
162
+
163
+ def formatted_server_timing server_timing
164
+ if server_timing.any?
165
+ server_timing
166
+ # TODO: Nested sorting
167
+ .sort_by { |_, timing| -timing }
168
+ .map { |event, timing| "<span><b>#{event}:</b> #{timing}</span>" }.join
169
+ else
170
+ "NA"
171
+ end
166
172
  end
167
173
 
168
174
  def formatted_ruby_vm_stat ruby_vm_stat
@@ -185,17 +191,6 @@ module Dial
185
191
  HTML
186
192
  end.join
187
193
  end
188
-
189
- def formatted_server_timing server_timing
190
- if server_timing.any?
191
- server_timing
192
- # TODO: Nested sorting
193
- .sort_by { |_, timing| -timing }
194
- .map { |event, timing| "<span><b>#{event}:</b> #{timing}</span>" }.join
195
- else
196
- "NA"
197
- end
198
- end
199
194
  end
200
195
  end
201
196
  end
@@ -5,8 +5,8 @@ module Dial
5
5
  private
6
6
 
7
7
  def server_timing headers
8
- timing = if (ActionDispatch.const_defined? :Constants) && (ActionDispatch::Constants.const_defined? :SERVER_TIMING)
9
- headers[ActionDispatch::Constants::SERVER_TIMING]
8
+ timing = if ::ActionDispatch.const_defined? "Constants::SERVER_TIMING"
9
+ headers[::ActionDispatch::Constants::SERVER_TIMING]
10
10
  else
11
11
  headers["Server-Timing"]
12
12
  end
@@ -5,11 +5,11 @@ module Dial
5
5
  private
6
6
 
7
7
  def ruby_vm_stat_diff before, after
8
- stat_diff before, after, except: [:next_shape_id]
8
+ stat_diff before, after, no_diff: [:next_shape_id]
9
9
  end
10
10
 
11
11
  def gc_stat_diff before, after
12
- stat_diff before, after, except: [
12
+ stat_diff before, after, no_diff: [
13
13
  :heap_allocatable_slots,
14
14
  :malloc_increase_bytes_limit,
15
15
  :remembered_wb_unprotected_objects_limit,
@@ -20,14 +20,14 @@ module Dial
20
20
 
21
21
  def gc_stat_heap_diff before, after
22
22
  after.each_with_object({}) do |(slot_index, slot_stat), diff|
23
- diff[slot_index] = stat_diff before[slot_index], slot_stat, except: [:slot_size]
23
+ diff[slot_index] = stat_diff before[slot_index], slot_stat, no_diff: [:slot_size]
24
24
  end
25
25
  end
26
26
 
27
- def stat_diff before, after, except: []
28
- after.except(*except).each_with_object({}) do |(key, value), diff|
27
+ def stat_diff before, after, no_diff: []
28
+ after.except(*no_diff).each_with_object({}) do |(key, value), diff|
29
29
  diff[key] = value - before[key]
30
- end
30
+ end.merge after.slice *no_diff
31
31
  end
32
32
  end
33
33
  end
@@ -2,10 +2,10 @@
2
2
 
3
3
  require "vernier"
4
4
 
5
- require_relative "ruby_stat"
6
- require_relative "rails_stat"
7
5
  require_relative "constants"
8
- require_relative "panel"
6
+ require_relative "middleware/panel"
7
+ require_relative "middleware/ruby_stat"
8
+ require_relative "middleware/rails_stat"
9
9
 
10
10
  module Dial
11
11
  class Middleware
@@ -17,7 +17,7 @@ module Dial
17
17
  end
18
18
 
19
19
  def call env
20
- start_time = ::Process.clock_gettime ::Process::CLOCK_MONOTONIC
20
+ start_time = Process.clock_gettime Process::CLOCK_MONOTONIC
21
21
 
22
22
  ruby_vm_stat_before = RubyVM.stat
23
23
  gc_stat_before = GC.stat
@@ -29,7 +29,7 @@ module Dial
29
29
  profile_out_pathname = "#{profile_out_dirname}#{profile_out_filename}"
30
30
 
31
31
  status, headers, rack_body = nil
32
- ::Vernier.profile out: profile_out_pathname do
32
+ ::Vernier.profile out: profile_out_pathname, interval: 500, allocation_interval: 1000 do
33
33
  status, headers, rack_body = @app.call env
34
34
  end
35
35
 
@@ -38,19 +38,19 @@ module Dial
38
38
  return [status, headers, rack_body]
39
39
  end
40
40
 
41
- finish_time = ::Process.clock_gettime ::Process::CLOCK_MONOTONIC
41
+ finish_time = Process.clock_gettime Process::CLOCK_MONOTONIC
42
42
  env[REQUEST_TIMING_HEADER] = ((finish_time - start_time) * 1_000).round 2
43
43
 
44
- ruby_vm_stat_diff = ruby_vm_stat_diff ruby_vm_stat_before, RubyVM.stat
45
- gc_stat_diff = gc_stat_diff gc_stat_before, GC.stat
46
- gc_stat_heap_diff = gc_stat_heap_diff gc_stat_heap_before, GC.stat_heap
44
+ ruby_vm_stat = ruby_vm_stat_diff ruby_vm_stat_before, RubyVM.stat
45
+ gc_stat = gc_stat_diff gc_stat_before, GC.stat
46
+ gc_stat_heap = gc_stat_heap_diff gc_stat_heap_before, GC.stat_heap
47
47
  server_timing = server_timing headers
48
48
 
49
49
  body = String.new.tap do |str|
50
50
  rack_body.each { |chunk| str << chunk }
51
- rack_body.close if body.respond_to? :close
51
+ rack_body.close if rack_body.respond_to? :close
52
52
  end.sub "</body>", <<~HTML
53
- #{Panel.html env, profile_out_filename, ruby_vm_stat_diff, gc_stat_diff, gc_stat_heap_diff, server_timing}
53
+ #{Panel.html env, profile_out_filename, ruby_vm_stat, gc_stat, gc_stat_heap, server_timing}
54
54
  </body>
55
55
  HTML
56
56
 
data/lib/dial/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dial
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.3"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Young
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2024-11-10 00:00:00.000000000 Z
10
+ date: 2024-11-14 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: railties
@@ -99,10 +99,10 @@ files:
99
99
  - lib/dial/engine.rb
100
100
  - lib/dial/engine/routes.rb
101
101
  - lib/dial/middleware.rb
102
- - lib/dial/panel.rb
103
- - lib/dial/rails_stat.rb
102
+ - lib/dial/middleware/panel.rb
103
+ - lib/dial/middleware/rails_stat.rb
104
+ - lib/dial/middleware/ruby_stat.rb
104
105
  - lib/dial/railtie.rb
105
- - lib/dial/ruby_stat.rb
106
106
  - lib/dial/version.rb
107
107
  homepage: https://github.com/joshuay03/dial
108
108
  licenses: