scout_apm 3.0.0.pre5 → 3.0.0.pre6
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 +4 -0
- data/lib/scout_apm/agent/reporting.rb +2 -2
- data/lib/scout_apm/agent.rb +7 -0
- data/lib/scout_apm/config.rb +71 -11
- data/lib/scout_apm/layaway.rb +48 -23
- data/lib/scout_apm/layer_converters/converter_base.rb +4 -4
- data/lib/scout_apm/reporter.rb +0 -1
- data/lib/scout_apm/server_integrations/puma.rb +5 -2
- data/lib/scout_apm/store.rb +4 -2
- data/lib/scout_apm/version.rb +1 -1
- data/test/unit/config_test.rb +11 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a17bfe8d072cc469eafdaf6f5d9a53e29282ea6a
|
4
|
+
data.tar.gz: 39707f4cfacb744879297744928c038fe1a1c8aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9d208abf69daf67b5ca3bf487117e58cd434b445cd43126d9ec6ba90242b2179b1f4913aff3e3d8a38d89c6e0c2940d559059509baab072b7d0aac1899a936f
|
7
|
+
data.tar.gz: 91e4143528147d48c5eec703002cfd783579e89fca9c48806e0ec9745a57b622f660f9a7acd5186e6fc0ac5aef0c61f3e69bcc8a1bd5e29fd6ed94c5270e90d2
|
data/CHANGELOG.markdown
CHANGED
@@ -24,7 +24,7 @@ module ScoutApm
|
|
24
24
|
report_to_server
|
25
25
|
end
|
26
26
|
|
27
|
-
# In a running app, one process will get
|
27
|
+
# In a running app, one process will get the period ready for delivery, the others will see 0.
|
28
28
|
def report_to_server
|
29
29
|
period_to_report = ScoutApm::StoreReportingPeriodTimestamp.minutes_ago(2)
|
30
30
|
|
@@ -101,7 +101,7 @@ module ScoutApm
|
|
101
101
|
histogram_clause = "#{histograms.length} Histograms"
|
102
102
|
|
103
103
|
logger.info "#{time_clause} Delivering #{metrics_clause} and #{slow_trans_clause} and #{job_clause}, #{process_log_str}."
|
104
|
-
# logger.debug("
|
104
|
+
# logger.debug("\n\nMetrics: #{metrics.pretty_inspect}\nSlowTrans: #{slow_transactions.pretty_inspect}\nMetadata: #{metadata.inspect.pretty_inspect}\n\n")
|
105
105
|
end
|
106
106
|
|
107
107
|
# TODO: Move this into PayloadSerializer?
|
data/lib/scout_apm/agent.rb
CHANGED
@@ -113,6 +113,7 @@ module ScoutApm
|
|
113
113
|
def start(options = {})
|
114
114
|
@options.merge!(options)
|
115
115
|
|
116
|
+
|
116
117
|
@config = ScoutApm::Config.with_file(@config.value("config_file"))
|
117
118
|
layaway.config = config
|
118
119
|
|
@@ -123,6 +124,12 @@ module ScoutApm
|
|
123
124
|
|
124
125
|
load_instruments if should_load_instruments?(options)
|
125
126
|
|
127
|
+
if !@config.any_keys_found?
|
128
|
+
logger.info("No configuration file loaded, and no configuration found in ENV. " +
|
129
|
+
"For assistance configuring Scout, visit " +
|
130
|
+
"http://help.apm.scoutapp.com/#configuration-options")
|
131
|
+
end
|
132
|
+
|
126
133
|
return false unless preconditions_met?(options)
|
127
134
|
@started = true
|
128
135
|
logger.info "Starting monitoring for [#{environment.application_name}]. Framework [#{environment.framework}] App Server [#{environment.app_server}] Background Job Framework [#{environment.background_job_name}]."
|
data/lib/scout_apm/config.rb
CHANGED
@@ -5,25 +5,55 @@ require 'scout_apm/environment'
|
|
5
5
|
|
6
6
|
# Valid Config Options:
|
7
7
|
#
|
8
|
+
# This list is complete, but some are old and unused, or for developers of
|
9
|
+
# scout_apm itself. See the documentation at http://help.apm.scoutapp.com for
|
10
|
+
# customer-focused documentation.
|
11
|
+
#
|
8
12
|
# application_root - override the detected directory of the application
|
13
|
+
# compress_payload - true/false to enable gzipping of payload
|
9
14
|
# data_file - override the default temporary storage location. Must be a location in a writable directory
|
10
|
-
#
|
15
|
+
# dev_trace - true or false. Enables always-on tracing in development environmen only
|
11
16
|
# direct_host - override the default "direct" host. The direct_host bypasses the ingestion pipeline and goes directly to the webserver, and is primarily used for features under development.
|
17
|
+
# enable_background_jobs - true or false
|
18
|
+
# host - configuration used in development
|
19
|
+
# hostname - override the default hostname detection. Default varies by environment - either system hostname, or PAAS hostname
|
12
20
|
# key - the account key with Scout APM. Found in Settings in the Web UI
|
13
21
|
# log_file_path - either a directory or "STDOUT".
|
14
22
|
# log_level - DEBUG / INFO / WARN as usual
|
15
23
|
# monitor - true or false. False prevents any instrumentation from starting
|
16
24
|
# name - override the name reported to APM. This is the name that shows in the Web UI
|
17
|
-
#
|
25
|
+
# profile - turn on/off scoutprof (only applicable in Gem versions including scoutprof)
|
26
|
+
# proxy - an http proxy
|
18
27
|
# report_format - 'json' or 'marshal'. Marshal is legacy and will be removed.
|
19
|
-
#
|
20
|
-
# enable_background_jobs - true or false
|
28
|
+
# uri_reporting - 'path' or 'full_path' default is 'full_path', which reports URL params as well as the path.
|
21
29
|
#
|
22
30
|
# Any of these config settings can be set with an environment variable prefixed
|
23
31
|
# by SCOUT_ and uppercasing the key: SCOUT_LOG_LEVEL for instance.
|
24
32
|
|
25
33
|
module ScoutApm
|
26
34
|
class Config
|
35
|
+
KNOWN_CONFIG_OPTIONS = [
|
36
|
+
'application_root',
|
37
|
+
'compress_payload',
|
38
|
+
'config_file',
|
39
|
+
'data_file',
|
40
|
+
'dev_trace',
|
41
|
+
'direct_host',
|
42
|
+
'disabled_instruments',
|
43
|
+
'enable_background_jobs',
|
44
|
+
'host',
|
45
|
+
'hostname',
|
46
|
+
'ignore',
|
47
|
+
'key',
|
48
|
+
'log_level',
|
49
|
+
'log_file_path',
|
50
|
+
'monitor',
|
51
|
+
'name',
|
52
|
+
'profile',
|
53
|
+
'proxy',
|
54
|
+
'report_format',
|
55
|
+
'uri_reporting',
|
56
|
+
]
|
27
57
|
|
28
58
|
################################################################################
|
29
59
|
# Coersions
|
@@ -136,6 +166,10 @@ module ScoutApm
|
|
136
166
|
end
|
137
167
|
|
138
168
|
def value(key)
|
169
|
+
if ! KNOWN_CONFIG_OPTIONS.include?(key)
|
170
|
+
ScoutApm::Agent.instance.logger.debug("Requested looking up a unknown configuration key: #{key} (not a problem. Evaluate and add to config.rb)")
|
171
|
+
end
|
172
|
+
|
139
173
|
o = @overlays.detect{ |overlay| overlay.has_key?(key) }
|
140
174
|
raw_value = if o
|
141
175
|
o.value(key)
|
@@ -148,19 +182,24 @@ module ScoutApm
|
|
148
182
|
coercion.coerce(raw_value)
|
149
183
|
end
|
150
184
|
|
185
|
+
# Did we load anything for configuration?
|
186
|
+
def any_keys_found?
|
187
|
+
@overlays.any? { |overlay| overlay.any_keys_found? }
|
188
|
+
end
|
189
|
+
|
151
190
|
class ConfigDefaults
|
152
191
|
DEFAULTS = {
|
153
|
-
'
|
192
|
+
'compress_payload' => true,
|
193
|
+
'dev_trace' => false,
|
154
194
|
'direct_host' => 'https://apm.scoutapp.com',
|
155
|
-
'log_level' => 'info',
|
156
|
-
'uri_reporting' => 'full_path',
|
157
|
-
'report_format' => 'json',
|
158
195
|
'disabled_instruments' => [],
|
159
196
|
'enable_background_jobs' => true,
|
197
|
+
'host' => 'https://checkin.scoutapp.com',
|
160
198
|
'ignore' => [],
|
161
|
-
'
|
199
|
+
'log_level' => 'info',
|
162
200
|
'profile' => true, # for scoutprof
|
163
|
-
'
|
201
|
+
'report_format' => 'json',
|
202
|
+
'uri_reporting' => 'full_path',
|
164
203
|
}.freeze
|
165
204
|
|
166
205
|
def value(key)
|
@@ -170,6 +209,11 @@ module ScoutApm
|
|
170
209
|
def has_key?(key)
|
171
210
|
DEFAULTS.has_key?(key)
|
172
211
|
end
|
212
|
+
|
213
|
+
# Defaults are here, but not counted as user specified.
|
214
|
+
def any_keys_found?
|
215
|
+
false
|
216
|
+
end
|
173
217
|
end
|
174
218
|
|
175
219
|
|
@@ -184,6 +228,10 @@ module ScoutApm
|
|
184
228
|
def has_key?(*)
|
185
229
|
true
|
186
230
|
end
|
231
|
+
|
232
|
+
def any_keys_found?
|
233
|
+
false
|
234
|
+
end
|
187
235
|
end
|
188
236
|
|
189
237
|
class ConfigEnvironment
|
@@ -199,6 +247,12 @@ module ScoutApm
|
|
199
247
|
def key_to_env_key(key)
|
200
248
|
'SCOUT_' + key.upcase
|
201
249
|
end
|
250
|
+
|
251
|
+
def any_keys_found?
|
252
|
+
KNOWN_CONFIG_OPTIONS.any? { |option|
|
253
|
+
ENV.has_key?(key_to_env_key(option))
|
254
|
+
}
|
255
|
+
end
|
202
256
|
end
|
203
257
|
|
204
258
|
# Attempts to load a configuration file, and parse it as YAML. If the file
|
@@ -224,6 +278,12 @@ module ScoutApm
|
|
224
278
|
@settings.has_key?(key)
|
225
279
|
end
|
226
280
|
|
281
|
+
def any_keys_found?
|
282
|
+
KNOWN_CONFIG_OPTIONS.any? { |option|
|
283
|
+
@settings.has_key?(option)
|
284
|
+
}
|
285
|
+
end
|
286
|
+
|
227
287
|
private
|
228
288
|
|
229
289
|
def load_file(file)
|
@@ -255,7 +315,7 @@ module ScoutApm
|
|
255
315
|
@file_loaded = false
|
256
316
|
end
|
257
317
|
rescue Exception => e # Explicit `Exception` handling to catch SyntaxError and anything else that ERB or YAML may throw
|
258
|
-
logger.
|
318
|
+
logger.info("Failed loading configuration file (#{@resolved_file_path}): #{e.message}. ScoutAPM will continue starting with configuration from ENV and defaults")
|
259
319
|
@file_loaded = false
|
260
320
|
end
|
261
321
|
end
|
data/lib/scout_apm/layaway.rb
CHANGED
@@ -7,9 +7,6 @@
|
|
7
7
|
#
|
8
8
|
module ScoutApm
|
9
9
|
class Layaway
|
10
|
-
# How old a file needs to be in Seconds before it gets reported.
|
11
|
-
REPORTING_AGE = 120
|
12
|
-
|
13
10
|
# How long to let a stale file sit before deleting it.
|
14
11
|
# Letting it sit a bit may be useful for debugging
|
15
12
|
STALE_AGE = 10 * 60
|
@@ -60,7 +57,6 @@ module ScoutApm
|
|
60
57
|
def with_claim(timestamp)
|
61
58
|
coordinator_file = glob_pattern(timestamp, :coordinator)
|
62
59
|
|
63
|
-
|
64
60
|
begin
|
65
61
|
# This file gets deleted only by a process that successfully created and obtained the exclusive lock
|
66
62
|
f = File.open(coordinator_file, File::RDWR | File::CREAT | File::EXCL | File::NONBLOCK)
|
@@ -70,25 +66,35 @@ module ScoutApm
|
|
70
66
|
|
71
67
|
begin
|
72
68
|
if f
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
69
|
+
begin
|
70
|
+
ScoutApm::Agent.instance.logger.debug("Obtained Reporting Lock")
|
71
|
+
|
72
|
+
log_layaway_file_information
|
73
|
+
|
74
|
+
files = all_files_for(timestamp).reject{|l| l.to_s == coordinator_file.to_s }
|
75
|
+
rps = files.map{ |layaway| LayawayFile.new(layaway).load }.compact
|
76
|
+
if rps.any?
|
77
|
+
yield rps
|
78
|
+
|
79
|
+
ScoutApm::Agent.instance.logger.debug("Deleting the now-reported layaway files for #{timestamp.to_s}")
|
80
|
+
delete_files_for(timestamp) # also removes the coodinator_file
|
81
|
+
|
82
|
+
ScoutApm::Agent.instance.logger.debug("Checking for any Stale layaway files")
|
83
|
+
delete_stale_files(timestamp.to_time - STALE_AGE)
|
84
|
+
else
|
85
|
+
File.unlink(coordinator_file)
|
86
|
+
ScoutApm::Agent.instance.logger.debug("No layaway files to report")
|
87
|
+
end
|
88
|
+
|
89
|
+
true
|
90
|
+
rescue Exception => e
|
91
|
+
ScoutApm::Agent.instance.logger.debug("Caught an exception in with_claim, with the coordination file locked: #{e.message}, #{e.backtrace.inspect}")
|
92
|
+
raise
|
93
|
+
ensure
|
94
|
+
# Unlock the file when done!
|
95
|
+
f.flock(File::LOCK_UN | File::LOCK_NB)
|
96
|
+
f.close
|
86
97
|
end
|
87
|
-
|
88
|
-
# Unlock the file when done!
|
89
|
-
f.flock(File::LOCK_UN | File::LOCK_NB)
|
90
|
-
f.close
|
91
|
-
true
|
92
98
|
else
|
93
99
|
# Didn't obtain lock, another process is reporting. Return false from this function, but otherwise no work
|
94
100
|
false
|
@@ -97,7 +103,10 @@ module ScoutApm
|
|
97
103
|
end
|
98
104
|
|
99
105
|
def delete_files_for(timestamp)
|
100
|
-
all_files_for(timestamp).each { |layaway|
|
106
|
+
all_files_for(timestamp).each { |layaway|
|
107
|
+
ScoutApm::Agent.instance.logger.debug("Deleting layaway file: #{layaway}")
|
108
|
+
File.unlink(layaway)
|
109
|
+
}
|
101
110
|
end
|
102
111
|
|
103
112
|
def delete_stale_files(older_than)
|
@@ -108,6 +117,8 @@ module ScoutApm
|
|
108
117
|
select { |timestamp| timestamp.to_i < older_than.strftime(TIME_FORMAT).to_i }.
|
109
118
|
tap { |timestamps| ScoutApm::Agent.instance.logger.debug("Deleting stale layaway files with timestamps: #{timestamps.inspect}") }.
|
110
119
|
map { |timestamp| delete_files_for(timestamp) }
|
120
|
+
rescue => e
|
121
|
+
ScoutApm::Agent.instance.logger.debug("Problem deleting stale files: #{e.message}, #{e.backtrace.inspect}")
|
111
122
|
end
|
112
123
|
|
113
124
|
private
|
@@ -158,6 +169,20 @@ module ScoutApm
|
|
158
169
|
nil
|
159
170
|
end
|
160
171
|
end
|
172
|
+
|
173
|
+
def log_layaway_file_information
|
174
|
+
files_in_temp = Dir["#{directory}/*"].count
|
175
|
+
|
176
|
+
all_filenames = all_files_for(:all)
|
177
|
+
count_per_timestamp = Hash[
|
178
|
+
all_filenames.
|
179
|
+
group_by {|f| timestamp_from_filename(f) }.
|
180
|
+
map{ |timestamp, list| [timestamp, list.length] }
|
181
|
+
]
|
182
|
+
|
183
|
+
|
184
|
+
ScoutApm::Agent.instance.logger.debug("Total in #{directory}: #{files_in_temp}. Total Layaway Files: #{all_filenames.size}. By Timestamp: #{count_per_timestamp.inspect}")
|
185
|
+
end
|
161
186
|
end
|
162
187
|
end
|
163
188
|
|
@@ -88,8 +88,6 @@ module ScoutApm
|
|
88
88
|
if bt.any?
|
89
89
|
meta.backtrace = bt
|
90
90
|
@backtraces << meta
|
91
|
-
else
|
92
|
-
ScoutApm::Agent.instance.logger.debug { "Unable to capture an app-specific backtrace for #{meta.inspect}\n#{layer.backtrace}" }
|
93
91
|
end
|
94
92
|
end
|
95
93
|
|
@@ -157,9 +155,11 @@ module ScoutApm
|
|
157
155
|
end
|
158
156
|
end
|
159
157
|
|
160
|
-
def make_meta_options_desc_hash(layer)
|
158
|
+
def make_meta_options_desc_hash(layer, max_desc_length=1000)
|
161
159
|
if layer.desc
|
162
|
-
|
160
|
+
desc_s = layer.desc.to_s
|
161
|
+
trimmed_desc = desc_s[0 .. max_desc_length]
|
162
|
+
{:desc => trimmed_desc}
|
163
163
|
else
|
164
164
|
{}
|
165
165
|
end
|
data/lib/scout_apm/reporter.rb
CHANGED
@@ -27,7 +27,6 @@ module ScoutApm
|
|
27
27
|
headers.merge!(compression_headers)
|
28
28
|
|
29
29
|
compress_payload_size = payload.length
|
30
|
-
ScoutApm::Agent.instance.logger.debug("Compressed Payload: #{payload.inspect}")
|
31
30
|
ScoutApm::Agent.instance.logger.debug("Original Size: #{original_payload_size} Compressed Size: #{compress_payload_size}")
|
32
31
|
end
|
33
32
|
|
@@ -24,10 +24,13 @@ module ScoutApm
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def install
|
27
|
-
::Puma.cli_config.options[:before_worker_boot]
|
27
|
+
old = ::Puma.cli_config.options[:before_worker_boot] || []
|
28
|
+
new = Array(old) + [Proc.new do
|
28
29
|
logger.info "Installing Puma worker loop."
|
29
30
|
ScoutApm::Agent.instance.start_background_worker
|
30
|
-
end
|
31
|
+
end]
|
32
|
+
|
33
|
+
::Puma.cli_config.options[:before_worker_boot] = new
|
31
34
|
rescue
|
32
35
|
logger.warn "Unable to install Puma worker loop: #{$!.message}"
|
33
36
|
end
|
data/lib/scout_apm/store.rb
CHANGED
@@ -83,7 +83,7 @@ module ScoutApm
|
|
83
83
|
def write_to_layaway(layaway, force=false)
|
84
84
|
ScoutApm::Agent.instance.logger.debug("Writing to layaway#{" (Forced)" if force}")
|
85
85
|
|
86
|
-
reporting_periods.select { |time, rp| force || time.timestamp < current_timestamp.timestamp }.
|
86
|
+
reporting_periods.select { |time, rp| force || (time.timestamp < current_timestamp.timestamp) }.
|
87
87
|
each { |time, rp| collect_samplers(rp) }.
|
88
88
|
each { |time, rp| write_reporting_period(layaway, time, rp) }
|
89
89
|
end
|
@@ -95,7 +95,9 @@ module ScoutApm
|
|
95
95
|
rescue => e
|
96
96
|
ScoutApm::Agent.instance.logger.warn("Failed writing data to layaway file: #{e.message} / #{e.backtrace}")
|
97
97
|
ensure
|
98
|
-
reporting_periods.
|
98
|
+
ScoutApm::Agent.instance.logger.debug("Before delete, reporting periods length: #{reporting_periods.size}")
|
99
|
+
deleted_items = reporting_periods.delete(time)
|
100
|
+
ScoutApm::Agent.instance.logger.debug("After delete, reporting periods length: #{reporting_periods.size}. Did delete #{deleted_items}")
|
99
101
|
end
|
100
102
|
|
101
103
|
######################################
|
data/lib/scout_apm/version.rb
CHANGED
data/test/unit/config_test.rb
CHANGED
@@ -67,4 +67,15 @@ class ConfigTest < Minitest::Test
|
|
67
67
|
assert_equal 10, coercion.coerce(10)
|
68
68
|
assert_equal ["a"], coercion.coerce(["a"])
|
69
69
|
end
|
70
|
+
|
71
|
+
def test_any_keys_found
|
72
|
+
ENV.stubs(:has_key?).returns(nil)
|
73
|
+
|
74
|
+
conf = ScoutApm::Config.with_file("a_file_that_doesnt_exist.yml")
|
75
|
+
assert ! conf.any_keys_found?
|
76
|
+
|
77
|
+
ENV.stubs(:has_key?).with("SCOUT_MONITOR").returns("true")
|
78
|
+
conf = ScoutApm::Config.with_file("a_file_that_doesnt_exist.yml")
|
79
|
+
assert conf.any_keys_found?
|
80
|
+
end
|
70
81
|
end
|
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: 3.0.0.
|
4
|
+
version: 3.0.0.pre6
|
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: 2016-
|
12
|
+
date: 2016-12-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -293,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
293
293
|
version: 1.3.1
|
294
294
|
requirements: []
|
295
295
|
rubyforge_project: scout_apm
|
296
|
-
rubygems_version: 2.
|
296
|
+
rubygems_version: 2.5.1
|
297
297
|
signing_key:
|
298
298
|
specification_version: 4
|
299
299
|
summary: Ruby application performance monitoring
|