scout_apm 5.0.0 → 5.2.0

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: f9a94a38d6b06a02e34ce7923e8084976739cc8d0fba1adfbc606f88b0bdf4d7
4
- data.tar.gz: aebe73f5379911e8691be2771b3a3fc3f5fbdd4779f2038f6a6f6e0ed38e1e20
3
+ metadata.gz: 81ad3b683899407ed049b7267d6d79a84d5afac011445d1078f4342c345c7ace
4
+ data.tar.gz: 29e141854923fa21c57ca3fcc7ca9e4cc96dbd741c36c0586e7fd2cd7a8186f8
5
5
  SHA512:
6
- metadata.gz: d8850b1365747879effcfe383d0b438070069d2b625365dc8ea61db7c72cf6840cdf73675c95aea7a7688750dbcb41efec1b7320232312172bc49be9b207d421
7
- data.tar.gz: f3d389aa73f8b4090627843410c610edc1c5fa88740587136dbd8277d3ddfa5360e61d0d256ae23db7cf53f20b482d3f283541c077efcd2d12032e5f3f72f4e2
6
+ metadata.gz: a857678f6d91c709fbbdfb30409339f37e99cd83260cec9d3808f81638245de03cf4b0721270203f0ee619cc56b06fc3baa795a10e859c3068e0e2c36a2247b2
7
+ data.tar.gz: 972da0997d251c5704291e60e390916a417de3036aadcada469540acd20520f4edd95b3b76da9202734755bc37c3a9a22e44916c23e74c9199d3c6a7a2447797
@@ -36,6 +36,9 @@ jobs:
36
36
  bundler: 1.17.3
37
37
  - ruby: 2.7
38
38
  - ruby: 3.0
39
+ - ruby: 3.0
40
+ gemfile: gems/sidekiq.gemfile
41
+ test_features: "sidekiq_install"
39
42
 
40
43
  env:
