scout_apm 2.6.10 → 3.0.0.pre0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -2
- data/.rubocop.yml +3 -11
- data/CHANGELOG.markdown +4 -362
- data/Gemfile +1 -14
- data/README.markdown +7 -52
- data/Rakefile +1 -0
- data/ext/allocations/allocations.c +1 -7
- data/ext/allocations/extconf.rb +0 -1
- data/ext/rusage/rusage.c +0 -26
- data/ext/stacks/extconf.rb +37 -0
- data/ext/stacks/scout_atomics.h +86 -0
- data/ext/stacks/stacks.c +811 -0
- data/lib/scout_apm/agent/logging.rb +69 -0
- data/lib/scout_apm/agent/reporting.rb +126 -0
- data/lib/scout_apm/agent.rb +259 -138
- data/lib/scout_apm/app_server_load.rb +15 -41
- data/lib/scout_apm/attribute_arranger.rb +3 -14
- data/lib/scout_apm/background_job_integrations/delayed_job.rb +1 -70
- data/lib/scout_apm/background_job_integrations/sidekiq.rb +24 -31
- data/lib/scout_apm/background_worker.rb +12 -23
- data/lib/scout_apm/capacity.rb +57 -0
- data/lib/scout_apm/config.rb +37 -206
- data/lib/scout_apm/context.rb +4 -20
- data/lib/scout_apm/deploy_integrations/capistrano_2.cap +12 -0
- data/lib/scout_apm/deploy_integrations/capistrano_2.rb +83 -0
- data/lib/scout_apm/deploy_integrations/capistrano_3.cap +12 -0
- data/lib/scout_apm/deploy_integrations/capistrano_3.rb +88 -0
- data/lib/scout_apm/environment.rb +28 -42
- data/lib/scout_apm/fake_store.rb +0 -12
- data/lib/scout_apm/framework_integrations/rails_2.rb +1 -2
- data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +6 -17
- data/lib/scout_apm/framework_integrations/sinatra.rb +1 -1
- data/lib/scout_apm/histogram.rb +3 -12
- data/lib/scout_apm/instant/assets/xmlhttp_instrumentation.html +2 -2
- data/lib/scout_apm/instant/middleware.rb +54 -202
- data/lib/scout_apm/instant_reporting.rb +7 -7
- data/lib/scout_apm/instruments/.DS_Store +0 -0
- data/lib/scout_apm/instruments/action_controller_rails_2.rb +9 -15
- data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +76 -124
- data/lib/scout_apm/instruments/active_record.rb +29 -324
- data/lib/scout_apm/instruments/delayed_job.rb +57 -0
- data/lib/scout_apm/instruments/elasticsearch.rb +6 -10
- data/lib/scout_apm/instruments/grape.rb +9 -12
- data/lib/scout_apm/instruments/http_client.rb +7 -14
- data/lib/scout_apm/instruments/influxdb.rb +6 -10
- data/lib/scout_apm/instruments/middleware_detailed.rb +11 -15
- data/lib/scout_apm/instruments/middleware_summary.rb +5 -11
- data/lib/scout_apm/instruments/mongoid.rb +8 -39
- data/lib/scout_apm/instruments/moped.rb +6 -11
- data/lib/scout_apm/instruments/net_http.rb +9 -27
- data/lib/scout_apm/instruments/percentile_sampler.rb +23 -42
- data/lib/scout_apm/instruments/process/process_cpu.rb +6 -11
- data/lib/scout_apm/instruments/process/process_memory.rb +12 -17
- data/lib/scout_apm/instruments/rails_router.rb +6 -12
- data/lib/scout_apm/instruments/redis.rb +6 -10
- data/lib/scout_apm/instruments/sinatra.rb +4 -5
- data/lib/scout_apm/job_record.rb +2 -4
- data/lib/scout_apm/layaway.rb +34 -88
- data/lib/scout_apm/layaway_file.rb +3 -13
- data/lib/scout_apm/layer.rb +60 -25
- data/lib/scout_apm/layer_converters/allocation_metric_converter.rb +6 -7
- data/lib/scout_apm/layer_converters/converter_base.rb +14 -203
- data/lib/scout_apm/layer_converters/depth_first_walker.rb +10 -22
- data/lib/scout_apm/layer_converters/error_converter.rb +8 -8
- data/lib/scout_apm/layer_converters/job_converter.rb +50 -37
- data/lib/scout_apm/layer_converters/metric_converter.rb +19 -18
- data/lib/scout_apm/layer_converters/request_queue_time_converter.rb +13 -13
- data/lib/scout_apm/layer_converters/slow_job_converter.rb +116 -52
- data/lib/scout_apm/layer_converters/slow_request_converter.rb +120 -51
- data/lib/scout_apm/metric_meta.rb +5 -0
- data/lib/scout_apm/metric_set.rb +1 -9
- data/lib/scout_apm/metric_stats.rb +8 -7
- data/lib/scout_apm/middleware.rb +9 -7
- data/lib/scout_apm/reporter.rb +24 -71
- data/lib/scout_apm/request_histograms.rb +0 -12
- data/lib/scout_apm/request_manager.rb +7 -5
- data/lib/scout_apm/scored_item_set.rb +0 -7
- data/lib/scout_apm/serializers/app_server_load_serializer.rb +0 -4
- data/lib/scout_apm/serializers/deploy_serializer.rb +16 -0
- data/lib/scout_apm/serializers/directive_serializer.rb +0 -4
- data/lib/scout_apm/serializers/payload_serializer.rb +4 -11
- data/lib/scout_apm/serializers/payload_serializer_to_json.rb +16 -35
- data/lib/scout_apm/serializers/slow_jobs_serializer_to_json.rb +1 -2
- data/lib/scout_apm/server_integrations/passenger.rb +1 -1
- data/lib/scout_apm/server_integrations/puma.rb +2 -5
- data/lib/scout_apm/slow_job_policy.rb +13 -25
- data/lib/scout_apm/slow_job_record.rb +4 -13
- data/lib/scout_apm/slow_request_policy.rb +13 -25
- data/lib/scout_apm/slow_transaction.rb +5 -25
- data/lib/scout_apm/store.rb +32 -99
- data/lib/scout_apm/trace_compactor.rb +312 -0
- data/lib/scout_apm/tracer.rb +31 -35
- data/lib/scout_apm/tracked_request.rb +95 -262
- data/lib/scout_apm/utils/active_record_metric_name.rb +13 -88
- data/lib/scout_apm/utils/backtrace_parser.rb +4 -7
- data/lib/scout_apm/utils/fake_stacks.rb +87 -0
- data/lib/scout_apm/utils/installed_gems.rb +3 -7
- data/lib/scout_apm/utils/klass_helper.rb +2 -8
- data/lib/scout_apm/utils/null_logger.rb +13 -0
- data/lib/scout_apm/utils/sql_sanitizer.rb +5 -16
- data/lib/scout_apm/utils/sql_sanitizer_regex.rb +0 -7
- data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +0 -6
- data/lib/scout_apm/utils/unique_id.rb +0 -27
- data/lib/scout_apm/version.rb +2 -1
- data/lib/scout_apm.rb +25 -84
- data/scout_apm.gemspec +3 -17
- data/test/test_helper.rb +3 -57
- data/test/unit/agent_test.rb +54 -1
- data/test/unit/background_job_integrations/sidekiq_test.rb +3 -0
- data/test/unit/config_test.rb +12 -25
- data/test/unit/context_test.rb +4 -4
- data/test/unit/histogram_test.rb +4 -25
- data/test/unit/ignored_uris_test.rb +1 -1
- data/test/unit/instruments/active_record_instruments_test.rb +5 -0
- data/test/unit/layaway_test.rb +2 -62
- data/test/unit/serializers/payload_serializer_test.rb +15 -43
- data/test/unit/slow_request_policy_test.rb +6 -15
- data/test/unit/sql_sanitizer_test.rb +6 -53
- data/test/unit/store_test.rb +4 -73
- data/test/unit/utils/active_record_metric_name_test.rb +5 -59
- data/test/unit/utils/backtrace_parser_test.rb +1 -6
- data/tester.rb +53 -0
- metadata +28 -229
- data/.travis.yml +0 -26
- data/Guardfile +0 -43
- data/gems/README.md +0 -28
- data/gems/octoshark.gemfile +0 -4
- data/gems/rails3.gemfile +0 -5
- data/gems/rails4.gemfile +0 -4
- data/gems/rails5.gemfile +0 -4
- data/gems/rails6.gemfile +0 -4
- data/lib/scout_apm/agent/exit_handler.rb +0 -65
- data/lib/scout_apm/agent/preconditions.rb +0 -81
- data/lib/scout_apm/agent_context.rb +0 -261
- data/lib/scout_apm/auto_instrument/instruction_sequence.rb +0 -31
- data/lib/scout_apm/auto_instrument/layer.rb +0 -23
- data/lib/scout_apm/auto_instrument/parser.rb +0 -27
- data/lib/scout_apm/auto_instrument/rails.rb +0 -175
- data/lib/scout_apm/auto_instrument.rb +0 -5
- data/lib/scout_apm/background_job_integrations/legacy_sneakers.rb +0 -55
- data/lib/scout_apm/background_job_integrations/que.rb +0 -134
- data/lib/scout_apm/background_job_integrations/resque.rb +0 -88
- data/lib/scout_apm/background_job_integrations/shoryuken.rb +0 -124
- data/lib/scout_apm/background_job_integrations/sneakers.rb +0 -87
- data/lib/scout_apm/background_recorder.rb +0 -48
- data/lib/scout_apm/db_query_metric_set.rb +0 -97
- data/lib/scout_apm/db_query_metric_stats.rb +0 -102
- data/lib/scout_apm/debug.rb +0 -37
- data/lib/scout_apm/detailed_trace.rb +0 -217
- data/lib/scout_apm/error.rb +0 -27
- data/lib/scout_apm/error_service/error_buffer.rb +0 -39
- data/lib/scout_apm/error_service/error_record.rb +0 -211
- data/lib/scout_apm/error_service/ignored_exceptions.rb +0 -66
- data/lib/scout_apm/error_service/middleware.rb +0 -32
- data/lib/scout_apm/error_service/notifier.rb +0 -33
- data/lib/scout_apm/error_service/payload.rb +0 -47
- data/lib/scout_apm/error_service/periodic_work.rb +0 -17
- data/lib/scout_apm/error_service/railtie.rb +0 -11
- data/lib/scout_apm/error_service/sidekiq.rb +0 -80
- data/lib/scout_apm/error_service.rb +0 -32
- data/lib/scout_apm/extensions/config.rb +0 -87
- data/lib/scout_apm/extensions/transaction_callback_payload.rb +0 -74
- data/lib/scout_apm/git_revision.rb +0 -59
- data/lib/scout_apm/instrument_manager.rb +0 -88
- data/lib/scout_apm/instruments/action_view.rb +0 -141
- data/lib/scout_apm/instruments/http.rb +0 -48
- data/lib/scout_apm/instruments/memcached.rb +0 -43
- data/lib/scout_apm/instruments/resque.rb +0 -39
- data/lib/scout_apm/instruments/samplers.rb +0 -11
- data/lib/scout_apm/layer_children_set.rb +0 -86
- data/lib/scout_apm/layer_converters/database_converter.rb +0 -70
- data/lib/scout_apm/layer_converters/find_layer_by_type.rb +0 -38
- data/lib/scout_apm/layer_converters/histograms.rb +0 -15
- data/lib/scout_apm/layer_converters/trace_converter.rb +0 -184
- data/lib/scout_apm/limited_layer.rb +0 -126
- data/lib/scout_apm/logger.rb +0 -158
- data/lib/scout_apm/periodic_work.rb +0 -47
- data/lib/scout_apm/rack.rb +0 -26
- data/lib/scout_apm/remote/message.rb +0 -27
- data/lib/scout_apm/remote/recorder.rb +0 -57
- data/lib/scout_apm/remote/router.rb +0 -49
- data/lib/scout_apm/remote/server.rb +0 -60
- data/lib/scout_apm/reporting.rb +0 -143
- data/lib/scout_apm/serializers/db_query_serializer_to_json.rb +0 -15
- data/lib/scout_apm/serializers/histograms_serializer_to_json.rb +0 -21
- data/lib/scout_apm/synchronous_recorder.rb +0 -30
- data/lib/scout_apm/tasks/doctor.rb +0 -75
- data/lib/scout_apm/tasks/support.rb +0 -22
- data/lib/scout_apm/transaction.rb +0 -13
- data/lib/scout_apm/transaction_time_consumed.rb +0 -51
- data/lib/scout_apm/utils/gzip_helper.rb +0 -24
- data/lib/scout_apm/utils/marshal_logging.rb +0 -90
- data/lib/scout_apm/utils/numbers.rb +0 -14
- data/lib/scout_apm/utils/scm.rb +0 -14
- data/lib/tasks/doctor.rake +0 -11
- data/test/tmp/README.md +0 -17
- data/test/unit/agent_context_test.rb +0 -15
- data/test/unit/auto_instrument/assignments-instrumented.rb +0 -31
- data/test/unit/auto_instrument/assignments.rb +0 -31
- data/test/unit/auto_instrument/controller-ast.txt +0 -57
- data/test/unit/auto_instrument/controller-instrumented.rb +0 -49
- data/test/unit/auto_instrument/controller.rb +0 -49
- data/test/unit/auto_instrument/rescue_from-instrumented.rb +0 -13
- data/test/unit/auto_instrument/rescue_from.rb +0 -13
- data/test/unit/auto_instrument_test.rb +0 -54
- data/test/unit/db_query_metric_set_test.rb +0 -67
- data/test/unit/db_query_metric_stats_test.rb +0 -113
- data/test/unit/error_service/error_buffer_test.rb +0 -25
- data/test/unit/error_service/ignored_exceptions_test.rb +0 -49
- data/test/unit/extensions/periodic_callbacks_test.rb +0 -58
- data/test/unit/extensions/transaction_callbacks_test.rb +0 -58
- data/test/unit/fake_store_test.rb +0 -10
- data/test/unit/git_revision_test.rb +0 -15
- data/test/unit/instruments/active_record_test.rb +0 -40
- data/test/unit/instruments/net_http_test.rb +0 -27
- data/test/unit/instruments/percentile_sampler_test.rb +0 -133
- data/test/unit/layer_children_set_test.rb +0 -97
- data/test/unit/layer_converters/depth_first_walker_test.rb +0 -70
- data/test/unit/layer_converters/metric_converter_test.rb +0 -22
- data/test/unit/layer_converters/stubs.rb +0 -33
- data/test/unit/limited_layer_test.rb +0 -53
- data/test/unit/logger_test.rb +0 -69
- data/test/unit/remote/test_message.rb +0 -13
- data/test/unit/remote/test_router.rb +0 -33
- data/test/unit/remote/test_server.rb +0 -15
- data/test/unit/request_histograms_test.rb +0 -17
- data/test/unit/tracer_test.rb +0 -76
- data/test/unit/tracked_request_test.rb +0 -71
- data/test/unit/transaction_test.rb +0 -14
- data/test/unit/transaction_time_consumed_test.rb +0 -46
- data/test/unit/utils/numbers_test.rb +0 -15
- data/test/unit/utils/scm.rb +0 -17
data/gems/README.md
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# Gems
|
2
|
-
|
3
|
-
These gemfiles list specific configurations of gems that we use in travis testing.
|
4
|
-
|
5
|
-
## Travis Matrix
|
6
|
-
|
7
|
-
```yaml
|
8
|
-
matrix:
|
9
|
-
include:
|
10
|
-
- rvm: "1.8.7"
|
11
|
-
gemfile: gems/rails3.gemfile
|
12
|
-
```
|
13
|
-
|
14
|
-
Using a gemfile controls the specific versions of the gems that are installed, and can be used to reproduce customer configurations for testing.
|
15
|
-
|
16
|
-
## Local Testing
|
17
|
-
|
18
|
-
To install the gems specified by a specific gemfile:
|
19
|
-
|
20
|
-
```
|
21
|
-
BUNDLE_GEMFILE=gems/rails5.gemfile bundle install
|
22
|
-
```
|
23
|
-
|
24
|
-
Then, to run tests using these gems:
|
25
|
-
|
26
|
-
```
|
27
|
-
BUNDLE_GEMFILE=gems/rails5.gemfile bundle exec rake
|
28
|
-
```
|
data/gems/octoshark.gemfile
DELETED
data/gems/rails3.gemfile
DELETED
data/gems/rails4.gemfile
DELETED
data/gems/rails5.gemfile
DELETED
data/gems/rails6.gemfile
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
module ScoutApm
|
2
|
-
class Agent
|
3
|
-
class ExitHandler
|
4
|
-
attr_reader :context
|
5
|
-
|
6
|
-
def initialize(context)
|
7
|
-
@context = context
|
8
|
-
end
|
9
|
-
|
10
|
-
def install
|
11
|
-
logger.debug "Shutdown handler not supported" and return unless exit_handler_supported?
|
12
|
-
logger.debug "Installing Shutdown Handler"
|
13
|
-
|
14
|
-
at_exit do
|
15
|
-
logger.info "Shutting down Scout Agent"
|
16
|
-
# MRI 1.9 bug drops exit codes.
|
17
|
-
# http://bugs.ruby-lang.org/issues/5218
|
18
|
-
if environment.ruby_19?
|
19
|
-
status = $!.status if $!.is_a?(SystemExit)
|
20
|
-
shutdown
|
21
|
-
exit status if status
|
22
|
-
else
|
23
|
-
shutdown
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# Called via the at_exit handler, it:
|
31
|
-
# (1) Stops the background worker
|
32
|
-
# (2) Stores metrics locally (forcing current-minute metrics to be written)
|
33
|
-
# It does not attempt to actually report metrics.
|
34
|
-
def shutdown
|
35
|
-
logger.info "Shutting down ScoutApm"
|
36
|
-
return if !context.started?
|
37
|
-
context.shutting_down!
|
38
|
-
::ScoutApm::Agent.instance.stop_background_worker
|
39
|
-
end
|
40
|
-
|
41
|
-
def exit_handler_supported?
|
42
|
-
if environment.sinatra?
|
43
|
-
logger.debug "Exit handler not supported for Sinatra"
|
44
|
-
false
|
45
|
-
elsif environment.jruby?
|
46
|
-
logger.debug "Exit handler not supported for JRuby"
|
47
|
-
false
|
48
|
-
elsif environment.rubinius?
|
49
|
-
logger.debug "Exit handler not supported for Rubinius"
|
50
|
-
false
|
51
|
-
else
|
52
|
-
true
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def logger
|
57
|
-
context.logger
|
58
|
-
end
|
59
|
-
|
60
|
-
def environment
|
61
|
-
context.environment
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
module ScoutApm
|
2
|
-
class Agent
|
3
|
-
class Preconditions
|
4
|
-
# The preconditions here must be a 2 element hash, with :message and :check.
|
5
|
-
# message: Proc that takes the environment, and returns a string
|
6
|
-
# check: Proc that takes an AgentContext and returns true if precondition was met, if false, we shouldn't start.
|
7
|
-
# severity: Severity of the log message (one of: :debug, :info, :warn, :error or :fatal)
|
8
|
-
PRECONDITIONS = [
|
9
|
-
PRECONDITION_ENABLED = {
|
10
|
-
:message => proc {|environ| "Monitoring isn't enabled for the [#{environ.env}] environment." },
|
11
|
-
:check => proc { |context| context.config.value('monitor') },
|
12
|
-
:severity => :info,
|
13
|
-
},
|
14
|
-
|
15
|
-
PRECONDITION_APP_NAME = {
|
16
|
-
:message => proc {|environ| "An application name could not be determined. Specify the :name value in scout_apm.yml." },
|
17
|
-
:check => proc { |context| context.environment.application_name },
|
18
|
-
:severity => :warn,
|
19
|
-
},
|
20
|
-
|
21
|
-
PRECONDITION_INTERACTIVE = {
|
22
|
-
:message => proc {|environ| "Agent attempting to load in interactive mode." },
|
23
|
-
:check => proc { |context| ! context.environment.interactive? },
|
24
|
-
:severity => :info,
|
25
|
-
},
|
26
|
-
|
27
|
-
PRECONDITION_DETECTED_SERVER = {
|
28
|
-
:message => proc {|environ| "Deferring agent start. Standing by for first request" },
|
29
|
-
:check => proc { |context|
|
30
|
-
app_server_missing = !context.environment.app_server_integration(true).found?
|
31
|
-
background_job_missing = context.environment.background_job_integrations.length == 0
|
32
|
-
|
33
|
-
!app_server_missing && !background_job_missing
|
34
|
-
},
|
35
|
-
:severity => :info,
|
36
|
-
},
|
37
|
-
|
38
|
-
PRECONDITION_ALREADY_STARTED = {
|
39
|
-
:message => proc {|environ| "Already started agent." },
|
40
|
-
:check => proc { |context| !context.started? },
|
41
|
-
:severity => :info,
|
42
|
-
},
|
43
|
-
|
44
|
-
PRECONDITION_OLD_SCOUT_RAILS = {
|
45
|
-
:message => proc {|environ| "ScoutAPM is incompatible with the old Scout Rails plugin. Please remove scout_rails from your Gemfile" },
|
46
|
-
:check => proc { !defined?(::ScoutRails) },
|
47
|
-
:severity => :warn,
|
48
|
-
},
|
49
|
-
]
|
50
|
-
|
51
|
-
def check?(context)
|
52
|
-
@check_result ||=
|
53
|
-
begin
|
54
|
-
failed_preconditions = PRECONDITIONS.inject(Array.new) { |errors, condition|
|
55
|
-
unless condition[:check].call(context)
|
56
|
-
errors << {
|
57
|
-
:severity => condition[:severity],
|
58
|
-
:message => condition[:message].call(context.environment),
|
59
|
-
}
|
60
|
-
end
|
61
|
-
|
62
|
-
errors
|
63
|
-
}
|
64
|
-
|
65
|
-
if failed_preconditions.any?
|
66
|
-
failed_preconditions.each {|error| context.logger.send(error[:severity], error[:message]) }
|
67
|
-
force? # if forced, return true anyway
|
68
|
-
else
|
69
|
-
# No errors, we met preconditions
|
70
|
-
true
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# XXX: Wire up options here and below in the appserver & bg server detections
|
76
|
-
def force?
|
77
|
-
false
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
@@ -1,261 +0,0 @@
|
|
1
|
-
module ScoutApm
|
2
|
-
class AgentContext
|
3
|
-
|
4
|
-
attr_accessor :extensions
|
5
|
-
|
6
|
-
# Initially start up without attempting to load a configuration file. We
|
7
|
-
# need to be able to lookup configuration options like "application_root"
|
8
|
-
# which would then in turn influence where the yaml configuration file is
|
9
|
-
# located
|
10
|
-
#
|
11
|
-
# Later in initialization, we set config= to include the file.
|
12
|
-
def initialize()
|
13
|
-
@logger = LoggerFactory.build_minimal_logger
|
14
|
-
@process_start_time = Time.now
|
15
|
-
@extensions = ScoutApm::Extensions::Config.new(self)
|
16
|
-
end
|
17
|
-
|
18
|
-
def marshal_dump
|
19
|
-
[]
|
20
|
-
end
|
21
|
-
|
22
|
-
def marshal_load(*args)
|
23
|
-
@logger = LoggerFactory.build_minimal_logger
|
24
|
-
@process_start_time = Time.now
|
25
|
-
end
|
26
|
-
|
27
|
-
#####################################
|
28
|
-
# Lifecycle: Remote Server/Client
|
29
|
-
#
|
30
|
-
# This allows short lived forked processes to communicate back to the parent process.
|
31
|
-
# Used in the Resque instrumentation
|
32
|
-
#
|
33
|
-
# Parent Pre-fork: start_remote_server! once
|
34
|
-
# Child Post-fork: become_remote_client! after each fork
|
35
|
-
#
|
36
|
-
# TODO: Figure out where to extract this to
|
37
|
-
#####################################
|
38
|
-
|
39
|
-
def start_remote_server!(bind, port)
|
40
|
-
return if @remote_server && @remote_server.running?
|
41
|
-
|
42
|
-
logger.info("Starting Remote Agent Server")
|
43
|
-
|
44
|
-
# Start the listening web server only in parent process.
|
45
|
-
@remote_server = ScoutApm::Remote::Server.new(
|
46
|
-
bind,
|
47
|
-
port,
|
48
|
-
ScoutApm::Remote::Router.new(ScoutApm::SynchronousRecorder.new(self), logger),
|
49
|
-
logger
|
50
|
-
)
|
51
|
-
|
52
|
-
@remote_server.start
|
53
|
-
end
|
54
|
-
|
55
|
-
# Execute this in the child process of a remote agent. The parent is
|
56
|
-
# expected to have its accepting webserver up and running
|
57
|
-
def become_remote_client!(host, port)
|
58
|
-
logger.debug("Becoming Remote Agent (reporting to: #{host}:#{port})")
|
59
|
-
@recorder = ScoutApm::Remote::Recorder.new(host, port, logger)
|
60
|
-
@store = ScoutApm::FakeStore.new
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
###############
|
65
|
-
# Accessors #
|
66
|
-
###############
|
67
|
-
|
68
|
-
attr_reader :process_start_time
|
69
|
-
|
70
|
-
def config
|
71
|
-
@config ||= ScoutApm::Config.without_file(self)
|
72
|
-
end
|
73
|
-
|
74
|
-
def environment
|
75
|
-
@environment ||= ScoutApm::Environment.instance
|
76
|
-
end
|
77
|
-
|
78
|
-
def started?
|
79
|
-
@started
|
80
|
-
end
|
81
|
-
|
82
|
-
def shutting_down?
|
83
|
-
@shutting_down
|
84
|
-
end
|
85
|
-
|
86
|
-
def installed?
|
87
|
-
@installed
|
88
|
-
end
|
89
|
-
|
90
|
-
def logger
|
91
|
-
@logger ||= LoggerFactory.build(config, environment)
|
92
|
-
end
|
93
|
-
|
94
|
-
def ignored_uris
|
95
|
-
@ignored_uris ||= ScoutApm::IgnoredUris.new(config.value('ignore'))
|
96
|
-
end
|
97
|
-
|
98
|
-
def slow_request_policy
|
99
|
-
@slow_request_policy ||= ScoutApm::SlowRequestPolicy.new(self)
|
100
|
-
end
|
101
|
-
|
102
|
-
def slow_job_policy
|
103
|
-
@slow_job_policy ||= ScoutApm::SlowJobPolicy.new(self)
|
104
|
-
end
|
105
|
-
|
106
|
-
# Maintains a Histogram of insignificant/significant autoinstrument layers.
|
107
|
-
# significant = 1
|
108
|
-
# insignificant = 0
|
109
|
-
def auto_instruments_layer_histograms
|
110
|
-
@auto_instruments_layer_histograms ||= ScoutApm::RequestHistograms.new
|
111
|
-
end
|
112
|
-
|
113
|
-
# Histogram of the cumulative requests since the start of the process
|
114
|
-
def request_histograms
|
115
|
-
@request_histograms ||= ScoutApm::RequestHistograms.new
|
116
|
-
end
|
117
|
-
|
118
|
-
# Histogram of the requests, distinct by reporting period (minute)
|
119
|
-
# { StoreReportingPeriodTimestamp => RequestHistograms }
|
120
|
-
def request_histograms_by_time
|
121
|
-
@request_histograms_by_time ||= Hash.new { |h, k| h[k] = ScoutApm::RequestHistograms.new }
|
122
|
-
end
|
123
|
-
|
124
|
-
def transaction_time_consumed
|
125
|
-
@transaction_time_consumed ||= ScoutApm::TransactionTimeConsumed.new
|
126
|
-
end
|
127
|
-
|
128
|
-
def store
|
129
|
-
return @store if @store
|
130
|
-
self.store = ScoutApm::Store.new(self)
|
131
|
-
end
|
132
|
-
|
133
|
-
def layaway
|
134
|
-
@layaway ||= ScoutApm::Layaway.new(self)
|
135
|
-
end
|
136
|
-
|
137
|
-
def recorder
|
138
|
-
@recorder ||= RecorderFactory.build(self)
|
139
|
-
end
|
140
|
-
|
141
|
-
def dev_trace_enabled?
|
142
|
-
config.value('dev_trace') && environment.env == "development"
|
143
|
-
end
|
144
|
-
|
145
|
-
###################
|
146
|
-
# Error Service #
|
147
|
-
###################
|
148
|
-
|
149
|
-
def error_buffer
|
150
|
-
@error_buffer ||= ScoutApm::ErrorService::ErrorBuffer.new(self)
|
151
|
-
end
|
152
|
-
|
153
|
-
def ignored_exceptions
|
154
|
-
@ignored_exceptions ||= ScoutApm::ErrorService::IgnoredExceptions.new(self, config.value('errors_ignored_exceptions'))
|
155
|
-
end
|
156
|
-
|
157
|
-
#############
|
158
|
-
# Setters #
|
159
|
-
#############
|
160
|
-
|
161
|
-
# When we set the config for any reason, there are some values we must
|
162
|
-
# reinitialize, since the config could have changed their settings, so nil
|
163
|
-
# them out here, then let them get lazily reset as needed
|
164
|
-
#
|
165
|
-
# Don't use this in initializer, since it'll attempt to log immediately
|
166
|
-
def config=(config)
|
167
|
-
@config = config
|
168
|
-
|
169
|
-
@logger = nil
|
170
|
-
|
171
|
-
log_configuration_settings
|
172
|
-
|
173
|
-
@ignored_uris = nil
|
174
|
-
@slow_request_policy = nil
|
175
|
-
@slow_job_policy = nil
|
176
|
-
@request_histograms = nil
|
177
|
-
@request_histograms_by_time = nil
|
178
|
-
@store = nil
|
179
|
-
@layaway = nil
|
180
|
-
@recorder = nil
|
181
|
-
end
|
182
|
-
|
183
|
-
def installed!
|
184
|
-
@installed = true
|
185
|
-
end
|
186
|
-
|
187
|
-
def started!
|
188
|
-
@started = true
|
189
|
-
end
|
190
|
-
|
191
|
-
def shutting_down!
|
192
|
-
@shutting_down = true
|
193
|
-
end
|
194
|
-
|
195
|
-
def store=(store)
|
196
|
-
@store = store
|
197
|
-
|
198
|
-
# Installs the default samplers
|
199
|
-
# Don't install samplers on nil stores
|
200
|
-
if store
|
201
|
-
ScoutApm::Instruments::Samplers::DEFAULT_SAMPLERS.each { |s| store.add_sampler(s) }
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
def recorder=(recorder)
|
206
|
-
@recorder = recorder
|
207
|
-
end
|
208
|
-
|
209
|
-
# I believe this is only useful for testing?
|
210
|
-
def environment=(env)
|
211
|
-
@environment = env
|
212
|
-
end
|
213
|
-
|
214
|
-
#########################
|
215
|
-
# Callbacks & helpers #
|
216
|
-
#
|
217
|
-
# Should find ways to remove these into external spots
|
218
|
-
#########################
|
219
|
-
|
220
|
-
# Called after config is reset and loaded from file
|
221
|
-
def log_configuration_settings
|
222
|
-
@config.log_settings(logger)
|
223
|
-
|
224
|
-
if !@config.any_keys_found?
|
225
|
-
logger.info("No configuration file loaded, and no configuration found in ENV. " +
|
226
|
-
"For assistance configuring Scout, visit " +
|
227
|
-
"https://docs.scoutapm.com/#ruby-configuration-options")
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
class RecorderFactory
|
233
|
-
def self.build(context)
|
234
|
-
if context.config.value("async_recording")
|
235
|
-
context.logger.debug("Using asynchronous recording")
|
236
|
-
ScoutApm::BackgroundRecorder.new(context).start
|
237
|
-
else
|
238
|
-
context.logger.debug("Using synchronous recording")
|
239
|
-
ScoutApm::SynchronousRecorder.new(context).start
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
class LoggerFactory
|
245
|
-
def self.build(config, environment)
|
246
|
-
ScoutApm::Logger.new(environment.root,
|
247
|
-
{
|
248
|
-
:log_level => config.value('log_level'),
|
249
|
-
:log_file_path => config.value('log_file_path'),
|
250
|
-
:stdout => config.value('log_stdout') || environment.platform_integration.log_to_stdout?,
|
251
|
-
:stderr => config.value('log_stderr'),
|
252
|
-
:logger_class => config.value('log_class'),
|
253
|
-
}
|
254
|
-
)
|
255
|
-
end
|
256
|
-
|
257
|
-
def self.build_minimal_logger
|
258
|
-
ScoutApm::Logger.new(nil, :stdout => true)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'scout_apm/auto_instrument/rails'
|
3
|
-
|
4
|
-
module ScoutApm
|
5
|
-
module AutoInstrument
|
6
|
-
module InstructionSequence
|
7
|
-
def load_iseq(path)
|
8
|
-
if Rails.controller_path?(path) & !Rails.ignore?(path)
|
9
|
-
begin
|
10
|
-
new_code = Rails.rewrite(path)
|
11
|
-
return self.compile(new_code, path, path)
|
12
|
-
rescue
|
13
|
-
warn "Failed to apply auto-instrumentation to #{path}: #{$!}"
|
14
|
-
end
|
15
|
-
elsif Rails.ignore?(path)
|
16
|
-
warn "AutoInstruments are ignored for path=#{path}."
|
17
|
-
end
|
18
|
-
|
19
|
-
return self.compile_file(path)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# This should work (https://bugs.ruby-lang.org/issues/15572), but it doesn't.
|
24
|
-
# RubyVM::InstructionSequence.extend(InstructionSequence)
|
25
|
-
|
26
|
-
# So we do this instead:
|
27
|
-
class << ::RubyVM::InstructionSequence
|
28
|
-
prepend InstructionSequence
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
|
2
|
-
module ScoutApm
|
3
|
-
def self.AutoInstrument(name, backtrace)
|
4
|
-
request = ScoutApm::RequestManager.lookup
|
5
|
-
|
6
|
-
file_name, _ = backtrace.first.split(":", 2)
|
7
|
-
|
8
|
-
begin
|
9
|
-
layer = ScoutApm::Layer.new('AutoInstrument', name)
|
10
|
-
layer.backtrace = backtrace
|
11
|
-
layer.file_name = file_name
|
12
|
-
|
13
|
-
request.start_layer(layer)
|
14
|
-
started_layer = true
|
15
|
-
|
16
|
-
result = yield
|
17
|
-
ensure
|
18
|
-
request.stop_layer if started_layer
|
19
|
-
end
|
20
|
-
|
21
|
-
return result
|
22
|
-
end
|
23
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'parser/current'
|
3
|
-
raise LoadError, "Parser::TreeRewriter was not defined" unless defined?(Parser::TreeRewriter)
|
4
|
-
|
5
|
-
module ScoutApm
|
6
|
-
module AutoInstrument
|
7
|
-
class Cache
|
8
|
-
def initialize
|
9
|
-
@local_assignments = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def local_assignments?(node)
|
13
|
-
unless @local_assignments.key?(node)
|
14
|
-
if node.type == :lvasgn
|
15
|
-
@local_assignments[node] = true
|
16
|
-
elsif node.children.find{|child| child.is_a?(Parser::AST::Node) && self.local_assignments?(child)}
|
17
|
-
@local_assignments[node] = true
|
18
|
-
else
|
19
|
-
@local_assignments[node] = false
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
return @local_assignments[node]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|