app_profiler 0.2.0 → 0.2.1

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: 1c36371d12c24dfed23e6e492b5c3912e01480bfd7a5973bf1f311a86adc86d3
4
- data.tar.gz: 1b78da495c55cee24ab6b0d6f8d8194ca6cfb27030de7a4ba90db37fa60e3988
3
+ metadata.gz: daf174f3e936f7c9e466d16f75cc866f779944ae781e39501dae6d51cd74da42
4
+ data.tar.gz: 42871b642bf002450af142941793c41a1bfd76d6b6c6932b45e6cca9c287cb58
5
5
  SHA512:
6
- metadata.gz: bd4e66293f491f25caba2a352b509012344bdc6e04c880cb4c3d60d00f3dc38cab50b9c59cf0cbe14c36adc2591610bd004addc28521cf077b7d3b7c91585947
7
- data.tar.gz: 036c9de32a86b5e99e1d244fe1200aa3e0dabdf6d610d91c34aa6621bf8a194b9a769a8a9bae254432d2e2bfae67b137a1209c4214bb2c2ce774aa9db9bea907
6
+ metadata.gz: cf696efe9cfe2582aafd201e30fe6f82aae17f1b137e93a7d2e2b2c34256f4ace88de0d771fc398844c1010999b5c9424f1b2ab0026395ee88b2ad440a88d54a
7
+ data.tar.gz: eb47ff8a3c0131065400a702d447fb8c170c9d2769860921be61d082ad6affe1ca714bbd211fd2cfe2aec78a89a57bbd32fc76d950d5fa1531feb5b43e29dac9
@@ -3,10 +3,6 @@
3
3
  module AppProfiler
4
4
  module Backend
5
5
  class BaseBackend
6
- def self.name
7
- raise NotImplementedError
8
- end
9
-
10
6
  def run(params = {}, &block)
11
7
  raise NotImplementedError
12
8
  end
@@ -31,6 +27,10 @@ module AppProfiler
31
27
  def run_lock
32
28
  @run_lock ||= Mutex.new
33
29
  end
30
+
31
+ def name
32
+ raise NotImplementedError
33
+ end
34
34
  end
35
35
 
36
36
  protected
@@ -16,8 +16,10 @@ module AppProfiler
16
16
  :object,
17
17
  ].freeze
18
18
 
19
- def self.name
20
- :stackprof
19
+ class << self
20
+ def name
21
+ :stackprof
22
+ end
21
23
  end
22
24
 
23
25
  def run(params = {})
@@ -44,7 +46,7 @@ module AppProfiler
44
46
  StackProf.start(**DEFAULTS, **params)
45
47
  rescue => error
46
48
  AppProfiler.logger.info(
47
- "[Profiler] failed to start the profiler error_class=#{error.class} error_message=#{error.message}"
49
+ "[Profiler] failed to start the profiler error_class=#{error.class} error_message=#{error.message}",
48
50
  )
49
51
  release_run_lock
50
52
  # This is a boolean instead of nil because StackProf#start returns a
@@ -66,7 +68,7 @@ module AppProfiler
66
68
  BaseProfile.from_stackprof(stackprof_profile)
67
69
  rescue => error
68
70
  AppProfiler.logger.info(
69
- "[Profiler] failed to obtain the profile error_class=#{error.class} error_message=#{error.message}"
71
+ "[Profiler] failed to obtain the profile error_class=#{error.class} error_message=#{error.message}",
70
72
  )
71
73
  nil
72
74
  end
@@ -15,8 +15,10 @@ module AppProfiler
15
15
  :retained,
16
16
  ].freeze
17
17
 
18
- def self.name
19
- :vernier
18
+ class << self
19
+ def name
20
+ :vernier
21
+ end
20
22
  end
21
23
 
22
24
  def run(params = {})
@@ -48,7 +50,7 @@ module AppProfiler
48
50
  @collector.start
49
51
  rescue => error
50
52
  AppProfiler.logger.info(
51
- "[Profiler] failed to start the profiler error_class=#{error.class} error_message=#{error.message}"
53
+ "[Profiler] failed to start the profiler error_class=#{error.class} error_message=#{error.message}",
52
54
  )
