dial 0.1.0 → 0.1.2

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: 1c66ebfd5f92223dfdb75e7f13880a293074408ccfbf835eae6b641bed9b8fcc
4
- data.tar.gz: ef11315610241303543d3319ead19364effe60b326ee29f901ece1623331e8f2
3
+ metadata.gz: c1ac4b6e83d9c20da87125b635bb0d9e98d71147d1fa0490606bc7f5431aa171
4
+ data.tar.gz: ad2c423d69ade789af8cb6c52776d1688607a6a97c04215c231f26931a986f0d
5
5
  SHA512:
6
- metadata.gz: 004b0ed1ce0ba338bce6ec32a9c15b634263d6bdac011215a49497923c5f72bd6730d31ea76a6f38ce910efe67e09322d25efdd5e2dd97a6fd91959afe14bdcc
7
- data.tar.gz: a60be22b96db02f9bdcfe3d1a314ef98fa1b1d51af6b2744962156fe191703ad07d1b7fc8242fbefcb8098d4d889302cc7f66a3a6a0775ee6758102f8904c50c
6
+ metadata.gz: 957163d6a4b723704c6956d0056f6f36a67f1ce07415b5e39ae84be396ca58a77cb5fd076ce8dec8471e019e10d7fb516594cb8c9ea5806b7c80f15af8063c17
7
+ data.tar.gz: df6125c631c2948aa24cc03508f951b47bc198c39ecc34d4a1a091eb265c0b6aa572f75d8e6b4883d6856b2bf830ba1bd7617e6e0fb5bacd924c7475876302fd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.2] - 2024-11-10
4
+
5
+ - Add support for request profiling with vernier
6
+
7
+ ## [0.1.1] - 2024-11-08
8
+
9
+ - Set upper bound on dependencies
10
+
3
11
  ## [0.1.0] - 2024-11-08
4
12
 
5
13
  - Initial release
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Dial
2
2
 
