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,74 +0,0 @@
|
|
1
|
-
# Contains methods specific to logging (initializing the log file, applying the log level, applying the log format, etc.)
|
2
|
-
module ScoutApm
|
3
|
-
class Agent
|
4
|
-
module Logging
|
5
|
-
def default_log_path
|
6
|
-
"#{environment.root}/log"
|
7
|
-
end
|
8
|
-
|
9
|
-
def init_logger(opts={})
|
10
|
-
if opts[:force]
|
11
|
-
@log_file = nil
|
12
|
-
@logger = nil
|
13
|
-
end
|
14
|
-
|
15
|
-
begin
|
16
|
-
@log_file ||= determine_log_destination
|
17
|
-
rescue => e
|
18
|
-
end
|
19
|
-
|
20
|
-
begin
|
21
|
-
@logger ||= Logger.new(@log_file)
|
22
|
-
@logger.level = log_level
|
23
|
-
apply_log_format
|
24
|
-
rescue Exception => e
|
25
|
-
@logger = Logger.new(STDOUT)
|
26
|
-
apply_log_format
|
27
|
-
@logger.error "Unable to open log file for writing: #{e.message}. Falling back to STDOUT"
|
28
|
-
end
|
29
|
-
@logger
|
30
|
-
end
|
31
|
-
|
32
|
-
def apply_log_format
|
33
|
-
def logger.format_message(severity, timestamp, progname, msg)
|
34
|
-
# since STDOUT isn't exclusive like the scout_apm.log file, apply a prefix.
|
35
|
-
prefix = @logdev.dev == STDOUT ? "[Scout] " : ''
|
36
|
-
prefix + "[#{Utils::Time.to_s(timestamp)} #{ScoutApm::Agent.instance.environment.hostname} (#{$$})] #{severity} : #{msg}\n"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def log_level
|
41
|
-
case config.value('log_level').downcase
|
42
|
-
when "debug" then Logger::DEBUG
|
43
|
-
when "info" then Logger::INFO
|
44
|
-
when "warn" then Logger::WARN
|
45
|
-
when "error" then Logger::ERROR
|
46
|
-
when "fatal" then Logger::FATAL
|
47
|
-
else Logger::INFO
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def determine_log_destination
|
52
|
-
case true
|
53
|
-
when wants_stdout? then STDOUT
|
54
|
-
when wants_stderr? then STDERR
|
55
|
-
else "#{log_file_path}/scout_apm.log"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def wants_stdout?
|
60
|
-
config.value('log_file_path').to_s.upcase == 'STDOUT' || environment.platform_integration.log_to_stdout?
|
61
|
-
end
|
62
|
-
|
63
|
-
def wants_stderr?
|
64
|
-
config.value('log_file_path').to_s.upcase == 'STDERR'
|
65
|
-
end
|
66
|
-
|
67
|
-
def log_file_path
|
68
|
-
config.value('log_file_path') || default_log_path
|
69
|
-
end
|
70
|
-
end
|
71
|
-
include Logging
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
@@ -1,129 +0,0 @@
|
|
1
|
-
# Methods related to sending metrics to scoutapp.com.
|
2
|
-
module ScoutApm
|
3
|
-
class Agent
|
4
|
-
module Reporting
|
5
|
-
def reporter
|
6
|
-
@reporter ||= ScoutApm::Reporter.new(:checkin, config, logger)
|
7
|
-
end
|
8
|
-
|
9
|
-
# The data moves through a treadmill of reporting, coordinating several Rails processes by using an external file.
|
10
|
-
# * During the minute it is being recorded by the instruments, it gets
|
11
|
-
# recorded into the ram of each process (in the Store class).
|
12
|
-
# * The minute after, each process writes its own metrics to a shared LayawayFile
|
13
|
-
# * The minute after that, the first process to wake up pushes the combined
|
14
|
-
# data to the server, and wipes it. Next processes don't have anything to do.
|
15
|
-
#
|
16
|
-
# At any given point, there is data in each of those steps, moving its way through the process
|
17
|
-
def process_metrics
|
18
|
-
# Write the previous minute's data to the shared-across-process layaway file.
|
19
|
-
store.write_to_layaway(layaway)
|
20
|
-
|
21
|
-
# Attempt to send 2 minutes ago's data up to the server. This
|
22
|
-
# only acctually occurs if this process is the first to wake up this
|
23
|
-
# minute.
|
24
|
-
report_to_server
|
25
|
-
end
|
26
|
-
|
27
|
-
# In a running app, one process will get the period ready for delivery, the others will see 0.
|
28
|
-
def report_to_server
|
29
|
-
period_to_report = ScoutApm::StoreReportingPeriodTimestamp.minutes_ago(2)
|
30
|
-
|
31
|
-
logger.debug("Attempting to claim #{period_to_report.to_s}")
|
32
|
-
|
33
|
-
did_write = layaway.with_claim(period_to_report) do |rps|
|
34
|
-
logger.debug("Succeeded claiming #{period_to_report.to_s}")
|
35
|
-
|
36
|
-
begin
|
37
|
-
merged = rps.inject { |memo, rp| memo.merge(rp) }
|
38
|
-
logger.debug("Merged #{rps.length} reporting periods, delivering")
|
39
|
-
deliver_period(merged)
|
40
|
-
true
|
41
|
-
rescue => e
|
42
|
-
logger.debug("Error merging reporting periods #{e.message}")
|
43
|
-
logger.debug("Error merging reporting periods #{e.backtrace}")
|
44
|
-
false
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
if !did_write
|
50
|
-
logger.debug("Failed to obtain claim for #{period_to_report.to_s}")
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
def deliver_period(reporting_period)
|
57
|
-
metrics = reporting_period.metrics_payload
|
58
|
-
slow_transactions = reporting_period.slow_transactions_payload
|
59
|
-
jobs = reporting_period.jobs
|
60
|
-
slow_jobs = reporting_period.slow_jobs_payload
|
61
|
-
histograms = reporting_period.histograms
|
62
|
-
db_query_metrics = reporting_period.db_query_metrics_payload
|
63
|
-
|
64
|
-
metadata = {
|
65
|
-
:app_root => ScoutApm::Environment.instance.root.to_s,
|
66
|
-
:unique_id => ScoutApm::Utils::UniqueId.simple,
|
67
|
-
:agent_version => ScoutApm::VERSION,
|
68
|
-
:agent_time => reporting_period.timestamp.to_s,
|
69
|
-
:agent_pid => Process.pid,
|
70
|
-
:platform => "ruby",
|
71
|
-
}
|
72
|
-
|
73
|
-
log_deliver(metrics, slow_transactions, metadata, slow_jobs, histograms)
|
74
|
-
|
75
|
-
payload = ScoutApm::Serializers::PayloadSerializer.serialize(metadata, metrics, slow_transactions, jobs, slow_jobs, histograms, db_query_metrics)
|
76
|
-
logger.debug("Sending payload w/ Headers: #{headers.inspect}")
|
77
|
-
|
78
|
-
reporter.report(payload, headers)
|
79
|
-
rescue => e
|
80
|
-
logger.warn "Error on checkin"
|
81
|
-
logger.info e.message
|
82
|
-
logger.debug e.backtrace
|
83
|
-
end
|
84
|
-
|
85
|
-
def log_deliver(metrics, slow_transactions, metadata, jobs_traces, histograms)
|
86
|
-
total_request_count = metrics.
|
87
|
-
select { |meta,stats| meta.metric_name =~ /\AController/ }.
|
88
|
-
inject(0) {|sum, (_, stat)| sum + stat.call_count }
|
89
|
-
|
90
|
-
memory = metrics.
|
91
|
-
find {|meta,stats| meta.metric_name =~ /\AMemory/ }
|
92
|
-
process_log_str = if memory
|
93
|
-
"Recorded from #{memory.last.call_count} processes"
|
94
|
-
else
|
95
|
-
"Recorded across (unknown) processes"
|
96
|
-
end
|
97
|
-
|
98
|
-
time_clause = "[#{Time.parse(metadata[:agent_time]).strftime("%H:%M")}]"
|
99
|
-
metrics_clause = "#{metrics.length} Metrics for #{total_request_count} requests"
|
100
|
-
slow_trans_clause = "#{slow_transactions.length} Slow Transaction Traces"
|
101
|
-
job_clause = "#{jobs_traces.length} Job Traces"
|
102
|
-
histogram_clause = "#{histograms.length} Histograms"
|
103
|
-
|
104
|
-
logger.info "#{time_clause} Delivering #{metrics_clause} and #{slow_trans_clause} and #{job_clause}, #{process_log_str}."
|
105
|
-
logger.debug("\n\nMetrics: #{metrics.pretty_inspect}\nSlowTrans: #{slow_transactions.pretty_inspect}\nMetadata: #{metadata.inspect.pretty_inspect}\n\n")
|
106
|
-
end
|
107
|
-
|
108
|
-
# TODO: Move this into PayloadSerializer?
|
109
|
-
def headers
|
110
|
-
if ScoutApm::Agent.instance.config.value("report_format") == 'json'
|
111
|
-
headers = {'Content-Type' => 'application/json'}
|
112
|
-
else
|
113
|
-
headers = {}
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
# Before reporting, lookup metric_id for each MetricMeta. This speeds up
|
118
|
-
# reporting on the server-side.
|
119
|
-
def add_metric_ids(metrics)
|
120
|
-
metrics.each do |meta,stats|
|
121
|
-
if metric_id = metric_lookup[meta]
|
122
|
-
meta.metric_id = metric_id
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
include Reporting
|
128
|
-
end
|
129
|
-
end
|