53
55
  release_run_lock
54
56
  # This is a boolean instead of nil to be consistent with the stackprof backend behaviour
@@ -83,7 +85,7 @@ module AppProfiler
83
85
  BaseProfile.from_vernier(data)
84
86
  rescue => error
85
87
  AppProfiler.logger.info(
86
- "[Profiler] failed to obtain the profile error_class=#{error.class} error_message=#{error.message}"
88
+ "[Profiler] failed to obtain the profile error_class=#{error.class} error_message=#{error.message}",
87
89
  )
88
90
  nil
89
91
  end
@@ -14,7 +14,7 @@ module AppProfiler
14
14
  append_headers(
15
15
  response,
16
16
  upload: profile_upload,
17
- autoredirect: autoredirect.nil? ? AppProfiler.autoredirect : autoredirect
17
+ autoredirect: autoredirect.nil? ? AppProfiler.autoredirect : autoredirect,
18
18
  ) if response
19
19
  end
20
20
  end
@@ -41,7 +41,7 @@ module AppProfiler
41
41
  profile,
42
42
  response: response,
43
43
  autoredirect: params.autoredirect,
44
- async: params.async
44
+ async: params.async,
45
45
  )
46
46
 
47
47
  response
@@ -15,20 +15,22 @@ module AppProfiler
15
15
 
16
16
  delegate :[], to: :@data
17
17
 
18
- # This function should not be called if `StackProf.results` returns nil.
19
- def self.from_stackprof(data)
20
- options = INTERNAL_METADATA_KEYS.map { |key| [key, data[:metadata]&.delete(key)] }.to_h
18
+ class << self
19
+ # This function should not be called if `StackProf.results` returns nil.
20
+ def from_stackprof(data)
21
+ options = INTERNAL_METADATA_KEYS.map { |key| [key, data[:metadata]&.delete(key)] }.to_h
21
22
 
22
- StackprofProfile.new(data, **options).tap do |profile|
23
- raise ArgumentError, "invalid profile data" unless profile.valid?
23
+ StackprofProfile.new(data, **options).tap do |profile|
24
+ raise ArgumentError, "invalid profile data" unless profile.valid?
25
+ end
24
26
  end
25
- end
26
27
 
27
- def self.from_vernier(data)
28
- options = INTERNAL_METADATA_KEYS.map { |key| [key, data[:meta]&.delete(key)] }.to_h
28
+ def from_vernier(data)
29
+ options = INTERNAL_METADATA_KEYS.map { |key| [key, data[:meta]&.delete(key)] }.to_h
29
30
 
30
- VernierProfile.new(data, **options).tap do |profile|
31
- raise ArgumentError, "invalid profile data" unless profile.valid?
31
+ VernierProfile.new(data, **options).tap do |profile|
32
+ raise ArgumentError, "invalid profile data" unless profile.valid?
33
+ end
32
34
  end
33
35
  end
34
36
 
@@ -44,7 +46,7 @@ module AppProfiler
44
46
  AppProfiler.storage.upload(self).tap do |upload|
45
47
  if upload && defined?(upload.url)
