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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7390634901f7ed74144c6790bc71af190f24c8d
4
- data.tar.gz: 8741c95aadfaa77c821e5543fe6e831a5d8d0b9d
3
+ metadata.gz: a17bfe8d072cc469eafdaf6f5d9a53e29282ea6a
4
+ data.tar.gz: 39707f4cfacb744879297744928c038fe1a1c8aa
5
5
  SHA512:
6
- metadata.gz: ef79c08136c8238d7c284a825e85a6dfd2b2d19af8b573582b0e6ec93a23dfc00789d39555380c59d152e4344caf3f05957a43d06cf743f14a8c1609ac6a0623
7
- data.tar.gz: d735090eea242c1bc02591c1068ad04aa839c776245b97e733801b54f94be98b434c1729dbf6fd3c70eabcbad917471d916fa983ddd15ceb6422088ba58ec7f7
6
+ metadata.gz: e9d208abf69daf67b5ca3bf487117e58cd434b445cd43126d9ec6ba90242b2179b1f4913aff3e3d8a38d89c6e0c2940d559059509baab072b7d0aac1899a936f
7
+ data.tar.gz: 91e4143528147d48c5eec703002cfd783579e89fca9c48806e0ec9745a57b622f660f9a7acd5186e6fc0ac5aef0c61f3e69bcc8a1bd5e29fd6ed94c5270e90d2
data/CHANGELOG.markdown CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  * ScoutProf BETA
4
4
 
5
+ # 2.1.17
6
+
7
+ * Additional logging around file system usage
8
+
5
9
  # 2.1.16
6
10
 
7
11
  * Extract the name correctly for DelayedJob workers run via ActiveJob
@@ -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 one period ready for delivery, the others will see 0.
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("Metrics: #{metrics.pretty_inspect}\nSlowTrans: #{slow_transactions.pretty_inspect}\nMetadata: #{metadata.inspect.pretty_inspect}")
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?
@@ -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}]."
@@ -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
- # host - override the default hostname detection. Default varies by environment - either system hostname, or PAAS hostname
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
- # uri_reporting - 'path' or 'full_path' default is 'full_path', which reports URL params as well as the path.
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
- # dev_trace - true or false. Enables always-on tracing in development environmen only
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
- 'host' => 'https://checkin.scoutapp.com',
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
- 'dev_trace' => false,
199
+ 'log_level' => 'info',
162
200
  'profile' => true, # for scoutprof
163
- 'compress_payload' => true,
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.debug("Failed loading configuration file: #{e.message}. ScoutAPM will continue starting with configuration from ENV and defaults")
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
@@ -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
- ScoutApm::Agent.instance.logger.debug("Obtained Reporting Lock")
75
-
76
- files = all_files_for(timestamp).reject{|l| l.to_s == coordinator_file.to_s }
77
- rps = files.map{ |layaway| LayawayFile.new(layaway).load }.compact
78
- if rps.any?
79
- yield rps
80
-
81
- delete_files_for(timestamp) # also removes the coodinator_file
82
- delete_stale_files(timestamp.to_time - STALE_AGE)
83
- else
84
- File.unlink(coordinator_file)
85
- ScoutApm::Agent.instance.logger.debug("No layaway files to report")
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| File.unlink(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
- {:desc => layer.desc.to_s}
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
@@ -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] << Proc.new do
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
@@ -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.delete(time)
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
  ######################################
@@ -1,3 +1,3 @@
1
1
  module ScoutApm
2
- VERSION = "3.0.0.pre5"
2
+ VERSION = "3.0.0.pre6"
3
3
  end
@@ -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.pre5
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-11-29 00:00:00.000000000 Z
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.4.8
296
+ rubygems_version: 2.5.1
297
297
  signing_key:
298
298
  specification_version: 4
299
299
  summary: Ruby application performance monitoring