dial 0.1.7 → 0.1.9

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: 22930c6ef22196a525fb4986ce053b36f148867083636976d54f184a2dd2f46d
4
- data.tar.gz: a7131f94657e6fca3f8826306cf8d9a1cd98e888def46e05ba690833492dcd8d
3
+ metadata.gz: 31949e2dbaf8b3ca4f422ae02115747913ce3bd704b0aaf8d45d5956d0ba2ac5
4
+ data.tar.gz: aecdd78df3d7e50c0dd9b98c67c0f7633d6cc2fa43ea33d01987a148dff53cf0
5
5
  SHA512:
6
- metadata.gz: f0bca632784f1ff0f5b8cd82df1117dcb0e8f2c7bcf07973b174964106a4eb67ac23fead61930b8ddd99376dcf0dc4df32624494518303b7a85be136c2a8e669
7
- data.tar.gz: d9da11b80ac380b8db0991498f966397707e9c3e6a270c75a68644de16b9bbd610604bb819345885c474047bb4ed4531ae106f19748972df594fac19a7e838e0
6
+ metadata.gz: 21ed80548f3559308cfdc13ff69df8168ef87ffa6268faea8d5901e2209cbd1e9f775bcbd48db355e83c1d3e48cb59f285af0c0271fc1fa14442852c84dab521
7
+ data.tar.gz: 202f8d84d6ce0520b7bf53df0cac7545a85f1c6f723c845158c9161cf52f1a1a6fbe55e70671a70c9bf1ca43aad052d28d2f10b3a7572ea34c5747090121ab98
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.9] - 2025-01-27
4
+
5
+ - Increase default vernier allocation interval from 10k to 100k
6
+
7
+ ## [0.1.8] - 2025-01-27
8
+
9
+ - Require ruby 3.3.0 or later
10
+ - Handle stale file deletion in railtie, extend to log files
11
+ - Make log files unique to each session - simplify installation
12
+
3
13
  ## [0.1.7] - 2025-01-25
4
14
 
5
15
  - Increase default vernier allocation interval from 1k to 10k
data/README.md CHANGED
@@ -12,11 +12,12 @@ Check out the demo:
12
12
 
13
13
  ## Installation
14
14
 
15
- 1. Add the gem to your Rails application's Gemfile (adjust the `require` option to match your server of choice):
15
+ 1. Add the gem to your Rails application's Gemfile:
16
16
 
17
17
  ```ruby
18
- # require in just the server process
19
- gem "dial", require: !!($PROGRAM_NAME =~ /puma/)
18
+ group :development do
19
+ gem "dial"
20
+ end
20
21
  ```
21
22
 
22
23
  2. Install the gem:
@@ -29,7 +30,7 @@ bundle install
29
30
 
30
31
  ```ruby
31
32
  # this will mount the engine at /dial
32
- mount Dial::Engine, at: "/" if Object.const_defined? "Dial::Engine"
33
+ mount Dial::Engine, at: "/" if Rails.env.development?
33
34
  ```
34
35
 
35
36
  ## Development
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.2.1"
14
+ spec.required_ruby_version = ">= 3.3.0"
15
15
 
16
16
  spec.metadata["source_code_uri"] = spec.homepage
17
17
  spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
@@ -3,11 +3,17 @@
3
3
  require_relative "version"
4
4
 
5
5
  module Dial
6
+ PROGRAM_ID = Process.getsid Process.pid
7
+
6
8
  REQUEST_TIMING_HEADER = "dial_request_timing"
7
9
 
8
- PROFILE_OUT_STALE_SECONDS = 60 * 60
9
- PROFILE_OUT_RELATIVE_DIRNAME = "tmp/dial/profiles/"
10
+ FILE_STALE_SECONDS = 60 * 60
11
+
12
+ VERNIER_INTERVAL = 500
13
+ VERNIER_ALLOCATION_INTERVAL = 100_000
14
+ VERNIER_PROFILE_OUT_RELATIVE_DIRNAME = "tmp/dial/profiles"
10
15
 
11
- PROSOPITE_IGNORE_QUERIES = [/schema_migrations/]
12
- PROSOPITE_LOG_RELATIVE_PATHNAME = "log/dial/prosopite.log"
16
+ PROSOPITE_IGNORE_QUERIES = [/schema_migrations/].freeze
17
+ PROSOPITE_LOG_RELATIVE_DIRNAME = "log/dial"
18
+ PROSOPITE_LOG_FILENAME = "#{Util.uuid}_prosopite_#{PROGRAM_ID}.log".freeze
13
19
  end
