app_profiler 0.2.0 → 0.2.1

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: 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: []