skylight 5.0.0.beta2 → 5.0.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: 2b77ca3f00aac3011421d279776acf31f9259debecb3319689250e49fbd3310f
4
- data.tar.gz: 6cee4d4a09aa991c3e5d3cf65bc9534797f59fc8951a7d088025271068d9e9cc
3
+ metadata.gz: 76c9ece1445d480897ecc306024fe939dacb94c14a02e68f7e33f5d722955284
4
+ data.tar.gz: 839b19ed8b3846003b3a54e5d0f3e327b0f969f2672b267dcaf4d1aa27df6254
5
5
  SHA512:
6
- metadata.gz: 98649cab11fb628dcfdade4a7dc5507d7640f5f90b6aa9230305fc1c5261d5f73ff3014bc399595f4bc6c85fafb334668f1b81e9020ea5e1f644f3e60ad966d7
7
- data.tar.gz: edfacb9d5322768a0dbdd9acbdd31ea5305a077dee1a24076078c448c73a9cd7b0b1889ead269db9e661ed49d11e02e2da38326bad90448b12db72718b949a81
6
+ metadata.gz: 2cbbcfd4a159b6abfa976f9d8ad4a87317973955d058408b681b1564d6d54bacadcb0e60c4bbac9ea03383dfed6d9355ac953a0b636c50a60ff99e52bcb3c5a2
7
+ data.tar.gz: b338f0d0a22d0b904600d050f217758d3b07c28e66c88c6f5eb961cd8701750b58a7175e3e9e31dad604c6c58c2d1b22197517c239192f41b9579c5c08a9ca5b
data/CHANGELOG.md CHANGED
@@ -1,24 +1,41 @@
1
- ## 5.0.0.beta2
1
+ ## 5.0.1 (March 11, 2021)
2
+ * [IMPROVEMENT] Use argument-forwarding (...) where available in custom instrumentation
3
+
4
+ ## 5.0.0 (March 5, 2021)
5
+
6
+ * [FEATURE] Add normalizer for Shrine events (thanks @janko!)
2
7
  * [FEATURE] Source Locations detection and reporting is now enabled by default (can be disabled with `SKYLIGHT_ENABLE_SOURCE_LOCATIONS=false`)
3
- * [BREAKING] Rename `environment` keyword argument to `priority_key`. Note `env` has not changed.
4
- * [BREAKING] Drop support for Ruby 2.4
5
- * [IMPROVEMENT] Improved Delayed::Job probe
8
+ * [FEATURE] Configuration for the Source Locations caches via `SYLIGHT_SOURCE_LOCATION_CACHE_SIZE`
6
9
 
7
- ## 5.0.0.beta
8
- * [BREAKING] Merge skylight-core into skylight. All classes previously namespaced under `Skylight::Core` have been moved to `Skylight`.
9
- * [BREAKING] Remove `Skylight::Util::Inflector`
10
- * [BREAKING] Drop support for Rails 4
11
- * [BREAKING] Drop support for Ruby 2.3
10
+ * [IMPROVEMENT] Improve keyword argument handling in Skylight::Helpers (thanks @lukebooth!)
11
+ * [IMPROVEMENT] Replace a Kernel.puts with Skylight.log (thanks @johnnyshields!)
12
+ * [IMPROVEMENT] Various updates to the SQL lexer
13
+ * [IMPROVEMENT] Reduce volume of log messages sent to the native logger in debug level
14
+ * [IMPROVEMENT] Optimizations for the Source Locations extension
15
+ * [IMPROVEMENT] Improved Delayed::Job probe
12
16
  * [IMPROVEMENT] Maintain method visibility when instrumenting with `instrument_method`
13
17
  * [IMPROVEMENT] Update probes to use `Module#prepend` where possible
14
18
  * [IMPROVEMENT] New tokio-based skylightd
15
19
  * [IMPROVEMENT] Support `render_layout` notifications in Rails 6.1
16
20
  * [IMPROVEMENT] Support `ActionMailer::MailDeliveryJob` in Rails 6.1