41
44
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,27 @@
1
+ # Unreleased
2
+
3
+ # 5.2.0
4
+
5
+ * Use Sidekiq lifecycle hooks to start Scout agent on Sidekiq start. (#449)
6
+
7
+ # 5.1.1
8
+
9
+ * Improvements to SqlServer scrubbing in SqlSanitizer (#422)
10
+
11
+ # 5.1.0
12
+
13
+ * Specify correct (MIT) license in Gemspec (#430)
14
+ * Install HTTP::Client instruments (#420)
15
+ * Sanitize FROM jsonb_as_recordset AS correctly in Postgres (#332)
16
+ * Call to_h on `ActiveRecord::Base.configurations` (#434)
17
+ * Allow loading of trusted `config/scout_apm.yml` via `YAML.unsafe_load` if available (#435)
18
+ * Better exception handling when loading config (#436)
19
+ * Check for nil other_metric_set in merge_external_service_metrics (#437)
20
+ * Log `warn` in InstructionSequence only if SCOUT_LOG_LEVEL is debug (#438)
21
+ * Check for Parser::TreeRewriter before loading AutoInstruments to avoid LoadError (#440)
22
+ * Fall back to STDERR upon exception in build_logger (#441)
23
+
24
+
1
25
  # 5.0.0
2
26
 
3
27
  * Add External Service metrics reporting (#403)
@@ -0,0 +1,4 @@
1
+ eval_gemfile("../Gemfile")
2
+
3
+ # https://github.com/scoutapp/scout_apm_ruby/issues/449
4
+ gem 'sidekiq', '>= 6.5.0'
@@ -10,10 +10,10 @@ module ScoutApm
10
10
  new_code = Rails.rewrite(path)
11
11
  return self.compile(new_code, path, path)
12
12
  rescue
13
- warn "Failed to apply auto-instrumentation to #{path}: #{$!}"
13
+ warn "Failed to apply auto-instrumentation to #{path}: #{$!}" if ENV['SCOUT_LOG_LEVEL'].to_s.downcase == "debug"
14
14
  end
15
15
  elsif Rails.ignore?(path)
16
- warn "AutoInstruments are ignored for path=#{path}."
16
+ warn "AutoInstruments are ignored for path=#{path}." if ENV['SCOUT_LOG_LEVEL'].to_s.downcase == "debug"
17
17
  end
18
18
 
19
19
  return self.compile_file(path)
@@ -37,17 +37,11 @@ module ScoutApm
37
37
  end
38
38
 
39
39
  def install_processor
40
- require 'sidekiq/processor' # sidekiq v4 has not loaded this file by this point
41
-
42
- ::Sidekiq::Processor.class_eval do
43
- def initialize_with_scout(*args)
40
+ ::Sidekiq.configure_server do |config|
41
+ config.on(:startup) do
44
42
  agent = ::ScoutApm::Agent.instance
45
43
  agent.start
46
- initialize_without_scout(*args)
47
44
  end
48
-
49
- alias_method :initialize_without_scout, :initialize
50
- alias_method :initialize, :initialize_with_scout
51
45
  end
52
46
  end
53
47
  end
@@ -432,7 +432,7 @@ module ScoutApm
432
432
  begin
433
433
  raw_file = File.read(@resolved_file_path)
434
434
  erb_file = ERB.new(raw_file).result(binding)
435
- parsed_yaml = YAML.load(erb_file)
435
+ parsed_yaml = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(erb_file) : YAML.load(erb_file)
436
436
  file_settings = parsed_yaml[app_environment]
437
437
 
438
438
  if file_settings.is_a? Hash
@@ -443,8 +443,8 @@ module ScoutApm
443
443
  logger.info("Couldn't find configuration in #{@resolved_file_path} for environment: #{app_environment}. Configuration in ENV will still be applied.")
444
444
  @file_loaded = false
445
445
  end
446
- rescue Exception => e # Explicit `Exception` handling to catch SyntaxError and anything else that ERB or YAML may throw
447
- logger.info("Failed loading configuration file (#{@resolved_file_path}): #{e.message}. ScoutAPM will continue starting with configuration from ENV and defaults")
446
+ rescue ScoutApm::AllExceptionsExceptOnesWeMustNotRescue => e # Everything except the most important exceptions we should never interfere with
447
+ logger.info("Failed loading configuration file (#{@resolved_file_path}): ScoutAPM will continue starting with configuration from ENV and defaults. Exception was #{e.class}: #{e.message}#{e.backtrace.map { |bt| "\n #{bt}" }.join('')}")
448
448
  @file_loaded = false
449
449
  end
450
450
  end
@@ -0,0 +1,12 @@
1
+ module ScoutApm
2
+ module AllExceptionsExceptOnesWeMustNotRescue
3
+ # Borrowed from https://github.com/rspec/rspec-support/blob/v3.8.0/lib/rspec/support.rb#L132-L140
4
+ # These exceptions are dangerous to rescue as rescuing them
5
+ # would interfere with things we should not interfere with.
6
+ AVOID_RESCUING = [NoMemoryError, SignalException, Interrupt, SystemExit]
7
+
8
+ def self.===(exception)
9
+ AVOID_RESCUING.none? { |ar| ar === exception }
10
+ end
11
+ end
12
+ end
@@ -78,7 +78,7 @@ module ScoutApm
78
78
  end
79
79
 
80
80
  if adapter.nil?
81
- adapter = ActiveRecord::Base.configurations[env]["adapter"]
81
+ adapter = ActiveRecord::Base.configurations.to_h[env]["adapter"]
82
82
  end
83
83
 
84
84
  return adapter
@@ -32,6 +32,7 @@ module ScoutApm
32
32
  install_instrument(ScoutApm::Instruments::NetHttp)
33
33
  install_instrument(ScoutApm::Instruments::Typhoeus)
34
34
  install_instrument(ScoutApm::Instruments::HttpClient)
35
+ install_instrument(ScoutApm::Instruments::HTTP)
35
36
  install_instrument(ScoutApm::Instruments::Memcached)
36
37
  install_instrument(ScoutApm::Instruments::Redis)
37
38
  install_instrument(ScoutApm::Instruments::InfluxDB)
@@ -69,7 +69,11 @@ module ScoutApm
69
69
  private
70
70
 
71
71
  def build_logger
72
- logger_class.new(@log_destination) rescue logger_class.new
72
+ logger_class.new(@log_destination)
73
+ rescue => e
74
+ logger = ::Logger.new(STDERR)
75
+ logger.error("Error while building ScoutApm logger: #{e.message}. Falling back to STDERR")
76
+ logger
73
77
  end
74
78
 
75
79
  def logger_class
@@ -217,6 +217,7 @@ module ScoutApm
217
217
 
218
218
  def initialize(timestamp, context)
219
219
  @timestamp = timestamp
220
+ @context = context
220
221
 
221
222
  @request_traces = ScoredItemSet.new(context.config.value('max_traces'))
222
223
  @job_traces = ScoredItemSet.new(context.config.value('max_traces'))
@@ -230,6 +231,11 @@ module ScoutApm
230
231
  @jobs = Hash.new
231
232
  end
232
233
 
234
+ def logger
235
+ @context.logger
236
+ end
237
+ private :logger
238
+
233
239
  # Merges another StoreReportingPeriod into this one
234
240
  def merge(other)
235
241
  self.
@@ -266,7 +272,11 @@ module ScoutApm
266
272
  end
267
273
 
268
274
  def merge_external_service_metrics!(other_metric_set)
269
- external_service_metric_set.combine!(other_metric_set)
275
+ if other_metric_set.nil?
276
+ logger.debug("Missing other_metric_set for merge_external_service_metrics - skipping.")
277
+ else
278
+ external_service_metric_set.combine!(other_metric_set)
279
+ end
270
280
  self
271
281
  end
272
282
 
@@ -12,11 +12,13 @@ module ScoutApm
12
12
 
13
13
  PSQL_VAR_INTERPOLATION = %r|\[\[.*\]\]\s*\z|.freeze
14
14
  PSQL_REMOVE_STRINGS = /'(?:[^']|'')*'/.freeze
15
+ PSQL_REMOVE_JSON_STRINGS = /:"(?:[^"]|"")*"/.freeze
15
16
  PSQL_REMOVE_INTEGERS = /(?<!LIMIT )\b\d+\b/.freeze
16
17
  PSQL_AFTER_SELECT = /(?:SELECT\s+).*?(?:WHERE|FROM\z)/im.freeze # Should be everything between a FROM and a WHERE
17
18
  PSQL_PLACEHOLDER = /\$\d+/.freeze
18
19
  PSQL_IN_CLAUSE = /IN\s+\(\?[^\)]*\)/.freeze
19
20
  PSQL_AFTER_FROM = /(?:FROM\s+).*?(?:WHERE|\z)/im.freeze # Should be everything between a FROM and a WHERE
21
+ PSQL_AFTER_FROM_AS = /(?:FROM\s+).*?(?:AS|\z)/im.freeze # Should be everything between a FROM and AS without WHERE
20
22
  PSQL_AFTER_JOIN = /(?:JOIN\s+).*?\z/im.freeze
21
23
  PSQL_AFTER_WHERE = /(?:WHERE\s+).*?(?:SELECT|\z)/im.freeze
22
24
  PSQL_AFTER_SET = /(?:SET\s+).*?(?:WHERE|\z)/im.freeze
@@ -32,7 +34,8 @@ module ScoutApm
32
34
  SQLITE_REMOVE_INTEGERS = /(?<!LIMIT )\b\d+\b/.freeze
33
35
 
34
36
  # => "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE (age > 50) ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY', N'@0 int', @0 = 10"
35
- SQLSERVER_EXECUTESQL = /EXEC sp_executesql N'(.*?)'.*/
37
+ SQLSERVER_REMOVE_EXECUTESQL = /EXEC sp_executesql (N')?/.freeze
38
+ SQLSERVER_REMOVE_STRINGS = /'(?:[^']|'')*'/.freeze
36
39
  SQLSERVER_REMOVE_INTEGERS = /(?<!LIMIT )\b(?<!@)\d+\b/.freeze
37
40
  SQLSERVER_IN_CLAUSE = /IN\s+\(\?[^\)]*\)/.freeze
38
41
 
@@ -65,7 +68,8 @@ module ScoutApm
65
68
  private
66
69
 
67
70
  def to_s_sqlserver
68
- sql.gsub!(SQLSERVER_EXECUTESQL, '\1')
71
+ sql.gsub!(SQLSERVER_REMOVE_EXECUTESQL, '')
72
+ sql.gsub!(SQLSERVER_REMOVE_STRINGS, '?')
69
73
  sql.gsub!(SQLSERVER_REMOVE_INTEGERS, '?')
70
74
  sql.gsub!(SQLSERVER_IN_CLAUSE, 'IN (?)')
71
75
  sql
@@ -76,6 +80,7 @@ module ScoutApm
76
80
  sql.gsub!(PSQL_VAR_INTERPOLATION, '')
77
81
  # sql.gsub!(PSQL_REMOVE_STRINGS, '?')
78
82
  sql.gsub!(PSQL_AFTER_WHERE) {|c| c.gsub(PSQL_REMOVE_STRINGS, '?')}
83
+ sql.gsub!(PSQL_AFTER_FROM_AS) {|c| c.gsub(PSQL_REMOVE_JSON_STRINGS, ':"?"')}
79
84
  sql.gsub!(PSQL_AFTER_JOIN) {|c| c.gsub(PSQL_REMOVE_STRINGS, '?')}
80
85
  sql.gsub!(PSQL_AFTER_SET) {|c| c.gsub(PSQL_REMOVE_STRINGS, '?')}
81
86
  sql.gsub!(PSQL_REMOVE_INTEGERS, '?')
@@ -1,3 +1,3 @@
1
1
  module ScoutApm
2
- VERSION = "5.0.0"
2
+ VERSION = "5.2.0"
3
3
  end
data/lib/scout_apm.rb CHANGED
@@ -27,6 +27,7 @@ require 'rusage'
27
27
  #####################################
28
28
  require 'scout_apm/version'
29
29
 
30
+ require 'scout_apm/exceptions'
30
31
  require 'scout_apm/debug'
31
32
  require 'scout_apm/tracked_request'
32
33
  require 'scout_apm/layer'
@@ -80,6 +81,7 @@ require 'scout_apm/histogram'
80
81
 
81
82
  require 'scout_apm/instruments/net_http'
82
83
  require 'scout_apm/instruments/http_client'
84
+ require 'scout_apm/instruments/http'
83
85
  require 'scout_apm/instruments/typhoeus'
84
86
  require 'scout_apm/instruments/moped'
85
87
  require 'scout_apm/instruments/mongoid'
@@ -221,8 +223,12 @@ if defined?(Rails) && defined?(Rails::VERSION) && defined?(Rails::VERSION::MAJOR
221
223
  ScoutApm::Agent.instance.install
222
224
 
223
225
  if ScoutApm::Agent.instance.context.config.value("auto_instruments")
224
- ScoutApm::Agent.instance.context.logger.debug("AutoInstruments is enabled.")
225
- require 'scout_apm/auto_instrument'
226
+ if defined?(Parser::TreeRewriter)
227
+ ScoutApm::Agent.instance.context.logger.debug("AutoInstruments is enabled.")
228
+ require 'scout_apm/auto_instrument'
229
+ else # AutoInstruments is turned on, but we don't he the prerequisites to use it
230
+ ScoutApm::Agent.instance.context.logger.debug("AutoInstruments is enabled, but Parser::TreeRewriter is missing. Update 'parser' gem to >= 2.5.0.")
231
+ end
226
232
  else
227
233
  ScoutApm::Agent.instance.context.logger.debug("AutoInstruments is disabled.")
228
234
  end
data/scout_apm.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.homepage = "https://github.com/scoutapp/scout_apm_ruby"
11
11
  s.summary = "Ruby application performance monitoring"
12
12
  s.description = "Monitors Ruby apps and reports detailed metrics on performance to Scout."
13
- s.license = "Proprietary (See LICENSE.md)"
13
+ s.license = "MIT"
14
14
 
15
15
  s.files = `git ls-files`.split("\n")
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -3,8 +3,25 @@ require 'scout_apm/request_manager'
3
3
  require 'scout_apm/background_job_integrations/sidekiq'
4
4
 
5
5
  class SidekiqTest < Minitest::Test
6
+ SidekiqIntegration = ScoutApm::BackgroundJobIntegrations::Sidekiq
6
7
  SidekiqMiddleware = ScoutApm::BackgroundJobIntegrations::SidekiqMiddleware
7
8
 
9
+ ########################################
10
+ # Install
11
+ ########################################
12
+ if (ENV["SCOUT_TEST_FEATURES"] || "").include?("sidekiq_install")
13
+ require 'sidekiq'
14
+
15
+ # Sidekiq::CLI needs to be defined in order for `Sidekiq.configure_server` to work
16
+ Sidekiq::CLI = nil
17
+
18
+ def test_starts_on_startup
19
+ ::ScoutApm::Agent.any_instance.expects(:start)
20
+ SidekiqIntegration.new.install
21
+ Sidekiq.options[:lifecycle_events][:startup].map(&:call)
22
+ end
23
+ end
24
+
8
25
  ########################################
9
26
  # Middleware
10
27
  ########################################
@@ -123,27 +123,27 @@ module ScoutApm
123
123
  end
124
124
 
125
125
  def test_sqlserver_integers
126
- skip "SQLServer Support requires Ruby 1.9+ For Regexes"
127
-
128
126
  sql = "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE (age > 50) ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY', N'@0 int', @0 = 10"
129
127
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :sqlserver }
130
- assert_equal %q|SELECT [users].* FROM [users] WHERE (age > ?) ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @0 ROWS ONLY|, ss.to_s
128
+ assert_equal "SELECT [users].* FROM [users] WHERE (age > ?) ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @0 ROWS ONLY?@0 int', @0 = ?", ss.to_s
131
129
  end
132
130
 
133
131
  def test_sqlserver_strings
134
- skip "SQLServer Support requires Ruby 1.9+ For Regexes"
132
+ sql = "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE first_name = N'john' AND last_name = N'doe' ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY', N'@0 int', @0 = 10"
133
+ ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :sqlserver }
134
+ assert_equal "SELECT [users].* FROM [users] WHERE first_name = N? AND last_name = N? ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @0 ROWS ONLY?@0 int', @0 = ?", ss.to_s
135
+ end
135
136
 
136
- sql = "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE [users].[email] = @0 ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @1 ROWS ONLY', N'@0 nvarchar(4000), @1 int', @0 = N'foo', @1 = 10"
137
+ def test_sqlserver_strings_no_executesql
138
+ sql = "EXEC Authenticate @username = N'abraham.lincoln', @password = N'somepassword!', @token = NULL, @app_name = N'Central Auth Service', @log_login = true, @ip_address = N'127.0.0.1', @external_type = NULL, @external_success = NULL"
137
139
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :sqlserver }
138
- assert_equal %q|SELECT [users].* FROM [users] WHERE [users].[email] = @0 ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @1 ROWS ONLY|, ss.to_s
140
+ assert_equal "EXEC Authenticate @username = N?, @password = N?, @token = NULL, @app_name = N?, @log_login = true, @ip_address = N?, @external_type = NULL, @external_success = NULL", ss.to_s
139
141
  end
140
142
 
141
143
  def test_sqlserver_in_clause
142
- skip "SQLServer Support requires Ruby 1.9+ For Regexes"
143
-
144
144
  sql = "EXEC sp_executesql N'SELECT [users].* FROM [users] WHERE (id IN (1,2,3)) ORDER BY [users].[id] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY', N'@0 int', @0 = 10"
145
145
  ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :sqlserver }
146
- assert_equal %q|SELECT [users].* FROM [users] WHERE (id IN (?)) ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @0 ROWS ONLY|, ss.to_s
146
+ assert_equal "SELECT [users].* FROM [users] WHERE (id IN (?)) ORDER BY [users].[id] ASC OFFSET ? ROWS FETCH NEXT @0 ROWS ONLY?@0 int', @0 = ?", ss.to_s
147
147
  end
148
148
 
149
149
  def test_scrubs_invalid_encoding
@@ -194,6 +194,17 @@ module ScoutApm
194
194
  WHERE (title = ?)|, ss.to_s
195
195
  end
196
196
 
197
+ def test_postgres_insert_select_from_jsonb_to_recordset_with_as
198
+ sql = %q|
199
+ INSERT INTO foos(foo_id, bar_id, external_id, email_address, created_at, updated_at)
200
+ SELECT 123, 456, external_id, email_address, NOW(), NOW()
201
+ FROM jsonb_to_recordset($${"items":[{"external_id":1234,"email_address":"test@domain.com"}]}$$::jsonb->'items')
202
+ AS t(external_id integer, email_address varchar)
203
+ |
204
+ ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :postgres }
205
+ assert_equal %q|INSERT INTO foos(foo_id, bar_id, external_id, email_address, created_at, updated_at) SELECT ?, ?, external_id, email_address, NOW(), NOW() FROM jsonb_to_recordset($${"items":[{"external_id":?,"email_address":"?"}]}$$::jsonb->'items') AS t(external_id integer, email_address varchar)|, ss.to_s
206
+ end
207
+
197
208
  def assert_faster_than(target_seconds)
198
209
  t1 = ::Time.now
199
210
  yield
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Haynes
8
8
  - Andre Lewis
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-11-02 00:00:00.000000000 Z
12
+ date: 2022-06-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -237,6 +237,7 @@ files:
237
237
  - gems/rails4.gemfile
238
238
  - gems/rails5.gemfile
239
239
  - gems/rails6.gemfile
240
+ - gems/sidekiq.gemfile
240
241
  - gems/typhoeus.gemfile
241
242
  - lib/scout_apm.rb
242
243
  - lib/scout_apm/agent.rb
@@ -280,6 +281,7 @@ files:
280
281
  - lib/scout_apm/error_service/periodic_work.rb
281
282
  - lib/scout_apm/error_service/railtie.rb
282
283
  - lib/scout_apm/error_service/sidekiq.rb
284
+ - lib/scout_apm/exceptions.rb
283
285
  - lib/scout_apm/extensions/config.rb
284
286
  - lib/scout_apm/extensions/transaction_callback_payload.rb
285
287
  - lib/scout_apm/external_service_metric_set.rb
@@ -469,9 +471,9 @@ files:
469
471
  - test/unit/utils/scm.rb
470
472
  homepage: https://github.com/scoutapp/scout_apm_ruby
471
473
  licenses:
472
- - Proprietary (See LICENSE.md)
474
+ - MIT
473
475
  metadata: {}
474
- post_install_message:
476
+ post_install_message:
475
477
  rdoc_options: []
476
478
  require_paths:
477
479
  - lib
@@ -487,8 +489,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
487
489
  - !ruby/object:Gem::Version
488
490
  version: '0'
489
491
  requirements: []
490
- rubygems_version: 3.0.3
491
- signing_key:
492
+ rubygems_version: 3.3.7
493
+ signing_key:
492
494
  specification_version: 4
493
495
  summary: Ruby application performance monitoring
494
496
  test_files: []