@@ -4,7 +4,7 @@ Dial::Engine.routes.draw do
4
4
  scope path: "/dial", as: "dial" do
5
5
  get "profile", to: lambda { |env|
6
6
  uuid = env[::Rack::QUERY_STRING].sub "uuid=", ""
7
- path = String ::Rails.root.join Dial::PROFILE_OUT_RELATIVE_DIRNAME, "#{uuid}.json"
7
+ path = String ::Rails.root.join Dial::VERNIER_PROFILE_OUT_RELATIVE_DIRNAME, "#{uuid}.json"
8
8
 
9
9
  if File.exist? path
10
10
  [
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "securerandom"
4
-
5
3
  require "vernier"
6
4
  require "prosopite"
7
5
 
@@ -21,13 +19,13 @@ module Dial
21
19
  def call env
22
20
  start_time = Process.clock_gettime Process::CLOCK_MONOTONIC
23
21
 
24
- profile_out_filename = "#{SecureRandom.uuid_v7}.json"
25
- profile_out_pathname = "#{profile_out_dir_pathname}#{profile_out_filename}"
22
+ profile_out_filename = "#{Util.uuid}_vernier.json"
23
+ profile_out_pathname = "#{profile_out_dir_pathname}/#{profile_out_filename}"
26
24
 
27
25
  status, headers, rack_body = nil
28
26
  ruby_vm_stat, gc_stat, gc_stat_heap = nil
29
27
  ::Prosopite.scan do
30
- ::Vernier.profile out: profile_out_pathname, interval: 500, allocation_interval: 10_000, hooks: [:memory_usage, :rails] do
28
+ ::Vernier.profile out: profile_out_pathname, interval: VERNIER_INTERVAL, allocation_interval: VERNIER_ALLOCATION_INTERVAL, hooks: [:memory_usage, :rails] do
31
29
  ruby_vm_stat, gc_stat, gc_stat_heap = with_diffed_ruby_stats do
32
30
  status, headers, rack_body = @app.call env
33
31
  end
@@ -36,12 +34,10 @@ module Dial
36
34
  server_timing = server_timing headers
37
35
 
38
36
  unless headers[::Rack::CONTENT_TYPE]&.include? "text/html"
39
- File.delete profile_out_pathname if File.exist? profile_out_pathname
40
37
  return [status, headers, rack_body]
41
38
  end
42
39
 
43
40
  query_logs = clear_query_logs!
44
- remove_stale_profile_out_files!
45
41
 
46
42
  finish_time = Process.clock_gettime Process::CLOCK_MONOTONIC
47
43
  env[REQUEST_TIMING_HEADER] = ((finish_time - start_time) * 1_000).round 2
@@ -73,26 +69,9 @@ module Dial
73
69
  ]
74
70
  end
75
71
 
76
- def remove_stale_profile_out_files!
77
- stale_profile_out_files.each do |profile_out_file|
78
- File.delete profile_out_file
79
- end
80
- end
81
-
82
- def stale_profile_out_files
83
- Dir.glob("#{profile_out_dir_pathname}/*.json").select do |profile_out_file|
84
- timestamp = Util.uuid_v7_timestamp File.basename profile_out_file
85
- timestamp < Time.now - PROFILE_OUT_STALE_SECONDS
86
- end
87
- end
88
-
89
- def profile_out_dir_pathname
90
- @_profile_out_dir_pathname ||= ::Rails.root.join PROFILE_OUT_RELATIVE_DIRNAME
91
- end
92
-
93
72
  def clear_query_logs!
94
73
  [].tap do |query_logs|
95
- File.open(query_log_pathname, "r+") do |file|
74
+ File.open("#{query_log_dir_pathname}/#{PROSOPITE_LOG_FILENAME}", "r+") do |file|
96
75
  entry = section = count = nil
97
76
  file.each_line do |line|
98
77
  entry, section, count = process_query_log_line line, entry, section, count
@@ -129,8 +108,12 @@ module Dial
129
108
  end
130
109
  end
131
110
 
132
- def query_log_pathname
133
- @_query_log_dir_pathname ||= ::Rails.root.join PROSOPITE_LOG_RELATIVE_PATHNAME
111
+ def profile_out_dir_pathname
112
+ ::Rails.root.join VERNIER_PROFILE_OUT_RELATIVE_DIRNAME
113
+ end
114
+
115
+ def query_log_dir_pathname
116
+ ::Rails.root.join PROSOPITE_LOG_RELATIVE_DIRNAME
134
117
  end
135
118
  end
136
119
  end
data/lib/dial/railtie.rb CHANGED
@@ -14,7 +14,13 @@ module Dial
14
14
 
15
15
  initializer "dial.set_up_vernier" do |app|
16
16
  app.config.after_initialize do
17
- FileUtils.mkdir_p ::Rails.root.join PROFILE_OUT_RELATIVE_DIRNAME
17
+ FileUtils.mkdir_p ::Rails.root.join VERNIER_PROFILE_OUT_RELATIVE_DIRNAME
18
+ end
19
+ end
20
+
21
+ initializer "dial.clean_up_vernier_profile_out_files" do |app|
22
+ stale_files("#{profile_out_dir_pathname}/*.json").each do |profile_out_file|
23
+ File.delete profile_out_file rescue nil
18
24
  end
19
25
  end
20
26
 
@@ -24,7 +30,7 @@ module Dial
24
30
  require "pg_query"
25
31
  end
26
32
 
27
- prosopite_log_pathname = ::Rails.root.join PROSOPITE_LOG_RELATIVE_PATHNAME
33
+ prosopite_log_pathname = "#{query_log_dir_pathname}/#{PROSOPITE_LOG_FILENAME}"
28
34
  FileUtils.mkdir_p File.dirname prosopite_log_pathname
29
35
  FileUtils.touch prosopite_log_pathname
30
36
  ::Prosopite.custom_logger = ProsopiteLogger.new prosopite_log_pathname
@@ -32,5 +38,28 @@ module Dial
32
38
  ::Prosopite.ignore_queries = PROSOPITE_IGNORE_QUERIES
33
39
  end
34
40
  end
41
+
42
+ initializer "dial.clean_up_prosopite_log_files" do |app|
43
+ stale_files("#{query_log_dir_pathname}/*.log").each do |query_log_file|
44
+ File.delete query_log_file rescue nil
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def stale_files glob_pattern
51
+ Dir.glob(glob_pattern).select do |file|
52
+ timestamp = Util.uuid_timestamp Util.file_name_uuid File.basename file
53
+ timestamp < Time.now - FILE_STALE_SECONDS
54
+ end
55
+ end
56
+
57
+ def profile_out_dir_pathname
58
+ ::Rails.root.join VERNIER_PROFILE_OUT_RELATIVE_DIRNAME
59
+ end
60
+
61
+ def query_log_dir_pathname
62
+ ::Rails.root.join PROSOPITE_LOG_RELATIVE_DIRNAME
63
+ end
35
64
  end
36
65
  end
data/lib/dial/util.rb CHANGED
@@ -1,9 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "securerandom"
4
+
3
5
  module Dial
4
6
  module Util
5
7
  class << self
6
- def uuid_v7_timestamp uuid
8
+ def uuid
9
+ SecureRandom.uuid_v7
10
+ end
11
+
12
+ def file_name_uuid file_name
13
+ file_name.split("_").first
14
+ end
15
+
16
+ def uuid_timestamp uuid
7
17
  high_bits_hex = uuid.split("-").first(2).join[0, 12].to_i 16
8
18
  Time.at high_bits_hex / 1000.0
9
19
  end
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.7"
4
+ VERSION = "0.1.9"
5
5
  end
data/lib/dial.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "dial/constants"
4
3
  require_relative "dial/util"
4
+ require_relative "dial/constants"
5
5
 
6
6
  require_relative "dial/railtie"
7
7
  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.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Young
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-25 00:00:00.000000000 Z
10
+ date: 2025-01-27 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: railties
@@ -147,7 +147,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
147
  requirements:
148
148
  - - ">="
149
149
  - !ruby/object:Gem::Version
150
- version: 3.2.1
150
+ version: 3.3.0
151
151
  required_rubygems_version: !ruby/object:Gem::Requirement
152
152
  requirements:
153
153
  - - ">="