17
- * [IMPROVEMENT] Better logging config
21
+ * [IMPROVEMENT] Better logging config. `SKYLIGHT_NATIVE_LOG_LEVEL` now defaults to `warn`.
22
+
23
+ * [BREAKING] Rename `environment` keyword argument to `priority_key`. Note `env` has not changed.
24
+ * [BREAKING] Drop support for Ruby 2.4
25
+ * [BREAKING] Merge skylight-core into skylight. All classes previously namespaced under `Skylight::Core` have been moved to `Skylight`.
26
+ * [BREAKING] Remove `Skylight::Util::Inflector`
27
+ * [BREAKING] Drop support for Rails 4
28
+ * [BREAKING] Drop support for Ruby 2.3
29
+
30
+ * [BUGFIX] Fix issue with missing metadata in MongoDB probe
31
+ * [BUGFIX] Resolve an inability to parse certain SQL queries containing arrays
18
32
  * [BUGFIX] Allow multiple probes to be registered under the same key
19
33
  * [BUGFIX] Do not refer to Redis constant until the probe is installed
20
34
  * [BUGFIX] Fix nested calls to `Normalizers::Faraday::Request.disable`
21
35
 
36
+ ## 4.3.2 (December 14, 2020)
37
+ * [BUGFIX] Backport an ActionView fix from Skylight 5 (makes Skylight 4 compatible with Rails 6.1)
38
+
22
39
  ## 4.3.1 (June 24, 2020)
23
40
  * [BUGFIX] Fix an issue in which `Mime::NullType` would result in an exception
24
41
 
data/CONTRIBUTING.md CHANGED
@@ -16,7 +16,7 @@ If you prefer to run tests in your own environment, you may do so as follows:
16
16
 
