scout_apm 2.3.5 → 2.4.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +0 -23
- data/lib/scout_apm.rb +21 -10
- data/lib/scout_apm/agent.rb +98 -336
- data/lib/scout_apm/agent/exit_handler.rb +64 -0
- data/lib/scout_apm/agent/preconditions.rb +69 -0
- data/lib/scout_apm/agent_context.rb +226 -0
- data/lib/scout_apm/app_server_load.rb +20 -18
- data/lib/scout_apm/background_job_integrations/resque.rb +7 -8
- data/lib/scout_apm/background_job_integrations/sidekiq.rb +2 -8
- data/lib/scout_apm/background_recorder.rb +8 -3
- data/lib/scout_apm/background_worker.rb +14 -7
- data/lib/scout_apm/config.rb +35 -29
- data/lib/scout_apm/context.rb +11 -4
- data/lib/scout_apm/db_query_metric_set.rb +17 -5
- data/lib/scout_apm/debug.rb +1 -1
- data/lib/scout_apm/environment.rb +10 -14
- data/lib/scout_apm/framework_integrations/sinatra.rb +1 -1
- data/lib/scout_apm/git_revision.rb +13 -8
- data/lib/scout_apm/histogram.rb +1 -1
- data/lib/scout_apm/instant/middleware.rb +7 -7
- data/lib/scout_apm/instant_reporting.rb +7 -7
- data/lib/scout_apm/instrument_manager.rb +87 -0
- data/lib/scout_apm/instruments/action_controller_rails_2.rb +12 -7
- data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +16 -11
- data/lib/scout_apm/instruments/action_view.rb +11 -7
- data/lib/scout_apm/instruments/active_record.rb +28 -51
- data/lib/scout_apm/instruments/elasticsearch.rb +10 -6
- data/lib/scout_apm/instruments/grape.rb +12 -8
- data/lib/scout_apm/instruments/http_client.rb +11 -10
- data/lib/scout_apm/instruments/influxdb.rb +10 -6
- data/lib/scout_apm/instruments/middleware_detailed.rb +11 -5
- data/lib/scout_apm/instruments/middleware_summary.rb +11 -5
- data/lib/scout_apm/instruments/mongoid.rb +10 -5
- data/lib/scout_apm/instruments/moped.rb +11 -6
- data/lib/scout_apm/instruments/net_http.rb +11 -9
- data/lib/scout_apm/instruments/percentile_sampler.rb +8 -6
- data/lib/scout_apm/instruments/process/process_cpu.rb +8 -4
- data/lib/scout_apm/instruments/process/process_memory.rb +15 -10
- data/lib/scout_apm/instruments/rails_router.rb +12 -6
- data/lib/scout_apm/instruments/redis.rb +10 -6
- data/lib/scout_apm/instruments/samplers.rb +11 -0
- data/lib/scout_apm/instruments/sinatra.rb +5 -4
- data/lib/scout_apm/layaway.rb +26 -39
- data/lib/scout_apm/layaway_file.rb +8 -3
- data/lib/scout_apm/layer.rb +1 -1
- data/lib/scout_apm/layer_converters/converter_base.rb +4 -2
- data/lib/scout_apm/layer_converters/database_converter.rb +1 -1
- data/lib/scout_apm/layer_converters/histograms.rb +2 -2
- data/lib/scout_apm/layer_converters/slow_job_converter.rb +4 -3
- data/lib/scout_apm/layer_converters/slow_request_converter.rb +5 -4
- data/lib/scout_apm/logger.rb +143 -0
- data/lib/scout_apm/middleware.rb +7 -9
- data/lib/scout_apm/periodic_work.rb +28 -0
- data/lib/scout_apm/remote/server.rb +0 -2
- data/lib/scout_apm/reporter.rb +14 -8
- data/lib/scout_apm/reporting.rb +135 -0
- data/lib/scout_apm/request_manager.rb +4 -7
- data/lib/scout_apm/serializers/payload_serializer.rb +1 -1
- data/lib/scout_apm/slow_job_policy.rb +6 -2
- data/lib/scout_apm/slow_job_record.rb +5 -5
- data/lib/scout_apm/slow_request_policy.rb +6 -2
- data/lib/scout_apm/slow_transaction.rb +5 -5
- data/lib/scout_apm/store.rb +22 -16
- data/lib/scout_apm/synchronous_recorder.rb +7 -3
- data/lib/scout_apm/tasks/doctor.rb +75 -0
- data/lib/scout_apm/tasks/support.rb +22 -0
- data/lib/scout_apm/tracer.rb +5 -5
- data/lib/scout_apm/tracked_request.rb +23 -35
- data/lib/scout_apm/utils/backtrace_parser.rb +1 -1
- data/lib/scout_apm/utils/installed_gems.rb +7 -3
- data/lib/scout_apm/utils/klass_helper.rb +8 -2
- data/lib/scout_apm/utils/scm.rb +1 -1
- data/lib/scout_apm/utils/sql_sanitizer.rb +4 -6
- data/lib/scout_apm/version.rb +1 -1
- data/lib/tasks/doctor.rake +11 -0
- data/test/test_helper.rb +15 -2
- data/test/unit/agent_test.rb +1 -54
- data/test/unit/config_test.rb +9 -5
- data/test/unit/context_test.rb +4 -4
- data/test/unit/db_query_metric_set_test.rb +11 -4
- data/test/unit/fake_store_test.rb +1 -1
- data/test/unit/git_revision_test.rb +3 -3
- data/test/unit/instruments/net_http_test.rb +2 -1
- data/test/unit/instruments/percentile_sampler_test.rb +5 -9
- data/test/unit/layaway_test.rb +10 -5
- data/test/unit/layer_converters/metric_converter_test.rb +2 -2
- data/test/unit/slow_request_policy_test.rb +7 -3
- data/test/unit/sql_sanitizer_test.rb +0 -6
- data/test/unit/store_test.rb +11 -8
- metadata +15 -7
- data/lib/scout_apm/agent/logging.rb +0 -74
- data/lib/scout_apm/agent/reporting.rb +0 -129
- data/lib/scout_apm/utils/null_logger.rb +0 -13
@@ -1,25 +1,29 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Instruments
|
3
3
|
class Elasticsearch
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
8
|
@installed = false
|
9
9
|
end
|
10
10
|
|
11
|
+
def logger
|
12
|
+
context.logger
|
13
|
+
end
|
14
|
+
|
11
15
|
def installed?
|
12
16
|
@installed
|
13
17
|
end
|
14
18
|
|
15
19
|
def install
|
16
|
-
@installed = true
|
17
|
-
|
18
20
|
if defined?(::Elasticsearch) &&
|
19
21
|
defined?(::Elasticsearch::Transport) &&
|
20
22
|
defined?(::Elasticsearch::Transport::Client)
|
21
23
|
|
22
|
-
|
24
|
+
@installed = true
|
25
|
+
|
26
|
+
logger.info "Instrumenting Elasticsearch"
|
23
27
|
|
24
28
|
::Elasticsearch::Transport::Client.class_eval do
|
25
29
|
include ScoutApm::Tracer
|
@@ -1,22 +1,26 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Instruments
|
3
3
|
class Grape
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
8
|
@installed = false
|
9
9
|
end
|
10
10
|
|
11
|
+
def logger
|
12
|
+
context.logger
|
13
|
+
end
|
14
|
+
|
11
15
|
def installed?
|
12
16
|
@installed
|
13
17
|
end
|
14
18
|
|
15
19
|
def install
|
16
|
-
@installed = true
|
17
|
-
|
18
20
|
if defined?(::Grape) && defined?(::Grape::Endpoint)
|
19
|
-
|
21
|
+
@installed = true
|
22
|
+
|
23
|
+
logger.info "Instrumenting Grape::Endpoint"
|
20
24
|
|
21
25
|
::Grape::Endpoint.class_eval do
|
22
26
|
include ScoutApm::Instruments::GrapeEndpointInstruments
|
@@ -33,7 +37,7 @@ module ScoutApm
|
|
33
37
|
request = ::Grape::Request.new(env || args.first)
|
34
38
|
req = ScoutApm::RequestManager.lookup
|
35
39
|
|
36
|
-
path = ScoutApm::Agent.instance.config.value("uri_reporting") == 'path' ? request.path : request.fullpath
|
40
|
+
path = ScoutApm::Agent.instance.context.config.value("uri_reporting") == 'path' ? request.path : request.fullpath
|
37
41
|
req.annotate_request(:uri => path)
|
38
42
|
|
39
43
|
# IP Spoofing Protection can throw an exception, just move on w/o remote ip
|
@@ -50,7 +54,7 @@ module ScoutApm
|
|
50
54
|
self.options[:path].first,
|
51
55
|
].compact.map{ |n| n.to_s }.join("/")
|
52
56
|
rescue => e
|
53
|
-
|
57
|
+
logger.info("Error getting Grape Endpoint Name. Error: #{e.message}. Options: #{self.options.inspect}")
|
54
58
|
name = "Grape/Unknown"
|
55
59
|
end
|
56
60
|
|
@@ -1,33 +1,34 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Instruments
|
3
3
|
class HttpClient
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
8
|
@installed = false
|
9
9
|
end
|
10
10
|
|
11
|
+
def logger
|
12
|
+
context.logger
|
13
|
+
end
|
14
|
+
|
11
15
|
def installed?
|
12
16
|
@installed
|
13
17
|
end
|
14
18
|
|
15
19
|
def install
|
16
|
-
@installed = true
|
17
|
-
|
18
20
|
if defined?(::HTTPClient)
|
19
|
-
|
21
|
+
@installed = true
|
22
|
+
|
23
|
+
logger.info "Instrumenting HTTPClient"
|
20
24
|
|
21
25
|
::HTTPClient.class_eval do
|
22
26
|
include ScoutApm::Tracer
|
23
27
|
|
24
28
|
def request_with_scout_instruments(*args, &block)
|
25
|
-
|
26
29
|
method = args[0].to_s
|
27
30
|
url = args[1]
|
28
|
-
|
29
|
-
max_length = ScoutApm::Agent.instance.config.value('instrument_http_url_length')
|
30
|
-
url = url && url.to_s[0..(max_length - 1)]
|
31
|
+
url = url && url.to_s[0..99]
|
31
32
|
|
32
33
|
self.class.instrument("HTTP", method, :desc => url) do
|
33
34
|
request_without_scout_instruments(*args, &block)
|
@@ -1,22 +1,26 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Instruments
|
3
3
|
class InfluxDB
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
8
|
@installed = false
|
9
9
|
end
|
10
10
|
|
11
|
+
def logger
|
12
|
+
context.logger
|
13
|
+
end
|
14
|
+
|
11
15
|
def installed?
|
12
16
|
@installed
|
13
17
|
end
|
14
18
|
|
15
19
|
def install
|
16
|
-
@installed = true
|
17
|
-
|
18
20
|
if defined?(::InfluxDB)
|
19
|
-
|
21
|
+
@installed = true
|
22
|
+
|
23
|
+
logger.debug "Instrumenting InfluxDB"
|
20
24
|
|
21
25
|
::InfluxDB::Client.class_eval do
|
22
26
|
include ScoutApm::Tracer
|
@@ -9,22 +9,28 @@
|
|
9
9
|
module ScoutApm
|
10
10
|
module Instruments
|
11
11
|
class MiddlewareDetailed
|
12
|
-
|
13
|
-
|
12
|
+
attr_reader :context
|
13
|
+
|
14
|
+
def initialize(context)
|
15
|
+
@context = context
|
14
16
|
@installed = false
|
15
17
|
end
|
16
18
|
|
19
|
+
def logger
|
20
|
+
context.logger
|
21
|
+
end
|
22
|
+
|
17
23
|
def installed?
|
18
24
|
@installed
|
19
25
|
end
|
20
26
|
|
21
27
|
def install
|
22
|
-
@installed = true
|
23
|
-
|
24
28
|
if defined?(ActionDispatch) && defined?(ActionDispatch::MiddlewareStack) && defined?(ActionDispatch::MiddlewareStack::Middleware)
|
29
|
+
@installed = true
|
30
|
+
|
25
31
|
ActionDispatch::MiddlewareStack::Middleware.class_eval do
|
26
32
|
def build(app)
|
27
|
-
|
33
|
+
logger.info("Building Middleware #{klass.name}")
|
28
34
|
new_mw = klass.new(app, *args, &block)
|
29
35
|
MiddlewareWrapper.new(new_mw, klass.name)
|
30
36
|
end
|
@@ -6,20 +6,26 @@
|
|
6
6
|
module ScoutApm
|
7
7
|
module Instruments
|
8
8
|
class MiddlewareSummary
|
9
|
-
|
10
|
-
|
9
|
+
attr_reader :context
|
10
|
+
|
11
|
+
def initialize(context)
|
12
|
+
@context = context
|
11
13
|
@installed = false
|
12
14
|
end
|
13
15
|
|
16
|
+
def logger
|
17
|
+
context.logger
|
18
|
+
end
|
19
|
+
|
14
20
|
def installed?
|
15
21
|
@installed
|
16
22
|
end
|
17
23
|
|
18
24
|
def install
|
19
|
-
@installed = true
|
20
|
-
|
21
25
|
if defined?(ActionDispatch) && defined?(ActionDispatch::MiddlewareStack)
|
22
|
-
|
26
|
+
@installed = true
|
27
|
+
|
28
|
+
logger.info("Instrumenting Middleware")
|
23
29
|
ActionDispatch::MiddlewareStack.class_eval do
|
24
30
|
def build_with_scout_instruments(app = nil, &block)
|
25
31
|
mw_stack = build_without_scout_instruments(app) { block.call if block }
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Instruments
|
3
3
|
class Mongoid
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
8
|
@installed = false
|
9
9
|
end
|
10
10
|
|
11
|
+
def logger
|
12
|
+
context.logger
|
13
|
+
end
|
14
|
+
|
11
15
|
def installed?
|
12
16
|
@installed
|
13
17
|
end
|
@@ -17,7 +21,8 @@ module ScoutApm
|
|
17
21
|
|
18
22
|
# Mongoid versions that use Moped should instrument Moped.
|
19
23
|
if defined?(::Mongoid) and !defined?(::Moped)
|
20
|
-
|
24
|
+
logger.info "Instrumenting Mongoid 2.x"
|
25
|
+
@installed = true
|
21
26
|
|
22
27
|
### OLD (2.x) mongoids
|
23
28
|
if defined?(::Mongoid::Collection)
|
@@ -33,7 +38,7 @@ module ScoutApm
|
|
33
38
|
|
34
39
|
### 5.x Mongoid
|
35
40
|
if (mongoid_v5? || mongoid_v6?) && defined?(::Mongoid::Contextual::Mongo)
|
36
|
-
|
41
|
+
logger.info "Instrumenting Mongoid 5.x/6.x"
|
37
42
|
# All the public methods from Mongoid::Contextual::Mongo.
|
38
43
|
# TODO: Geo and MapReduce support (?). They are in other Contextual::* classes
|
39
44
|
methods = [
|
@@ -1,22 +1,27 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Instruments
|
3
3
|
class Moped
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
8
|
@installed = false
|
9
9
|
end
|
10
10
|
|
11
|
+
def logger
|
12
|
+
context.logger
|
13
|
+
end
|
14
|
+
|
11
15
|
def installed?
|
12
16
|
@installed
|
13
17
|
end
|
14
18
|
|
15
19
|
def install
|
16
|
-
@installed = true
|
17
|
-
|
18
20
|
if defined?(::Moped)
|
19
|
-
|
21
|
+
@installed = true
|
22
|
+
|
23
|
+
logger.info "Instrumenting Moped"
|
24
|
+
|
20
25
|
::Moped::Node.class_eval do
|
21
26
|
include ScoutApm::Tracer
|
22
27
|
|
@@ -1,22 +1,26 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
module Instruments
|
3
3
|
class NetHttp
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :context
|
5
5
|
|
6
|
-
def
|
7
|
-
@
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
8
|
@installed = false
|
9
9
|
end
|
10
10
|
|
11
|
+
def logger
|
12
|
+
context.logger
|
13
|
+
end
|
14
|
+
|
11
15
|
def installed?
|
12
16
|
@installed
|
13
17
|
end
|
14
18
|
|
15
19
|
def install
|
16
|
-
@installed = true
|
17
|
-
|
18
20
|
if defined?(::Net) && defined?(::Net::HTTP)
|
19
|
-
|
21
|
+
@installed = true
|
22
|
+
|
23
|
+
logger.info "Instrumenting Net::HTTP"
|
20
24
|
|
21
25
|
::Net::HTTP.class_eval do
|
22
26
|
include ScoutApm::Tracer
|
@@ -30,9 +34,7 @@ module ScoutApm
|
|
30
34
|
def request_scout_description(req)
|
31
35
|
path = req.path
|
32
36
|
path = path.path if path.respond_to?(:path)
|
33
|
-
|
34
|
-
max_length = ScoutApm::Agent.instance.config.value('instrument_http_url_length')
|
35
|
-
(@address + path.split('?').first)[0..(max_length - 1)]
|
37
|
+
(@address + path.split('?').first)[0..99]
|
36
38
|
end
|
37
39
|
|
38
40
|
alias request_without_scout_instruments request
|
@@ -18,14 +18,16 @@ module ScoutApm
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class PercentileSampler
|
21
|
-
|
21
|
+
def initialize(context)
|
22
|
+
@context = context
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
+
def histograms
|
26
|
+
@context.request_histograms_by_time
|
27
|
+
end
|
25
28
|
|
26
|
-
def
|
27
|
-
@logger
|
28
|
-
@histograms = histograms
|
29
|
+
def logger
|
30
|
+
@context.logger
|
29
31
|
end
|
30
32
|
|
31
33
|
def human_name
|
@@ -2,14 +2,14 @@ module ScoutApm
|
|
2
2
|
module Instruments
|
3
3
|
module Process
|
4
4
|
class ProcessCpu
|
5
|
-
attr_reader :logger
|
6
5
|
attr_reader :num_processors
|
7
6
|
attr_accessor :last_run, :last_utime, :last_stime
|
7
|
+
attr_reader :context
|
8
8
|
|
9
|
+
def initialize(context)
|
10
|
+
@context = context
|
9
11
|
|
10
|
-
|
11
|
-
@num_processors = [num_processors, 1].compact.max
|
12
|
-
@logger = logger
|
12
|
+
@num_processors = [context.environment.processors, 1].compact.max
|
13
13
|
|
14
14
|
t = ::Process.times
|
15
15
|
@last_run = Time.now
|
@@ -98,6 +98,10 @@ module ScoutApm
|
|
98
98
|
self.last_utime = utime
|
99
99
|
self.last_stime = stime
|
100
100
|
end
|
101
|
+
|
102
|
+
def logger
|
103
|
+
context.logger
|
104
|
+
end
|
101
105
|
end
|
102
106
|
end
|
103
107
|
end
|
@@ -2,23 +2,24 @@ module ScoutApm
|
|
2
2
|
module Instruments
|
3
3
|
module Process
|
4
4
|
class ProcessMemory
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
def
|
9
|
-
|
5
|
+
# Account for Darwin returning maxrss in bytes and Linux in KB. Used by
|
6
|
+
# the slow converters. Doesn't feel like this should go here
|
7
|
+
# though...more of a utility.
|
8
|
+
def rss_to_mb(rss)
|
9
|
+
kilobyte_adjust = @context.environment.os == 'darwin' ? 1024 : 1
|
10
|
+
rss.to_f / 1024 / kilobyte_adjust
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
+
def rss
|
13
14
|
::Process.rusage.maxrss
|
14
15
|
end
|
15
16
|
|
16
|
-
def
|
17
|
+
def rss_in_mb
|
17
18
|
rss_to_mb(rss)
|
18
19
|
end
|
19
20
|
|
20
|
-
def initialize(
|
21
|
-
@
|
21
|
+
def initialize(context)
|
22
|
+
@context = context
|
22
23
|
end
|
23
24
|
|
24
25
|
def metric_type
|
@@ -46,7 +47,11 @@ module ScoutApm
|
|
46
47
|
end
|
47
48
|
|
48
49
|
def run
|
49
|
-
|
50
|
+
rss_in_mb.tap { |res| logger.debug "#{human_name}: #{res.inspect}" }
|
51
|
+
end
|
52
|
+
|
53
|
+
def logger
|
54
|
+
@context.logger
|
50
55
|
end
|
51
56
|
end
|
52
57
|
end
|