3
+ ![Version](https://img.shields.io/gem/v/dial)
4
+ ![Build](https://img.shields.io/github/actions/workflow/status/joshuay03/dial/.github/workflows/main.yml?branch=main)
5
+
3
6
  WIP
4
7
 
5
8
  A modern profiler for Rails applications.
@@ -7,19 +10,24 @@ A modern profiler for Rails applications.
7
10
  <details>
8
11
  <summary>POC</summary>
9
12
 
10
- ![Demo 1](https://github.com/user-attachments/assets/904daaf5-3f18-4c94-a7e4-9418539a19f3)
11
- ![Demo 2](https://github.com/user-attachments/assets/eb6ed9f5-b258-42df-8901-222c7d969fdd)
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
+ https://github.com/user-attachments/assets/bae59681-ebeb-42b3-9489-9692c072c3dc
12
18
 
13
19
  </details>
14
20
 
15
21
  ## Installation
16
22
 
17
- Install the gem and add it to your application's Gemfile by executing:
23
+ Install the gem and add it to your Rails application's Gemfile by executing:
18
24
 
19
25
  ```bash
20
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
26
+ bundle add dial
21
27
  ```
22
28
 
29
+ and everything should just work.
30
+
23
31
  ## Development
24
32
 
25
33
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the
data/dial.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = "A modern Rails profiler"
12
12
  spec.homepage = "https://github.com/joshuay03/dial"
13
13
  spec.license = "MIT"
14
- spec.required_ruby_version = ">= 3.0.0"
14
+ spec.required_ruby_version = ">= 3.2.1"
15
15
 
16
16
  spec.metadata["source_code_uri"] = spec.homepage
17
17
  spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
@@ -19,7 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.files = Dir["{lib}/**/*", "**/*.{gemspec,md,txt}"]
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency "railties", ">= 7.0.0", "<= 8.0"
23
- spec.add_dependency "activerecord", ">= 7.0.0", "<= 8.0"
24
- spec.add_dependency "actionpack", ">= 7.0.0", "<= 8.0"
22
+ spec.add_dependency "railties", ">= 7", "< 8.2"
23
+ spec.add_dependency "activerecord", ">= 7", "< 8.2"
24
+ spec.add_dependency "actionpack", ">= 7", "< 8.2"
25
+ spec.add_dependency "vernier", "~> 1.3"
25
26
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dial
4
- module Constants
5
- DIAL_REQUEST_TIMING = "dial_request_timing"
6
- end
4
+ REQUEST_TIMING_HEADER = "dial_request_timing"
5
+ PROFILE_OUT_RELATIVE_DIRNAME = "tmp/dial/profile/"
7
6
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dial::Engine.routes.draw do
4
+ scope path: "/dial", as: "dial" do
5
+ get "profile", to: lambda { |env|
6
+ uuid = env[Rack::QUERY_STRING].sub("uuid=", "")
7
+ path = String ::Rails.root.join Dial::PROFILE_OUT_RELATIVE_DIRNAME, "#{uuid}.json"
8
+
9
+ if File.exist? path
10
+ [
11
+ 200,
12
+ { "Content-Type" => "application/json", "Access-Control-Allow-Origin" => "https://vernier.prof" },
13
+ [File.read(path)]
14
+ ]
15
+ else
16
+ [
17
+ 404,
18
+ { "Content-Type" => "text/plain" },
19
+ ["Not Found"]
20
+ ]
21
+ end
22
+ }
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+
5
+ module Dial
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace Dial
8
+
9
+ paths["config/routes.rb"] = ["lib/dial/engine/routes.rb"]
10
+ end
11
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "vernier"
4
+
3
5
  require_relative "ruby_stat"
4
6
  require_relative "rails_stat"
5
7
  require_relative "constants"
@@ -9,7 +11,6 @@ module Dial
9
11
  class Middleware
10
12
  include RubyStat
11
13
  include RailsStat
12
- include Constants
13
14
 
14
15
  def initialize app
15
16
  @app = app
@@ -22,11 +23,23 @@ module Dial
22
23
  gc_stat_before = GC.stat
23
24
  gc_stat_heap_before = GC.stat_heap
24
25
 
25
- status, headers, rack_body = @app.call env
26
- return [status, headers, rack_body] unless headers[::Rack::CONTENT_TYPE]&.include? "text/html"
26
+ profile_out_dirname = String ::Rails.root.join PROFILE_OUT_RELATIVE_DIRNAME
27
+ FileUtils.mkdir_p profile_out_dirname
28
+ profile_out_filename = "#{SecureRandom.uuid}.json"
29
+ profile_out_pathname = "#{profile_out_dirname}#{profile_out_filename}"
30
+
31
+ status, headers, rack_body = nil
32
+ ::Vernier.profile out: profile_out_pathname do
33
+ status, headers, rack_body = @app.call env
34
+ end
35
+
36
+ unless headers[::Rack::CONTENT_TYPE]&.include? "text/html"
37
+ File.delete profile_out_pathname if File.exist? profile_out_pathname
38
+ return [status, headers, rack_body]
39
+ end
27
40
 
28
41
  finish_time = ::Process.clock_gettime ::Process::CLOCK_MONOTONIC
29
- env[DIAL_REQUEST_TIMING] = ((finish_time - start_time) * 1_000).round 2
42
+ env[REQUEST_TIMING_HEADER] = ((finish_time - start_time) * 1_000).round 2
30
43
 
31
44
  ruby_vm_stat_diff = ruby_vm_stat_diff ruby_vm_stat_before, RubyVM.stat
32
45
  gc_stat_diff = gc_stat_diff gc_stat_before, GC.stat
@@ -37,7 +50,7 @@ module Dial
37
50
  rack_body.each { |chunk| str << chunk }
38
51
  rack_body.close if body.respond_to? :close
39
52
  end.sub "</body>", <<~HTML
40
- #{Panel.html env, ruby_vm_stat_diff, gc_stat_diff, gc_stat_heap_diff, server_timing}
53
+ #{Panel.html env, profile_out_filename, ruby_vm_stat_diff, gc_stat_diff, gc_stat_heap_diff, server_timing}
41
54
  </body>
42
55
  HTML
43
56
 
data/lib/dial/panel.rb CHANGED
@@ -1,19 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cgi"
4
+
3
5
  require_relative "constants"
4
6
 
5
7
  module Dial
6
8
  class Panel
7
9
  class << self
8
- include Constants
9
-
10
- def html env, ruby_vm_stat, gc_stat, gc_stat_heap, server_timing
10
+ def html env, profile_out_filename, ruby_vm_stat, gc_stat, gc_stat_heap, server_timing
11
11
  <<~HTML
12
12
  <style>#{style}</style>
13
13
 
14
14
  <div id="dial">
15
15
  <div id="dial-preview">
16
- <span>#{formatted_rails_route_info(env)} | #{formatted_request_timing(env)}</span>
16
+ <span>
17
+ #{formatted_rails_route_info(env)} |
18
+ #{formatted_request_timing(env)} |
19
+ #{formatted_profile_ouput(env, profile_out_filename)}
20
+ </span>
17
21
  <span>#{formatted_rails_version}</span>
18
22
  <span>#{formatted_rack_version}</span>
19
23
  <span>#{formatted_ruby_version}</span>
@@ -135,7 +139,18 @@ module Dial
135
139
  end
136
140
 
137
141
  def formatted_request_timing env
138
- "<b>Request timing:</b> #{env[DIAL_REQUEST_TIMING]}ms"
142
+ "<b>Request timing:</b> #{env[REQUEST_TIMING_HEADER]}ms"
143
+ end
144
+
145
+ def formatted_profile_ouput env, profile_out_filename
146
+ uuid = profile_out_filename.sub ".json", ""
147
+ path = "dial/profile?uuid=#{uuid}"
148
+ host = env[::Rack::HTTP_HOST]
149
+ 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}"
152
+
153
+ "<a href='#{url}' target='_blank'>View profile</a>"
139
154
  end
140
155
 
141
156
  def formatted_rails_version
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.0"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/dial.rb CHANGED
@@ -2,3 +2,4 @@
2
2
 
3
3
  require_relative "dial/version"
4
4
  require_relative "dial/railtie"
5
+ require_relative "dial/engine"
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.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Young
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2024-11-08 00:00:00.000000000 Z
10
+ date: 2024-11-10 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: railties
@@ -15,60 +15,74 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 7.0.0
19
- - - "<="
18
+ version: '7'
19
+ - - "<"
20
20
  - !ruby/object:Gem::Version
21
- version: '8.0'
21
+ version: '8.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: 7.0.0
29
- - - "<="
28
+ version: '7'
29
+ - - "<"
30
30
  - !ruby/object:Gem::Version
31
- version: '8.0'
31
+ version: '8.2'
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: activerecord
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  requirements:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
- version: 7.0.0
39
- - - "<="
38
+ version: '7'
39
+ - - "<"
40
40
  - !ruby/object:Gem::Version
41
- version: '8.0'
41
+ version: '8.2'
42
42
  type: :runtime
43
43
  prerelease: false
44
44
  version_requirements: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - ">="
47
47
  - !ruby/object:Gem::Version
48
- version: 7.0.0
49
- - - "<="
48
+ version: '7'
49
+ - - "<"
50
50
  - !ruby/object:Gem::Version
51
- version: '8.0'
51
+ version: '8.2'
52
52
  - !ruby/object:Gem::Dependency
53
53
  name: actionpack
54
54
  requirement: !ruby/object:Gem::Requirement
55
55
  requirements:
56
56
  - - ">="
57
57
  - !ruby/object:Gem::Version
58
- version: 7.0.0
59
- - - "<="
58
+ version: '7'
59
+ - - "<"
60
60
  - !ruby/object:Gem::Version
61
- version: '8.0'
61
+ version: '8.2'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 7.0.0
69
- - - "<="
68
+ version: '7'
69
+ - - "<"
70
70
  - !ruby/object:Gem::Version
71
- version: '8.0'
71
+ version: '8.2'
72
+ - !ruby/object:Gem::Dependency
73
+ name: vernier
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - "~>"
77
+ - !ruby/object:Gem::Version
78
+ version: '1.3'
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '1.3'
72
86
  email:
73
87
  - djry1999@gmail.com
74
88
  executables: []
@@ -82,6 +96,8 @@ files:
82
96
  - dial.gemspec
83
97
  - lib/dial.rb
84
98
  - lib/dial/constants.rb
99
+ - lib/dial/engine.rb
100
+ - lib/dial/engine/routes.rb
85
101
  - lib/dial/middleware.rb
86
102
  - lib/dial/panel.rb
87
103
  - lib/dial/rails_stat.rb
@@ -101,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
117
  requirements:
102
118
  - - ">="
103
119
  - !ruby/object:Gem::Version
104
- version: 3.0.0
120
+ version: 3.2.1
105
121
  required_rubygems_version: !ruby/object:Gem::Requirement
106
122
  requirements:
107
123
  - - ">="