scout_apm 5.0.0 → 5.2.0

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