scout_apm 5.0.0 → 5.1.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 +4 -4
- data/CHANGELOG.markdown +16 -0
- data/lib/scout_apm/auto_instrument/instruction_sequence.rb +2 -2
- data/lib/scout_apm/config.rb +3 -3
- data/lib/scout_apm/exceptions.rb +12 -0
- data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +1 -1
- data/lib/scout_apm/instrument_manager.rb +1 -0
- data/lib/scout_apm/logger.rb +5 -1
- data/lib/scout_apm/store.rb +5 -1
- data/lib/scout_apm/utils/sql_sanitizer.rb +3 -0
- data/lib/scout_apm/version.rb +1 -1
- data/lib/scout_apm.rb +8 -2
- data/scout_apm.gemspec +1 -1
- data/test/unit/sql_sanitizer_test.rb +11 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a569967a27143fe36a506e8757eeda10f2de6cf85567cb2af8c08993b558abb
|
4
|
+
data.tar.gz: 49a5277948f6dab053268af7f912f8905b78d2173c79cfb1c3e9a87288e33113
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 523767ea43b634748ff16ee974fd6bb659ddced673fbd9106e6f3a07ed8e9d78ec30b88094dac2aff4a374af719691249534aa471a7fc993813018d92bf71333
|
7
|
+
data.tar.gz: f67a78084a1280b497422f4dc35ea3ed5afb1cfbde55c79c4020b11e407674f803ea8d1dec8803bb6bf1fcc8a4e11ac728621cf2f45b8d2d35956497d55a78d7
|
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
# Unreleased
|
2
|
+
|
3
|
+
# 5.1.0
|
4
|
+
|
5
|
+
* Specify correct (MIT) license in Gemspec (#430)
|
6
|
+
* Install HTTP::Client instruments (#420)
|
7
|
+
* Sanitize FROM jsonb_as_recordset AS correctly in Postgres (#332)
|
8
|
+
* Call to_h on `ActiveRecord::Base.configurations` (#434)
|
9
|
+
* Allow loading of trusted `config/scout_apm.yml` via `YAML.unsafe_load` if available (#435)
|
10
|
+
* Better exception handling when loading config (#436)
|
11
|
+
* Check for nil other_metric_set in merge_external_service_metrics (#437)
|
12
|
+
* Log `warn` in InstructionSequence only if SCOUT_LOG_LEVEL is debug (#438)
|
13
|
+
* Check for Parser::TreeRewriter before loading AutoInstruments to avoid LoadError (#440)
|
14
|
+
* Fall back to STDERR upon exception in build_logger (#441)
|
15
|
+
|
16
|
+
|
1
17
|
# 5.0.0
|
2
18
|
|
3
19
|
* Add External Service metrics reporting (#403)
|
@@ -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)
|
data/lib/scout_apm/config.rb
CHANGED
@@ -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
|
447
|
-
logger.info("Failed loading configuration file (#{@resolved_file_path}):
|
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
|
@@ -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)
|
data/lib/scout_apm/logger.rb
CHANGED
@@ -69,7 +69,11 @@ module ScoutApm
|
|
69
69
|
private
|
70
70
|
|
71
71
|
def build_logger
|
72
|
-
logger_class.new(@log_destination)
|
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
|
data/lib/scout_apm/store.rb
CHANGED
@@ -266,7 +266,11 @@ module ScoutApm
|
|
266
266
|
end
|
267
267
|
|
268
268
|
def merge_external_service_metrics!(other_metric_set)
|
269
|
-
|
269
|
+
if other_metric_set.nil?
|
270
|
+
logger.debug("Missing other_metric_set for merge_external_service_metrics - skipping.")
|
271
|
+
else
|
272
|
+
external_service_metric_set.combine!(other_metric_set)
|
273
|
+
end
|
270
274
|
self
|
271
275
|
end
|
272
276
|
|
@@ -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
|
@@ -76,6 +78,7 @@ module ScoutApm
|
|
76
78
|
sql.gsub!(PSQL_VAR_INTERPOLATION, '')
|
77
79
|
# sql.gsub!(PSQL_REMOVE_STRINGS, '?')
|
78
80
|
sql.gsub!(PSQL_AFTER_WHERE) {|c| c.gsub(PSQL_REMOVE_STRINGS, '?')}
|
81
|
+
sql.gsub!(PSQL_AFTER_FROM_AS) {|c| c.gsub(PSQL_REMOVE_JSON_STRINGS, ':"?"')}
|
79
82
|
sql.gsub!(PSQL_AFTER_JOIN) {|c| c.gsub(PSQL_REMOVE_STRINGS, '?')}
|
80
83
|
sql.gsub!(PSQL_AFTER_SET) {|c| c.gsub(PSQL_REMOVE_STRINGS, '?')}
|
81
84
|
sql.gsub!(PSQL_REMOVE_INTEGERS, '?')
|
data/lib/scout_apm/version.rb
CHANGED
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
|
-
|
225
|
-
|
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 = "
|
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")
|
@@ -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,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Haynes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-11-
|
12
|
+
date: 2021-11-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -280,6 +280,7 @@ files:
|
|
280
280
|
- lib/scout_apm/error_service/periodic_work.rb
|
281
281
|
- lib/scout_apm/error_service/railtie.rb
|
282
282
|
- lib/scout_apm/error_service/sidekiq.rb
|
283
|
+
- lib/scout_apm/exceptions.rb
|
283
284
|
- lib/scout_apm/extensions/config.rb
|
284
285
|
- lib/scout_apm/extensions/transaction_callback_payload.rb
|
285
286
|
- lib/scout_apm/external_service_metric_set.rb
|
@@ -469,7 +470,7 @@ files:
|
|
469
470
|
- test/unit/utils/scm.rb
|
470
471
|
homepage: https://github.com/scoutapp/scout_apm_ruby
|
471
472
|
licenses:
|
472
|
-
-
|
473
|
+
- MIT
|
473
474
|
metadata: {}
|
474
475
|
post_install_message:
|
475
476
|
rdoc_options: []
|