46
48
  AppProfiler.logger.info(
47
- <<~INFO.squish
49
+ <<~INFO.squish,
48
50
  [Profiler] data uploaded:
49
51
  profile_url=#{upload.url}
50
52
  profile_viewer_url=#{AppProfiler.profile_url(upload)}
@@ -54,7 +56,7 @@ module AppProfiler
54
56
  end
55
57
  rescue => error
56
58
  AppProfiler.logger.info(
57
- "[Profiler] failed to upload profile error_class=#{error.class} error_message=#{error.message}"
59
+ "[Profiler] failed to upload profile error_class=#{error.class} error_message=#{error.message}",
58
60
  )
59
61
  nil
60
62
  end
@@ -78,6 +80,10 @@ module AppProfiler
78
80
  @data
79
81
  end
80
82
 
83
+ def metadata
84
+ @data[:metadata]
85
+ end
86
+
81
87
  def mode
82
88
  raise NotImplementedError
83
89
  end
@@ -41,6 +41,7 @@ module AppProfiler
41
41
  AppProfiler.profile_enqueue_failure = app.config.app_profiler.profile_enqueue_failure
42
42
  AppProfiler.after_process_queue = app.config.app_profiler.after_process_queue
43
43
  AppProfiler.backend = app.config.app_profiler.profiler_backend || :stackprof
44
+ AppProfiler.forward_metadata_on_upload = app.config.app_profiler.forward_metadata_on_upload || false
44
45
  end
45
46
 
46
47
  initializer "app_profiler.add_middleware" do |app|
@@ -280,7 +280,7 @@ module AppProfiler
280
280
  @listen_thread = nil
281
281
 
282
282
  @logger.info(
283
- "[AppProfiler::Server] listening on addr=#{@transport.socket.addr}"
283
+ "[AppProfiler::Server] listening on addr=#{@transport.socket.addr}",
284
284
  )
285
285
  @pid = Process.pid
286
286
  end
@@ -342,7 +342,7 @@ module AppProfiler
342
342
  end
343
343
  rescue => e
344
344
  @logger.error(
345
- "[AppProfiler::Server] exception #{e} responding to request #{request}: #{e.message}"
345
+ "[AppProfiler::Server] exception #{e} responding to request #{request}: #{e.message}",
346
346
  )
347
347
  ensure
348
348
  session.close
@@ -6,12 +6,14 @@ module AppProfiler
6
6
  class_attribute :bucket_name, default: "profiles"
7
7
  class_attribute :credentials, default: {}
8
8
 
9
- def self.upload(_profile)
10
- raise NotImplementedError
11
- end
9
+ class << self
10
+ def upload(_profile)
11
+ raise NotImplementedError
12
+ end
12
13
 
13
- def self.enqueue_upload(_profile)
14
- raise NotImplementedError
14
+ def enqueue_upload(_profile)
15
+ raise NotImplementedError
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -15,6 +15,10 @@ module AppProfiler
15
15
  def upload(profile, _params = {})
16
16
  file = profile.file.open
17
17
 
18
+ metadata = if AppProfiler.forward_metadata_on_upload && profile.metadata.present?
19
+ profile.metadata
20
+ end
21
+
18
22
  ActiveSupport::Notifications.instrument(
19
23
  "gcs_upload.app_profiler",
20
24
  file_size: file.size,
@@ -24,6 +28,7 @@ module AppProfiler
24
28
  gcs_filename(profile),
25
29
  content_type: "application/json",
26
30
  content_encoding: "gzip",
31
+ metadata: metadata,
27
32
  )
28
33
  ensure
29
34
  profile.file.unlink
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppProfiler
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
@@ -9,17 +9,57 @@ module AppProfiler
9
9
  class BaseMiddleware
10
10
  class Sanitizer < Rails::HTML::Sanitizer.best_supported_vendor.safe_list_sanitizer
11
11
  self.allowed_tags = Set.new([
12
- "strong", "em", "b", "i", "p", "code", "pre", "tt", "samp", "kbd", "var", "sub",
13
- "sup", "dfn", "cite", "big", "small", "address", "hr", "br", "div", "span", "h1",
14
- "h2", "h3", "h4", "h5", "h6", "ul", "ol", "li", "dl", "dt", "dd", "abbr", "acronym",
15
- "a", "img", "blockquote", "del", "ins", "script",
12
+ "strong",
13
+ "em",
14
+ "b",
15
+ "i",
16
+ "p",
17
+ "code",
18
+ "pre",
19
+ "tt",
20
+ "samp",
21
+ "kbd",
22
+ "var",
23
+ "sub",
24
+ "sup",
25
+ "dfn",
26
+ "cite",
27
+ "big",
28
+ "small",
29
+ "address",
30
+ "hr",
31
+ "br",
32
+ "div",
33
+ "span",
34
+ "h1",
35
+ "h2",
36
+ "h3",
37
+ "h4",
38
+ "h5",
39
+ "h6",
40
+ "ul",
41
+ "ol",
42
+ "li",
43
+ "dl",
44
+ "dt",
45
+ "dd",
46
+ "abbr",
47
+ "acronym",
48
+ "a",
49
+ "img",
50
+ "blockquote",
51
+ "del",
52
+ "ins",
53
+ "script",
16
54
  ])
17
55
  end
18
56
 
19
57
  private_constant(:Sanitizer)
20
58
 
21
- def self.id(file)
22
- file.basename.to_s.delete_suffix(".json")
59
+ class << self
60
+ def id(file)
61
+ file.basename.to_s.delete_suffix(".json")
62
+ end
23
63
  end
24
64
 
25
65
  def initialize(app)
@@ -87,7 +127,7 @@ module AppProfiler
87
127
  </p>
88
128
  HTML
89
129
  end
90
- end
130
+ end,
91
131
  )