17
17
  ```shell
18
18
  # Select a gemfile and bundle install
19
- export BUNDLE_GEMFILE=$PWD/gemfiles/Gemfile.rails-5.2.x
19
+ export BUNDLE_GEMFILE=$PWD/gemfiles/rails-5.2.x/Gemfile
20
20
  bundle install
21
21
  # Run the test suite (takes 5-10 minutes)
22
22
  bundle exec rspec
data/ext/libskylight.yml CHANGED
@@ -1,6 +1,8 @@
1
- version: "5.0.0-45b02dd"
1
+ # commit: ea59cc7bdbbee0f69d1cf7e69827974a9ea67645
2
+ ---
3
+ version: "5.0.0-488d432"
2
4
  checksums:
3
- x86-linux: "218a51683cbe3f6e7f1d31097a7e732c6bac3e3780a707312f8441dd45d8f3a6"
4
- x86_64-linux: "2426968fef8cd7fe0fd0ea582fd8098db78025ce936bac9d72b7753995bd1ea9"
5
- x86_64-linux-musl: "ca07748d43fac0b4a05b38b5ce0fc4cb7e43469a183919c5d9980a8b2e0b01ab"
6
- x86_64-darwin: "8b19eb2ffd19f78ee6e547b37fcf5cad2e49aa9a8bc2b9615a791ccfc91c2552"
5
+ x86-linux: "3c16b6db1508f35720258551783fbcd30fd231638bad316ea76748d659838399"
6
+ x86_64-linux: "94383aa3359c3f2e9c0e3c16ee263d46c5673dd255f8842e6acadf5ec3131c06"
7
+ x86_64-linux-musl: "d2e2e2e61c321315f9bcaa157426f33aef8ffc2330ba46b2cdcbd9442e65f728"
8
+ x86_64-darwin: "bcc925d0bcbae83a484f35dbc9729dcf262e1f3a8c29b8d387d0f58ad8f3afa3"
data/lib/skylight.rb CHANGED
@@ -101,7 +101,7 @@ module Skylight
101
101
  message: e.message, klass: e.class)]
102
102
  end
103
103
 
104
- if config&.respond_to?("log_#{level}") && config&.respond_to?(:log_trace)
104
+ if config.respond_to?("log_#{level}") && config.respond_to?(:log_trace)
105
105
  config.send("log_#{level}", message)
106
106
  config.log_trace e.backtrace.join("\n")
107
107
  else
@@ -194,10 +194,17 @@ module Skylight
194
194
  opts = {}
195
195
  end
196
196
 
197
+ # NOTE: unless we have `:internal` (indicating a built-in Skylight instrument block),
198
+ # or we already have a `source_file` or `source_line` (probably set by `instrument_method`),
199
+ # we set the caller location to the second item on the stack
200
+ # (immediate caller of the `instrument` method).
201
+ unless opts[:source_file] || opts[:source_line] || opts[:internal]
202
+ opts = opts.merge(sk_instrument_location: caller_locations(1..1).first)
203
+ end
204
+
197
205
  meta ||= {}
198
206
 
199
207
  instrumenter.extensions.process_instrument_options(opts, meta)
200
-
201
208
  instrumenter.instrument(category, title, desc, meta, &block)
202
209
  end
203
210
 
data/lib/skylight/api.rb CHANGED
@@ -9,8 +9,11 @@ module Skylight
9
9
  attr_reader :config
10
10
 
11
11
  class Error < StandardError; end
12
+
12
13
  class Unauthorized < Error; end
14
+
13
15
  class Conflict < Error; end
16
+
14
17
  class CreateFailed < Error
15
18
  attr_reader :res
16
19
 
@@ -44,6 +44,7 @@ module Skylight
44
44
  -"LOG_LEVEL" => :log_level,
45
45
  -"ALERT_LOG_FILE" => :alert_log_file,
46
46
  -"NATIVE_LOG_FILE" => :native_log_file,
47
+ -"NATIVE_LOG_LEVEL" => :native_log_level,
47
48
  -"LOG_SQL_PARSE_ERRORS" => :log_sql_parse_errors,
48
49
 
49
50
  # == Proxy ==
@@ -110,7 +111,8 @@ module Skylight
110
111
  -"HEROKU_DYNO_INFO_PATH" => :'heroku.dyno_info_path',
111
112
 
112
113
  # == Source Location ==
113
- -"SOURCE_LOCATION_IGNORED_GEMS" => :source_location_ignored_gems
114
+ -"SOURCE_LOCATION_IGNORED_GEMS" => :source_location_ignored_gems,
115
+ -"SOURCE_LOCATION_CACHE_SIZE" => :source_location_cache_size
114
116
  }.freeze
115
117
 
116
118
  KEY_TO_NATIVE_ENV = {
@@ -143,6 +145,7 @@ module Skylight
143
145
  log_level: -"INFO",
144
146
  alert_log_file: -"-",
145
147
  log_sql_parse_errors: true,
148
+ native_log_level: -"warn",
146
149
 
147
150
  # Features
148
151
  enable_segments: true,
@@ -551,23 +554,13 @@ module Skylight
551
554
  when /^warn$/i then Logger::WARN
552
555
  when /^error$/i then Logger::ERROR
553
556
  when /^fatal$/i then Logger::FATAL
554
- else Logger::ERROR
557
+ else Logger::ERROR # rubocop:disable Lint/DuplicateBranch
555
558
  end
556
559
  end
557
560
  end
558
561
 
559
562
  def native_log_level
560
- @native_log_level ||=
561
- if trace?
562
- "trace"
563
- else
564
- case log_level
565
- when Logger::DEBUG then "debug"
566
- when Logger::INFO then "info"
567
- when Logger::WARN then "warn"
568
- else "error"
569
- end
570
- end
563
+ get(:native_log_level).to_s.downcase
571
564
  end
572
565
 
573
566
  def logger
@@ -690,7 +683,7 @@ module Skylight
690
683
  corrected_config = res.corrected_config
691
684
 
692
685
  # Use defaults if no corrected config is available. This will happen if the request failed.
693
- corrected_config ||= Hash[SERVER_VALIDATE.map { |k| [k, self.class.default_values.fetch(k)] }]
686
+ corrected_config ||= SERVER_VALIDATE.map { |k| [k, self.class.default_values.fetch(k)] }.to_h
694
687
 
695
688
  config_to_update = corrected_config.reject { |k, v| get(k) == v }
696
689
  unless config_to_update.empty?
@@ -13,10 +13,10 @@ module Skylight
13
13
  end
14
14
 
15
15
  Skylight.module_eval <<-RUBY, __FILE__, __LINE__ + 1
16
- class #{name}Error < NativeError
17
- def self.code; #{code}; end
18
- def self.message; #{message.to_json}; end
19
- end
16
+ class #{name}Error < NativeError # class SqlLexError < NativeError
17
+ def self.code; #{code}; end # def self.code; 4; end
18
+ def self.message; #{message.to_json}; end # def self.message; "Failed to lex SQL query."; end
19
+ end # end
20
20
  RUBY
21
21
 
22
22
  klass = Skylight.const_get("#{name}Error")
@@ -11,11 +11,13 @@ module Skylight
11
11
  include Util::Logging
12
12
 
13
13
  META_KEYS = %i[source_location source_file source_line].freeze
14
+ MAX_CALLER_DEPTH = 75
14
15
 
15
16
  def initialize(*)
16
17
  super
17
- @caller_cache = Util::LruCache.new(100)
18
- @instance_method_source_location_cache = Util::LruCache.new(100)
18
+ cache_size = (config[:source_location_cache_size] || 1000).to_i
19
+ @caller_cache = Util::LruCache.new(cache_size)
20
+ @instance_method_source_location_cache = Util::LruCache.new(cache_size)
19
21
  gem_require_trie # memoize this at startup
20
22
  end
21
23
 
@@ -35,6 +37,7 @@ module Skylight
35
37
  source_line = opts[:source_line] || opts[:meta]&.[](:source_line)
36
38
  source_name_hint, const_name, method_name = opts[:source_location_hint] ||
37
39
  opts[:meta]&.[](:source_location_hint)
40
+ instrument_location = opts[:sk_instrument_location]
38
41
 
39
42
  if source_location
40
43
  meta[:source_location] = source_location
@@ -45,6 +48,9 @@ module Skylight
45
48
  elsif source_file
46
49
  meta[:source_file] = source_file
47
50
  meta[:source_line] = source_line
51
+ elsif instrument_location && project_path?(instrument_location.absolute_path)
52
+ meta[:source_file] = instrument_location.absolute_path
53
+ meta[:source_line] = instrument_location.lineno
48
54
  else
49
55
  warn "Ignoring source_line without source_file" if source_line
50
56
  if (location = find_caller(cache_key: opts.hash))
@@ -134,10 +140,14 @@ module Skylight
134
140
  end
135
141
 
136
142
  def find_caller(cache_key: nil)
143
+ # starting at 4 to skip Skylight extension processing logic
144
+ locations = ::Kernel.caller_locations(4..MAX_CALLER_DEPTH)
145
+
137
146
  if cache_key
138
- @caller_cache.fetch(cache_key) { find_caller_inner }
147
+ localized_cache_key = [cache_key, locations.map(&:lineno)].hash
148
+ @caller_cache.fetch(localized_cache_key) { find_caller_inner(locations) }
139
149
  else
140
- find_caller_inner
150
+ find_caller_inner(locations)
141
151
  end
142
152
  end
143
153
 
@@ -236,11 +246,12 @@ module Skylight
236
246
  nil
237
247
  end
238
248
 
239
- def find_caller_inner
249
+ def find_caller_inner(locations)
240
250
  # Start at file before this one
241
251
  # NOTE: We could start farther back now to avoid more Skylight files
242
- caller_locations(1).find do |l|
243
- find_source_gem(l.absolute_path) || project_path?(l.absolute_path)
252
+ locations.find do |l|
253
+ absolute_path = l.absolute_path
254
+ find_source_gem(absolute_path) || project_path?(absolute_path)
244
255
  end
245
256
  end
246
257
 
@@ -12,7 +12,8 @@ module Skylight
12
12
  # @return [Hash] a hash containing `:category`, `:title`, and `:annotations`
13
13
  def self.build_opts(method, _scheme, host, _port, _path, _query)
14
14
  { category: "api.http.#{method.downcase}",
15
- title: "#{method.upcase} #{host}" }
15
+ title: "#{method.upcase} #{host}",
16
+ internal: true }
16
17
  end
17
18
  end
18
19
  end
@@ -14,7 +14,7 @@ module Skylight
14
14
 
15
15
  if (opts = @__sk_instrument_next_method)
16
16
  @__sk_instrument_next_method = nil
17
- instrument_method(name, opts)
17
+ instrument_method(name, **opts)
18
18
  end
19
19
  end
20
20
 
@@ -24,7 +24,7 @@ module Skylight
24
24
 
25
25
  if (opts = @__sk_instrument_next_method)
26
26
  @__sk_instrument_next_method = nil
27
- instrument_class_method(name, opts)
27
+ instrument_class_method(name, **opts)
28
28
  end
29
29
  end
30
30
 
@@ -77,14 +77,12 @@ module Skylight
77
77
  # do_expensive_stuff
78
78
  # end
79
79
  # end
80
- def instrument_method(*args)
81
- opts = args.pop if args.last.is_a?(Hash)
82
-
80
+ def instrument_method(*args, **opts)
83
81
  if (name = args.pop)
84
82
  title = "#{self}##{name}"
85
- __sk_instrument_method_on(self, name, title, opts || {})
83
+ __sk_instrument_method_on(self, name, title, **opts)
86
84
  else
87
- @__sk_instrument_next_method = opts || {}
85
+ @__sk_instrument_next_method = opts
88
86
  end
89
87
  end
90
88
 
@@ -123,14 +121,18 @@ module Skylight
123
121
  #
124
122
  # instrument_class_method :my_method, title: 'Expensive work'
125
123
  # end
126
- def instrument_class_method(name, opts = {})
124
+ def instrument_class_method(name, **opts)
125
+ # NOTE: If the class is defined anonymously and then assigned to a variable this code
126
+ # will not be aware of the updated name.
127
127
  title = "#{self}.#{name}"
128
- __sk_instrument_method_on(__sk_singleton_class, name, title, opts || {})
128
+ __sk_instrument_method_on(__sk_singleton_class, name, title, **opts)
129
129
  end
130
130
 
131
131
  private
132
132
 
133
- def __sk_instrument_method_on(klass, name, title, opts)
133
+ HAS_ARGUMENT_FORWARDING = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0")
134
+
135
+ def __sk_instrument_method_on(klass, name, title, **opts)
134
136
  category = (opts[:category] || "app.method").to_s
135
137
  title = (opts[:title] || title).to_s
136
138
  desc = opts[:description].to_s if opts[:description]
@@ -143,33 +145,58 @@ module Skylight
143
145
  # source_file and source_line to be removed from the trace span before it is submitted.
144
146
  source_file, source_line = klass.instance_method(name).source_location
145
147
 
146
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
147
- alias_method :"before_instrument_#{name}", :"#{name}"
148
-
149
- def #{name}(*args, &blk)
150
- span = Skylight.instrument(
151
- category: :"#{category}",
152
- title: #{title.inspect},
153
- description: #{desc.inspect},
154
- source_file: #{source_file.inspect},
155
- source_line: #{source_line.inspect})
148
+ # We should strongly prefer using the new argument-forwarding syntax (...) where available.
149
+ # In Ruby 2.7, the following are known to be syntax errors:
150
+ #
151
+ # - mixing positional arguments with argument forwarding (e.g., send(:method_name, ...))
152
+ # - calling a setter method with multiple arguments, unless dispatched via send or public_send.
153
+ #
154
+ # So it is possible, though not recommended, to define setter methods that take multiple arguments,
155
+ # keywords, and/or blocks. Unfortunately, this means that for setters, we still need to explicitly
156
+ # forward the different argument types.
157
+ is_setter_method = name.to_s.end_with?("=")
156
158
 
157
- meta = {}
158
- begin
159
- send(:before_instrument_#{name}, *args, &blk)
160
- rescue Exception => e
161
- meta[:exception_object] = e
162
- raise e
163
- ensure
164
- Skylight.done(span, meta) if span
165
- end
159
+ arg_string =
160
+ if HAS_ARGUMENT_FORWARDING
161
+ is_setter_method ? "*args, **kwargs, &blk" : "..."
162
+ else
163
+ "*args, &blk"
166
164
  end
167
165
 
168
- if protected_method_defined?(:"before_instrument_#{name}")
169
- protected :"#{name}"
170
- elsif private_method_defined?(:"before_instrument_#{name}")
171
- private :"#{name}"
166
+ original_method_dispatch =
167
+ if is_setter_method
168
+ "self.send(:before_instrument_#{name}, #{arg_string})"
169
+ else
170
+ "before_instrument_#{name}(#{arg_string})"
172
171
  end
172
+
173
+ klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
174
+ alias_method :"before_instrument_#{name}", :"#{name}" # alias_method :"before_instrument_process", :"process"
175
+ def #{name}(#{arg_string}) # def process(*args, **kwargs, &blk)
176
+ span = Skylight.instrument( # span = Skylight.instrument(
177
+ category: :"#{category}", # category: :"app.method",
178
+ title: #{title.inspect}, # title: "process",
179
+ description: #{desc.inspect}, # description: "Process data",
180
+ source_file: #{source_file.inspect}, # source_file: "myapp/lib/processor.rb",
181
+ source_line: #{source_line.inspect}) # source_line: 123)
182
+ #
183
+ meta = {} # meta = {}
184
+ #
185
+ begin # begin
186
+ #{original_method_dispatch} # self.before_instrument_process(...)
187
+ rescue Exception => e # rescue Exception => e
188
+ meta[:exception_object] = e # meta[:exception_object] = e
189
+ raise e # raise e
190
+ ensure # ensure
191
+ Skylight.done(span, meta) if span # Skylight.done(span, meta) if span
192
+ end # end
193
+ end # end
194
+ #
195
+ if protected_method_defined?(:"before_instrument_#{name}") # if protected_method_defined?(:"before_instrument_process")
196
+ protected :"#{name}" # protected :"process"
197
+ elsif private_method_defined?(:"before_instrument_#{name}") # elsif private_method_defined?(:"before_instrument_process")
198
+ private :"#{name}" # private :"process"
199
+ end # end
173
200
  RUBY
174
201
  end
175
202
 
@@ -10,7 +10,7 @@ module Skylight
10
10
  @closed = false
11
11
  end
12
12
 
13
- def respond_to_missing?(name, include_all = false) # rubocop:disable Lint/MissingSuper, Style/OptionalBooleanParameter
13
+ def respond_to_missing?(name, include_all = false)
14
14
  return false if name.to_s !~ /^to_ary$/
15
15
 
16
16
  @body.respond_to?(name, include_all)
@@ -101,7 +101,7 @@ module Skylight
101
101
 
102
102
  # @api private
103
103
  def self.check_install_errors(config)
104
- # Note: An unsupported arch doesn't count as an error.
104
+ # NOTE: An unsupported arch doesn't count as an error.
105
105
  install_log = File.expand_path("../../ext/install.log", __dir__)
106
106
 
107
107
  if File.exist?(install_log) && File.read(install_log) =~ /ERROR/
@@ -69,7 +69,8 @@ module Skylight
69
69
  return cat if cat == :skip
70
70
 
71
71
  meta ||= {}
72
- process_meta(trace, name, payload, meta, cache_key: ret.hash)
72
+ cache_key = ret.hash
73
+ process_meta(trace, name, payload, meta, cache_key: cache_key)
73
74
 
74
75
  [cat, title, desc, meta]
75
76
  end
@@ -144,7 +145,8 @@ module Skylight
144
145
  graphiti/resolve
145
146
  graphiti/render
146
147
  graphql/base
147
- sequel/sql].each do |file|
148
+ sequel/sql
149
+ shrine].each do |file|
148
150
  require "skylight/normalizers/#{file}"
149
151
  end
150
152
  end
@@ -0,0 +1,34 @@
1
+ module Skylight
2
+ module Normalizers
3
+ class Shrine < Normalizer
4
+ TITLES = {
5
+ "upload.shrine" => "Upload",
6
+ "download.shrine" => "Download",
7
+ "open.shrine" => "Open",
8
+ "exists.shrine" => "Exists",
9
+ "delete.shrine" => "Delete",
10
+ "metadata.shrine" => "Metadata",
11
+ "mime_type.shrine" => "MIME Type",
12
+ "image_dimensions.shrine" => "Image Dimensions",
13
+ "signature.shrine" => "Signature",
14
+ "extension.shrine" => "Extension",
15
+ "derivation.shrine" => "Derivation",
16
+ "derivatives.shrine" => "Derivatives",
17
+ "data_uri.shrine" => "Data URI",
18
+ "remote_url.shrine" => "Remote URL"
19
+ }.freeze
20
+
21
+ TITLES.each_key do |key|
22
+ register key
23
+ end
24
+
25
+ def normalize(_trace, name, _payload)
26
+ title = ["Shrine", TITLES[name]].join(" ")
27
+
28
+ cat = "app.#{name.split('.').reverse.join('.')}"
29
+
30
+ [cat, title, nil]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -18,7 +18,13 @@ module Skylight
18
18
  rescue
19
19
  block.call
20
20
  else
21
- Skylight.instrument(title: "Enqueue #{name}", category: CAT, description: desc, &block)
21
+ Skylight.instrument(
22
+ title: "Enqueue #{name}",
23
+ category: CAT,
24
+ description: desc,
25
+ internal: true,
26
+ &block
27
+ )
22
28
  end
23
29
 
24
30
  self.class.instance_eval do
@@ -85,7 +85,8 @@ module Skylight
85
85
  opts = {
86
86
  category: "app.delayed_job.job",
87
87
  title: format_source(*source_meta),
88
- meta: { source_location_hint: source_meta }
88
+ meta: { source_location_hint: source_meta },
89
+ internal: true
89
90
  }
90
91
 
91
92
  Skylight.instrument(opts) { __getobj__.perform }
@@ -26,7 +26,7 @@ module Skylight
26
26
 
27
27
  def disable_skylight_probe(class_name)
28
28
  klass = ::ActiveSupport::Inflector.safe_constantize("Skylight::Probes::#{class_name}::Probe")
29
- (klass ? klass.disable { yield } : yield).tap { puts "re-enabling: #{klass}" }
29
+ (klass ? klass.disable { yield } : yield).tap { Skylight.log(:debug, "re-enabling: #{klass}") }
30
30
  end
31
31
  end
32
32
  end
@@ -6,7 +6,7 @@ module Skylight
6
6
  # Middleware for Excon that instruments requests
7
7
  class Middleware < ::Excon::Middleware::Base
8
8
  def initialize(*)
9
- @requests = {}
9
+ @requests = {}.compare_by_identity
10
10
  super
11
11
  end
12
12
 
@@ -38,19 +38,19 @@ module Skylight
38
38
  scheme = datum[:scheme]
39
39
  host = datum[:host]
40
40
  # TODO: Maybe don't show other default ports like 443
41
- port = datum[:port] != 80 ? datum[:port] : nil
41
+ port = datum[:port] == 80 ? nil : datum[:port]
42
42
  path = datum[:path]
43
43
  query = datum[:query]
44
44
 
45
45
  opts = Formatters::HTTP.build_opts(method, scheme, host, port, path, query)
46
46
 
47
- @requests[datum.object_id] = Skylight.instrument(opts)
47
+ @requests[datum] = Skylight.instrument(opts)
48
48
  rescue Exception => e
49
49
  Skylight.error "failed to begin instrumentation for Excon; msg=%s", e.message
50
50
  end
51
51
 
52
52
  def end_instrumentation(datum)
53
- if (request = @requests.delete(datum.object_id))
53
+ if (request = @requests.delete(datum))
54
54
  meta = {}
55
55
  if datum[:error].is_a?(Exception)
56
56
  meta[:exception_object] = datum[:error]
@@ -113,7 +113,8 @@ module Skylight
113
113
  category: CAT,
114
114
  title: title,
115
115
  description: payload.empty? ? nil : payload.to_json,
116
- meta: { database: event.database_name }
116
+ meta: { database: event.database_name },
117
+ internal: true
117
118
  }
118
119
 
119
120
  @events[event.operation_id] = Skylight.instrument(opts)
@@ -6,12 +6,14 @@ module Skylight
6
6
 
7
7
  PIPELINED_OPTS = {
8
8
  category: "db.redis.pipelined".freeze,
9
- title: "PIPELINE".freeze
9
+ title: "PIPELINE".freeze,
10
+ internal: true
10
11
  }.freeze
11
12
 
12
13
  MULTI_OPTS = {
13
14
  category: "db.redis.multi".freeze,
14
- title: "MULTI".freeze
15
+ title: "MULTI".freeze,
16
+ internal: true
15
17
  }.freeze
16
18
 
17
19
  module ClientInstrumentation
@@ -22,7 +24,8 @@ module Skylight
22
24
 
23
25
  opts = {
24
26
  category: "db.redis.command",
25
- title: command_name.upcase.to_s
27
+ title: command_name.upcase.to_s,
28
+ internal: true
26
29
  }
27
30
 
28
31
  Skylight.instrument(opts) { super }
@@ -6,7 +6,7 @@ module Skylight
6
6
  GC_CAT = "noise.gc".freeze
7
7
  SYNTHETIC = "<synthetic>".freeze
8
8
 
9
- META_KEYS = %i[mute_children].freeze
9
+ META_KEYS = %i[mute_children database].freeze
10
10
 
11
11
  include Util::Logging
12
12
 
@@ -340,8 +340,10 @@ module Skylight
340
340
  def validate_meta(meta)
341
341
  unknown_keys = meta.keys - allowed_meta_keys
342
342
  if unknown_keys.any?
343
- warn "Unknown meta keys will be ignored; keys=#{unknown_keys.inspect}"
344
- unknown_keys.each { |key| meta.delete(key) }
343
+ unknown_keys.each do |key|
344
+ maybe_warn("unknown_meta:#{key}", "Unknown meta key will be ignored; key=#{key.inspect}")
345
+ meta.delete(key)
346
+ end
345
347
  end
346
348
  end
347
349
 
@@ -192,7 +192,7 @@ module Skylight
192
192
  body.dig(*key.split(".")) if body.is_a?(Hash)
193
193
  end
194
194
 
195
- def respond_to_missing?(name, include_all = false) # rubocop:disable Style/OptionalBooleanParameter
195
+ def respond_to_missing?(name, include_all = false)
196
196
  super || body.respond_to?(name, include_all)
197
197
  end
198
198
 
@@ -4,20 +4,20 @@ module Skylight
4
4
  def instrumenter_method(name, block: false)
5
5
  if block
6
6
  module_eval <<-RUBY, __FILE__, __LINE__ + 1
7
- def #{name}(*args)
8
- unless instrumenter
9
- return yield if block_given?
10
- return
11
- end
12
-
13
- instrumenter.#{name}(*args) { yield }
14
- end
7
+ def #{name}(*args) # def mute(*args)
8
+ unless instrumenter # unless instrumenter
9
+ return yield if block_given? # return yield if block_given?
10
+ return # return
11
+ end # end
12
+ #
13
+ instrumenter.#{name}(*args) { yield } # instrumenter.mute(*args) { yield }
14
+ end # end
15
15
  RUBY
16
16
  else
17
17
  module_eval <<-RUBY, __FILE__, __LINE__ + 1
18
- def #{name}(*args)
19
- instrumenter&.#{name}(*args)
20
- end
18
+ def #{name}(*args) # def config(*args)
19
+ instrumenter&.#{name}(*args) # instrumenter&.config(*args)
20
+ end # end
21
21
  RUBY
22
22
  end
23
23
  end
@@ -13,7 +13,7 @@ module Skylight
13
13
 
14
14
  # Try to avoid writing to STDOUT/STDERR twice
15
15
  logger_logdev = @logger.instance_variable_get(:@logdev)
16
- logger_out = logger_logdev&.respond_to?(:dev) ? logger_logdev.dev : nil
16
+ logger_out = logger_logdev.respond_to?(:dev) ? logger_logdev.dev : nil
17
17
  if logger_out != $stdout && logger_out != $stderr
18
18
  @logger.<<(*args)
19
19
  end
@@ -114,10 +114,10 @@ module Skylight
114
114
 
115
115
  if logger
116
116
  if logger.respond_to?(level)
117
- if !args.empty?
118
- logger.send level, format(msg, *args)
119
- else
117
+ if args.empty?
120
118
  logger.send level, msg
119
+ else
120
+ logger.send level, format(msg, *args)
121
121
  end
122
122
  return # rubocop:disable Style/RedundantReturn
123
123
  else
@@ -56,7 +56,7 @@ module Skylight
56
56
  "so"
57
57
  when /windows|cygwin/
58
58
  "dll"
59
- else
59
+ else # rubocop:disable Lint/DuplicateBranch
60
60
  "so"
61
61
  end
62
62
 
@@ -3,5 +3,5 @@ module Skylight
3
3
  # for compatibility with semver when it is parsed by the rust agent.
4
4
  # This string will be transformed in the gemspec to "5.0.0.alpha"
5
5
  # to conform with rubygems.
6
- VERSION = "5.0.0-beta2".freeze
6
+ VERSION = "5.0.1".freeze
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skylight
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta2
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilde, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-26 00:00:00.000000000 Z
11
+ date: 2021-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -142,14 +142,28 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 0.79.0
145
+ version: 1.11.0
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 0.79.0
152
+ version: 1.11.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.21.2
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.21.2
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: timecop
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -260,6 +274,7 @@ files:
260
274
  - lib/skylight/normalizers/graphql/base.rb
261
275
  - lib/skylight/normalizers/render.rb
262
276
  - lib/skylight/normalizers/sequel/sql.rb
277
+ - lib/skylight/normalizers/shrine.rb
263
278
  - lib/skylight/normalizers/sql.rb
264
279
  - lib/skylight/probes.rb
265
280
  - lib/skylight/probes/action_controller.rb
@@ -363,11 +378,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
363
378
  version: '2.5'
364
379
  required_rubygems_version: !ruby/object:Gem::Requirement
365
380
  requirements:
366
- - - ">"
381
+ - - ">="
367
382
  - !ruby/object:Gem::Version
368
- version: 1.3.1
383
+ version: '0'
369
384
  requirements: []
370
- rubygems_version: 3.1.2
385
+ rubygems_version: 3.2.3
371
386
  signing_key:
372
387
  specification_version: 4
373
388
  summary: Skylight is a smart profiler for Rails, Sinatra, and other Ruby apps.