dial 0.1.6 → 0.1.8

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: 4267ea5bc603e20d21e2cc7956154d210a7aad2441a4088c517adee6f9e630a5
4
- data.tar.gz: 57de7d2c3bf2cd8055c3e180ff745b95b8541176f0e8aea6ec05a69f5d1175c5
3
+ metadata.gz: 0bb2a49d25b9e1d11931b2bc987ad87098b04d7f29787b91422fae8ca482ca41
4
+ data.tar.gz: 73b24362f41546bee29b3df431c9edc611264c9d6cd662fed450c13f6f48e377
5
5
  SHA512:
6
- metadata.gz: 82995a0e0d7898af69ea939db4081214844e5b5de7f911be3c6e61ce51d9446d4abeda7dccd0be882c5efabd49267cdcfd2a042ae9c066b1c163f3e68ec1a0ee
7
- data.tar.gz: f5b75425302efda23211c8a87ef94f543d9b253ccb5965d04067db2f81c05c9ad1d2432d222419ccd6ed08dfa90d7243f42452a695c3faaa79f7c5aa5d8bdab3
6
+ metadata.gz: bfb8d6bfba055cc017a379740c23ed7daf6a0ab6141e360b44f9cc8ed168242d7f6d5ee1aeeb03b6c7974cda3cd759130cae17ace399f8ac7abc6e00433db1a3
7
+ data.tar.gz: 388af81b669f651ab4dde3086b3ce3afd3736c3ef127956f33eb8f1f785fd98bd373696e9cfc808fed1276c7dbef7aff460b645e398ae7f637971230eb990225
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.8] - 2025-01-27
4
+
5
+ - Require ruby 3.3.0 or later
6
+ - Handle stale file deletion in railtie, extend to log files
7
+ - Make log files unique to each session - simplify installation
8
+
9
+ ## [0.1.7] - 2025-01-25
10
+
11
+ - Increase default vernier allocation interval from 1k to 10k
12
+
3
13
  ## [0.1.6] - 2025-01-25
4
14
 
5
15
  - Fix redeclaration of JS constants
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,14 @@
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
10
  PROFILE_OUT_STALE_SECONDS = 60 * 60
9
- PROFILE_OUT_RELATIVE_DIRNAME = "tmp/dial/profiles/"
11
+ PROFILE_OUT_RELATIVE_DIRNAME = "tmp/dial/profiles"
10
12
 
11
- PROSOPITE_IGNORE_QUERIES = [/schema_migrations/]
12
- PROSOPITE_LOG_RELATIVE_PATHNAME = "log/dial/prosopite.log"
13
+ PROSOPITE_IGNORE_QUERIES = [/schema_migrations/].freeze
14
+ PROSOPITE_LOG_RELATIVE_DIRNAME = "log/dial"
15
+ PROSOPITE_LOG_FILENAME = "#{Util.uuid}_prosopite_#{PROGRAM_ID}.log".freeze
13
16
  end
@@ -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: 1000, hooks: [:memory_usage, :rails] do
28
+ ::Vernier.profile out: profile_out_pathname, interval: 500, allocation_interval: 10_000, 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 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
@@ -18,13 +18,19 @@ module Dial
18
18
  end
19
19
  end
20
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
24
+ end
25
+ end
26
+
21
27
  initializer "dial.set_up_prosopite" do |app|
22
28
  app.config.after_initialize do
23
29
  if ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
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 - PROFILE_OUT_STALE_SECONDS
54
+ end
55
+ end
56
+
57
+ def profile_out_dir_pathname
58
+ ::Rails.root.join 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.6"
4
+ VERSION = "0.1.8"
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.6
4
+ version: 0.1.8
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
  - - ">="