92
132
  end
93
133
 
@@ -12,7 +12,7 @@ module AppProfiler
12
12
  def initialize(app)
13
13
  super
14
14
  @speedscope = Rack::File.new(
15
- File.join(AppProfiler.root, "node_modules/speedscope/dist/release")
15
+ File.join(AppProfiler.root, "node_modules/speedscope/dist/release"),
16
16
  )
17
17
  end
18
18
 
@@ -33,7 +33,7 @@ module AppProfiler
33
33
  end || raise(ArgumentError)
34
34
 
35
35
  render(
36
- <<~HTML
36
+ <<~HTML,
37
37
  <script type="text/javascript">
38
38
  var graph = #{profile.read};
39
39
  var json = JSON.stringify(graph);
@@ -49,7 +49,7 @@ module AppProfiler
49
49
  exec("which", "yarn", silent: true) do
50
50
  raise(
51
51
  YarnError,
52
- <<~MSG.squish
52
+ <<~MSG.squish,
53
53
  `yarn` command not found.
54
54
  Please install `yarn` or make it available in PATH.
55
55
  MSG
data/lib/app_profiler.rb CHANGED
@@ -61,6 +61,7 @@ module AppProfiler
61
61
  mattr_reader :profile_enqueue_success, default: nil
62
62
  mattr_reader :profile_enqueue_failure, default: nil
63
63
  mattr_reader :after_process_queue, default: nil
64
+ mattr_accessor :forward_metadata_on_upload, default: false
64
65
 
65
66
  class << self
66
67
  def run(*args, backend: nil, **kwargs, &block)
@@ -70,7 +71,7 @@ module AppProfiler
70
71
  profiler.run(*args, **kwargs, &block)
71
72
  rescue BackendError => e
72
73
  logger.error(
73
- "[AppProfiler.run] exception #{e} configuring backend #{backend}: #{e.message}"
74
+ "[AppProfiler.run] exception #{e} configuring backend #{backend}: #{e.message}",
74
75
  )
75
76
  yield
76
77
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gannon McGibbon
@@ -10,10 +10,10 @@ authors:
10
10
  - Jon Simpson
11
11
  - Kevin Jalbert
12
12
  - Scott Francis
13
- autorequire:
13
+ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2024-06-18 00:00:00.000000000 Z
16
+ date: 2024-08-01 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: activesupport
@@ -127,7 +127,7 @@ dependencies:
127
127
  - - ">="
128
128
  - !ruby/object:Gem::Version
129
129
  version: '0'
130
- description:
130
+ description:
131
131
  email:
132
132
  - gems@shopify.com
133
133
  executables: []
@@ -165,7 +165,7 @@ homepage: https://github.com/Shopify/app_profiler
165
165
  licenses: []
166
166
  metadata:
167
167
  allowed_push_host: https://rubygems.org
168
- post_install_message:
168
+ post_install_message:
169
169
  rdoc_options: []
170
170
  require_paths:
171
171
  - lib
@@ -180,8 +180,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
180
  - !ruby/object:Gem::Version
181
181
  version: '0'
182
182
  requirements: []
183
- rubygems_version: 3.5.11
184
- signing_key:
183
+ rubygems_version: 3.5.16
184
+ signing_key:
185
185
  specification_version: 4
186
186
  summary: Collect performance profiles for your Rails application.
187
187
  test_files: []