elastic-apm 0.7.4 → 0.8.0

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.

Potentially problematic release.


This version of elastic-apm might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34b8dc72e1bc64618a6d3b3654ccdef57bdf3c596d875397b9f76df8236a0fef
4
- data.tar.gz: ba96b0160a873f20c840c3151bb1665d0c7c7bcb3fa6157c506107cae32197b1
3
+ metadata.gz: 3de476b7401d77bda31a38d7ba12a62eba3d0baa31827ad4ce255adaeb1d406d
4
+ data.tar.gz: e2f1752eeea668ab5dcbb3ea0f9eaea6b8378a40a8196350b08a3b03ada9c013
5
5
  SHA512:
6
- metadata.gz: 243f5ba02db88ca818d432679862b3bb0cd6469f305bf75391d4f180345228c6d0d11a7a60fc43a3e0276d58ead39933bd7450665cd799cf667fa9782f0bf9c2
7
- data.tar.gz: 26c7e98aa546c255a6b42e7a34d4b99680bc30de2225a2a3b697fae0f0b76d9326e13fe16f7ddcf65d58508a14aa9d80f5dec69c15169517479cb61d87de6c78
6
+ metadata.gz: 28ceced097366bc0576da434bfd9e8c21924335caf7dba8e09df3cc25cd1510b063aa79a2b3df103b6c5903d07191ed62a4dae5ab2ecf62e0650ed1451420145
7
+ data.tar.gz: b1ca5cf053a35c9b07ee8255363257e023cdc0c1e9d0f948c1591bdfd8dcba7e5239704996b43d59f2c81acd5bf7d2df531c5acee02fd8a3d048fd71ab9de7ff
data/.gitignore CHANGED
@@ -13,3 +13,4 @@
13
13
  Gemfile.lock
14
14
  /html_docs/
15
15
  spec/elastic_apm.log
16
+ spec/ruby-agent-junit.xml
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## 0.8.0 (2018-06-13)
8
+
9
+ ### Added
10
+
11
+ - Added an option to disable metrics collection ([#145](https://github.com/elastic/apm-agent-ruby/pulls/145))
12
+ - Filters can cancel the entire payload by returning `nil` ([#148](https://github.com/elastic/apm-agent-ruby/pulls/148))
13
+ - Added `ENV` version of the logging options ([#146](https://github.com/elastic/apm-agent-ruby/pull/146))
14
+ - Added `config.ignore_url_patterns` ([#151](https://github.com/elastic/apm-agent-ruby/pull/151))
15
+
16
+ ### Changed
17
+
18
+ - Use concurrent-ruby's TimerTask instead of `Thread#sleep`. Adds dependency on `concurrent-ruby`. ([#141](https://github.com/elastic/apm-agent-ruby/pull/141))
19
+
20
+ ### Fixed
21
+
22
+ - Remove newline on `hostname`
23
+ - Fixed ActionMailer spans renaming their transaction
24
+
25
+ ## 0.7.4 - 2018-06-07
26
+
27
+ Beginning of this document
28
+
29
+ ### Fixed
30
+
31
+ - Fix overwriting custom logger with Rails'
@@ -260,14 +260,17 @@ Arguments:
260
260
 
261
261
  Return the altered payload.
262
262
 
263
+ If `nil` is returned all subsequent filters will be skipped and the post request cancelled.
264
+
263
265
  Example:
264
266
 
265
267
  [source,ruby]
266
268
  ----
267
269
  ElasticAPM.add_filter(:filter_pings) do |payload|
268
- payload['transactions']&.reject! do |t|
269
- t['name'] == 'PingsController#index'
270
+ payload[:transactions]&.reject! do |t|
271
+ t[:name] == 'PingsController#index'
270
272
  end
273
+ payload
271
274
  end
272
275
  ----
273
276
 
@@ -275,17 +278,72 @@ end
275
278
  [[api-transaction]]
276
279
  === Transaction
277
280
 
278
- Things
281
+ `ElasticAPM.transaction` returns a `Transaction` (if the agent is running).
282
+
283
+ [float]
284
+ ==== Properties
285
+
286
+ - `name`: String
287
+ - `type`: String
288
+
289
+ [float]
290
+ [[api-transaction-release]]
291
+ ==== `#release`
292
+
293
+ Makes sure the transaction is no longer `ElasticAPM.current_transaction`.
294
+
295
+ [float]
296
+ [[api-transaction-done]]
297
+ ==== `#done(result)`
298
+
299
+ *Args:*
300
+
301
+ - `result`: String result of transaction, eg. `success`. Default: `nil`.
302
+
303
+ Ends the transaction, settings its `duration` to µs since it began and sets its result.
304
+
305
+ Returns `self`.
306
+
307
+ [float]
308
+ [[api-transaction-done_]]
309
+ ==== `#done?`
310
+
311
+ Returns whether the transaction is done.
312
+
313
+ [float]
314
+ [[api-transaction-submit]]
315
+ ==== `#submit(result, status:, headers:)`
316
+
317
+ *Args:*
318
+
319
+ - `result`: String result of transaction, eg. `success`. Default: `nil`.
320
+ - `status`: HTTP status code (for request transactions). Default: `nil`.
321
+ - `headers`: HTTP headers (for request transactions). Default: `{}`.
322
+
323
+ Ends transaction with done, adds HTTP request information, releases it and submits
324
+ it to the queue of transactions waiting to be sent to APM Server.
325
+
326
+ Returns `self`.
327
+
328
+ [float]
329
+ [[api-transaction-sampled_]]
330
+ ==== #sampled?
331
+
332
+ Whether the transaction is _sampled_ eg. it includes stacktraces for its spans.
279
333
 
280
334
  [float]
281
335
  [[api-span]]
282
336
  === Span
283
337
 
284
- Things
338
+ [float]
339
+ ==== Properties
340
+
341
+ - `name`: String
342
+ - `type`: String
285
343
 
286
344
  [float]
287
345
  [[api-context]]
288
346
  === Context
289
347
 
290
- Things
348
+ A `Context` provides more information to transactions. Build one with `ElasticAPM.build_context`.
291
349
 
@@ -209,6 +209,48 @@ otherwise, the default is `nil`.
209
209
 
210
210
  The host name to use when sending error and transaction data to the APM server.
211
211
 
212
+ [float]
213
+ [[config-log-path]]
214
+ ==== `log_path`
215
+
216
+ [options="header"]
217
+ |============
218
+ | Environment | `Config` key | Default | Example
219
+ | `ELASTIC_APM_LOG_PATH` | `log_path` | `nil` | `log/elastic_apm.log`
220
+ |============
221
+
222
+ A path to a log file.
223
+
224
+ By default Elastic APM logs to `stdout` or uses `Rails.log` when used with Rails.
225
+
226
+ Should support both absolute and relative paths. Just make sure the directory exists.
227
+
228
+ [float]
229
+ [[config-log-level]]
230
+ ==== `log_level`
231
+
232
+ [options="header"]
233
+ |============
234
+ | Environment | `Config` key | Default
235
+ | `ELASTIC_APM_LOG_LEVEL` | `log_level` | `Logger::DEBUG # => 0`
236
+ |============
237
+
238
+ By default Elastic APM logs to `stdout` or uses `Rails.log` when used with Rails.
239
+
240
+ [float]
241
+ [[config-logger]]
242
+ ==== `logger`
243
+
244
+ [options="header"]
245
+ |============
246
+ | Environment | `Config` key | Default | Example
247
+ | N/A | `logger` | Depends | `Logger.new('path/to_file.log')`
248
+ |============
249
+
250
+ By default Elastic APM logs to `stdout` or uses `Rails.log` when used with Rails.
251
+
252
+ Use this to provide another logger. Expected to have the same API as Ruby's built-in `Logger`.
253
+
212
254
  [float]
213
255
  [[config-source-lines-error-app-frames]]
214
256
  ==== `source_lines_error_app_frames`
@@ -361,6 +403,25 @@ https://github.com/elastic/apm-agent-ruby/blob/1.x/lib/elastic_apm/filters/secre
361
403
  what looks like confidential information] from the request/response headers.
362
404
  Use this option to add your own custom header keys to the list of filtered keys.
363
405
 
406
+ When setting this option via `ENV`, use a comma separated string.
407
+ Eg. `ELASTIC_APM_CUSTOM_KEY_FILTERS="a,b" # => [/a/, /b/]`
408
+
409
+ [float]
410
+ [[config-custom-ignore-url-patterns]]
411
+ ==== `ignore_url_patterns`
412
+ [options="header"]
413
+ |============
414
+ | Environment | `Config` key | Default | Example
415
+ | `ELASTIC_APM_IGNORE_URL_PATTERNS` | `ignore_url_patterns` | `[]` | `['^/ping', %r{^/admin}]`
416
+ |============
417
+
418
+ Use this option to ignroe certain URL patterns eg. healthchecks or admin sections.
419
+
420
+ _Ignoring_ in this context means _don't wrap in a <<api-transaction,Transaction>>_.
421
+ Errors will still be reported.
422
+
423
+ When setting this option via `ENV`, use a comma separated string.
424
+ Eg. `ELASTIC_APM_IGNORE_URL_PATTERNS="a,b" # => [/a/, /b/]`
364
425
 
365
426
  [float]
366
427
  [[config-filter-exception-types]]
@@ -18,5 +18,7 @@ Gem::Specification.new do |spec|
18
18
  f.match(%r{^(test|spec|features)/})
19
19
  end
20
20
 
21
+ spec.add_dependency('concurrent-ruby', '~> 1.0.0')
22
+
21
23
  spec.require_paths = ['lib']
22
24
  end
@@ -8,7 +8,7 @@ require 'elastic_apm/error'
8
8
  require 'elastic_apm/http'
9
9
  require 'elastic_apm/spies'
10
10
  require 'elastic_apm/serializers'
11
- require 'elastic_apm/timed_worker'
11
+ require 'elastic_apm/worker'
12
12
 
13
13
  module ElasticAPM
14
14
  # rubocop:disable Metrics/ClassLength
@@ -107,12 +107,23 @@ module ElasticAPM
107
107
  boot_worker unless worker_running?
108
108
 
109
109
  pending_transactions.push(transaction)
110
+
111
+ return unless should_flush_transactions?
112
+
113
+ messages.push(Worker::FlushMsg.new)
114
+ end
115
+
116
+ def should_flush_transactions?
117
+ return true unless config.flush_interval
118
+ return true if pending_transactions.length >= config.max_queue_size
119
+
120
+ false
110
121
  end
111
122
 
112
123
  def enqueue_error(error)
113
124
  boot_worker unless worker_running?
114
125
 
115
- messages.push(TimedWorker::ErrorMsg.new(error))
126
+ messages.push(Worker::ErrorMsg.new(error))
116
127
  end
117
128
 
118
129
  # instrumentation
@@ -182,7 +193,7 @@ module ElasticAPM
182
193
  debug 'Booting worker'
183
194
 
184
195
  @worker_thread = Thread.new do
185
- TimedWorker.new(
196
+ Worker.new(
186
197
  config,
187
198
  messages,
188
199
  pending_transactions,
@@ -192,7 +203,7 @@ module ElasticAPM
192
203
  end
193
204
 
194
205
  def kill_worker
195
- messages << TimedWorker::StopMsg.new
206
+ messages << Worker::StopMsg.new
196
207
 
197
208
  if @worker_thread && !@worker_thread.join(5) # 5 secs
198
209
  raise 'Failed to wait for worker, not all messages sent'
@@ -14,6 +14,7 @@ module ElasticAPM
14
14
  environment: ENV['RAILS_ENV'] || ENV['RACK_ENV'],
15
15
  enabled_environments: %w[production],
16
16
  disable_environment_warning: false,
17
+ instrument: true,
17
18
 
18
19
  log_path: nil,
19
20
  log_level: Logger::DEBUG,
@@ -46,6 +47,7 @@ module ElasticAPM
46
47
  current_user_username_method: :username,
47
48
 
48
49
  custom_key_filters: [],
50
+ ignore_url_patterns: [],
49
51
 
50
52
  view_paths: [],
51
53
  root_path: Dir.pwd
@@ -59,6 +61,10 @@ module ElasticAPM
59
61
  'ELASTIC_APM_ENABLED_ENVIRONMENTS' => [:list, 'enabled_environments'],
60
62
  'ELASTIC_APM_DISABLE_ENVIRONMENT_WARNING' =>
61
63
  [:bool, 'disable_environment_warning'],
64
+ 'ELASTIC_APM_INSTRUMENT' => [:bool, 'instrument'],
65
+
66
+ 'ELASTIC_APM_LOG_PATH' => 'log_path',
67
+ 'ELASTIC_APM_LOG_LEVEL' => [:int, 'log_level'],
62
68
 
63
69
  'ELASTIC_APM_SERVICE_NAME' => 'service_name',
64
70
  'ELASTIC_APM_SERVICE_VERSION' => 'service_version',
@@ -78,6 +84,7 @@ module ElasticAPM
78
84
  [:int, 'span_frames_min_duration'],
79
85
 
80
86
  'ELASTIC_APM_CUSTOM_KEY_FILTERS' => [:list, 'custom_key_filters'],
87
+ 'ELASTIC_APM_IGNORE_URL_PATTERNS' => [:list, 'ignore_url_patterns'],
81
88
 
82
89
  'ELASTIC_APM_MAX_QUEUE_SIZE' => [:int, 'max_queue_size'],
83
90
  'ELASTIC_APM_FLUSH_INTERVAL' => 'flush_interval',
@@ -109,6 +116,7 @@ module ElasticAPM
109
116
  attr_accessor :environment
110
117
  attr_accessor :enabled_environments
111
118
  attr_accessor :disable_environment_warning
119
+ attr_accessor :instrument
112
120
 
113
121
  attr_accessor :service_name
114
122
  attr_accessor :service_version
@@ -152,6 +160,7 @@ module ElasticAPM
152
160
  attr_accessor :current_user_username_method
153
161
 
154
162
  attr_reader :custom_key_filters
163
+ attr_reader :ignore_url_patterns
155
164
 
156
165
  alias :disable_environment_warning? :disable_environment_warning
157
166
  alias :verify_server_cert? :verify_server_cert
@@ -188,6 +197,10 @@ module ElasticAPM
188
197
  @custom_key_filters = Array(filters).map(&Regexp.method(:new))
189
198
  end
190
199
 
200
+ def ignore_url_patterns=(strings)
201
+ @ignore_url_patterns = Array(strings).map(&Regexp.method(:new))
202
+ end
203
+
191
204
  # rubocop:disable Metrics/MethodLength
192
205
  def available_spies
193
206
  %w[
@@ -32,7 +32,9 @@ module ElasticAPM
32
32
 
33
33
  def apply(payload)
34
34
  @filters.reduce(payload) do |result, (_key, filter)|
35
- filter.call(result)
35
+ result = filter.call(result)
36
+ break if result.nil?
37
+ result
36
38
  end
37
39
  end
38
40
 
@@ -33,7 +33,9 @@ module ElasticAPM
33
33
 
34
34
  def post(path, payload = {})
35
35
  payload.merge! @base_payload
36
- filters.apply(payload)
36
+
37
+ payload = filters.apply(payload)
38
+ return if payload.nil?
37
39
 
38
40
  request = prepare_request path, payload.to_json
39
41
  response = @adapter.perform request
@@ -55,8 +55,14 @@ module ElasticAPM
55
55
  @transaction_info.current = transaction
56
56
  end
57
57
 
58
- # rubocop:disable Metrics/MethodLength
58
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
59
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
59
60
  def transaction(*args)
61
+ unless config.instrument
62
+ yield if block_given?
63
+ return
64
+ end
65
+
60
66
  if (transaction = current_transaction)
61
67
  yield transaction if block_given?
62
68
  return transaction
@@ -82,7 +88,8 @@ module ElasticAPM
82
88
 
83
89
  transaction
84
90
  end
85
- # rubocop:enable Metrics/MethodLength
91
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
92
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
86
93
 
87
94
  def random_sample?
88
95
  rand <= config.transaction_sample_rate
@@ -7,19 +7,16 @@ module ElasticAPM
7
7
  @app = app
8
8
  end
9
9
 
10
- # rubocop:disable Metrics/MethodLength
10
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
11
11
  def call(env)
12
12
  begin
13
- transaction = ElasticAPM.transaction 'Rack', 'request',
14
- context: ElasticAPM.build_context(env)
13
+ if running? && !path_ignored?(env)
14
+ transaction = build_transaction(env)
15
+ end
15
16
 
16
17
  resp = @app.call env
17
- status, headers, = resp
18
18
 
19
- if transaction
20
- result = "HTTP #{status.to_s[0]}xx"
21
- transaction.submit(result, status: status, headers: headers)
22
- end
19
+ submit_transaction(transaction, *resp) if transaction
23
20
  rescue InternalError
24
21
  raise # Don't report ElasticAPM errors
25
22
  rescue ::Exception => e
@@ -32,6 +29,30 @@ module ElasticAPM
32
29
 
33
30
  resp
34
31
  end
35
- # rubocop:enable Metrics/MethodLength
32
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
33
+
34
+ def submit_transaction(transaction, status, headers, _body)
35
+ result = "HTTP #{status.to_s[0]}xx"
36
+ transaction.submit(result, status: status, headers: headers)
37
+ end
38
+
39
+ def path_ignored?(env)
40
+ config.ignore_url_patterns.any? do |r|
41
+ env['PATH_INFO'] =~ r
42
+ end
43
+ end
44
+
45
+ def build_transaction(env)
46
+ ElasticAPM.transaction 'Rack', 'request',
47
+ context: ElasticAPM.build_context(env)
48
+ end
49
+
50
+ def running?
51
+ ElasticAPM.running?
52
+ end
53
+
54
+ def config
55
+ ElasticAPM.agent.config
56
+ end
36
57
  end
37
58
  end
@@ -8,9 +8,8 @@ module ElasticAPM
8
8
  register 'process.action_mailer'
9
9
  TYPE = 'app.mailer.action'.freeze
10
10
 
11
- def normalize(transaction, _name, payload)
12
- transaction.name = endpoint(payload)
13
- [transaction.name, TYPE, nil]
11
+ def normalize(_transaction, _name, payload)
12
+ [endpoint(payload), TYPE, nil]
14
13
  end
15
14
 
16
15
  private
@@ -30,8 +30,8 @@ module ElasticAPM
30
30
  end
31
31
  # rubocop:enable Metrics/ParameterLists
32
32
 
33
- attr_accessor :name, :context, :type, :stacktrace, :original_backtrace
34
- attr_reader :id, :duration, :parent, :relative_start
33
+ attr_accessor :name, :type, :original_backtrace
34
+ attr_reader :id, :context, :stacktrace, :duration, :parent, :relative_start
35
35
 
36
36
  def start
37
37
  @relative_start = Util.micros - @transaction.timestamp
@@ -43,7 +43,7 @@ module ElasticAPM
43
43
  @duration = Util.micros - @transaction.timestamp - relative_start
44
44
 
45
45
  if original_backtrace && long_enough_for_stacktrace?
46
- self.stacktrace =
46
+ @stacktrace =
47
47
  @transaction.instrumenter.agent.stacktrace_builder.build(
48
48
  original_backtrace, type: :span
49
49
  )
@@ -9,7 +9,7 @@ module ElasticAPM
9
9
 
10
10
  def build
11
11
  {
12
- hostname: @config.hostname || `hostname`,
12
+ hostname: @config.hostname || `hostname`.chomp,
13
13
  architecture: platform.cpu,
14
14
  platform: platform.os
15
15
  }
@@ -3,7 +3,6 @@
3
3
  require 'securerandom'
4
4
 
5
5
  module ElasticAPM
6
- # rubocop:disable Metrics/ClassLength
7
6
  # @api private
8
7
  class Transaction
9
8
  DEFAULT_TYPE = 'custom'.freeze
@@ -37,9 +36,9 @@ module ElasticAPM
37
36
  end
38
37
  # rubocop:enable Metrics/MethodLength
39
38
 
40
- attr_accessor :id, :name, :result, :type
41
- attr_reader :context, :duration, :dropped_spans, :root_span, :timestamp,
42
- :spans, :notifications, :sampled, :instrumenter
39
+ attr_accessor :name, :type
40
+ attr_reader :id, :context, :duration, :dropped_spans, :root_span,
41
+ :timestamp, :spans, :result, :notifications, :sampled, :instrumenter
43
42
 
44
43
  def release
45
44
  @instrumenter.current_transaction = nil
@@ -53,7 +52,7 @@ module ElasticAPM
53
52
  end
54
53
 
55
54
  def done?
56
- !!(@result && @duration)
55
+ !!@duration
57
56
  end
58
57
 
59
58
  def submit(result = nil, status: nil, headers: {})
@@ -70,10 +69,6 @@ module ElasticAPM
70
69
  self
71
70
  end
72
71
 
73
- def running_spans
74
- spans.select(&:running?)
75
- end
76
-
77
72
  # rubocop:disable Metrics/MethodLength
78
73
  def span(name, type = nil, backtrace: nil, context: nil)
79
74
  unless sampled?
@@ -102,17 +97,6 @@ module ElasticAPM
102
97
  end
103
98
  # rubocop:enable Metrics/MethodLength
104
99
 
105
- def build_and_start_span(name, type, context, backtrace)
106
- span = next_span(name, type, context)
107
- spans << span
108
-
109
- if backtrace && span_frames_min_duration?
110
- span.original_backtrace = backtrace
111
- end
112
-
113
- span.start
114
- end
115
-
116
100
  def current_span
117
101
  spans.reverse.lazy.find(&:running?)
118
102
  end
@@ -148,6 +132,16 @@ module ElasticAPM
148
132
  def span_frames_min_duration?
149
133
  @instrumenter.agent.config.span_frames_min_duration != 0
150
134
  end
135
+
136
+ def build_and_start_span(name, type, context, backtrace)
137
+ span = next_span(name, type, context)
138
+ spans << span
139
+
140
+ if backtrace && span_frames_min_duration?
141
+ span.original_backtrace = backtrace
142
+ end
143
+
144
+ span.start
145
+ end
151
146
  end
152
- # rubocop:enable Metrics/ClassLength
153
147
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ElasticAPM
4
- VERSION = '0.7.4'.freeze
4
+ VERSION = '0.8.0'.freeze
5
5
  end
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'concurrent/timer_task'
4
+
3
5
  module ElasticAPM
4
6
  # @api private
5
- class TimedWorker
7
+ class Worker
6
8
  include Log
7
9
 
8
- SLEEP_INTERVAL = 0.1
10
+ # @api private
11
+ class StopMsg; end
9
12
 
10
13
  # @api private
11
- class StopMsg
12
- end
14
+ class FlushMsg; end
13
15
 
14
16
  # @api private
15
17
  class ErrorMsg
@@ -26,8 +28,6 @@ module ElasticAPM
26
28
  @pending_transactions = pending_transactions
27
29
  @adapter = adapter
28
30
 
29
- @last_sent_transactions = Time.now.utc
30
-
31
31
  @serializers = Struct.new(:transactions, :errors).new(
32
32
  Serializers::Transactions.new(config),
33
33
  Serializers::Errors.new(config)
@@ -36,46 +36,43 @@ module ElasticAPM
36
36
 
37
37
  attr_reader :config, :messages, :pending_transactions
38
38
 
39
- def run_forever
40
- loop do
41
- run_once
42
- sleep SLEEP_INTERVAL
43
- end
44
- end
45
-
46
- def run_once
47
- collect_and_send_transactions if should_flush_transactions?
48
- process_messages
49
- end
50
-
51
- private
52
-
53
39
  # rubocop:disable Metrics/MethodLength
54
- def process_messages
55
- should_exit = false
40
+ def run_forever
41
+ @timer_task = build_timer_task.execute
56
42
 
57
- while (msg = messages.pop(true))
43
+ while (msg = messages.pop)
58
44
  case msg
59
45
  when ErrorMsg
60
46
  post_error msg
47
+ when FlushMsg
48
+ collect_and_send_transactions
61
49
  when StopMsg
62
- should_exit = true
63
-
64
50
  # empty collected transactions before exiting
65
51
  collect_and_send_transactions
52
+ stop!
66
53
  end
67
54
  end
68
- rescue ThreadError # queue empty
69
- Thread.exit if should_exit
70
55
  end
71
56
  # rubocop:enable Metrics/MethodLength
72
57
 
58
+ private
59
+
60
+ def stop!
61
+ @timer_task && @timer_task.shutdown
62
+ Thread.exit
63
+ end
64
+
65
+ def build_timer_task
66
+ Concurrent::TimerTask.new(execution_interval: config.flush_interval) do
67
+ messages.push(FlushMsg.new)
68
+ end
69
+ end
70
+
73
71
  def post_error(msg)
74
72
  payload = @serializers.errors.build_all([msg.error])
75
73
  @adapter.post('/v1/errors', payload)
76
74
  end
77
75
 
78
- # rubocop:disable Metrics/MethodLength
79
76
  def collect_and_send_transactions
80
77
  return if pending_transactions.empty?
81
78
 
@@ -90,10 +87,7 @@ module ElasticAPM
90
87
  debug e.backtrace.join("\n")
91
88
  nil
92
89
  end
93
-
94
- @last_sent_transactions = Time.now
95
90
  end
96
- # rubocop:enable Metrics/MethodLength
97
91
 
98
92
  def collect_batched_transactions
99
93
  batch = []
@@ -108,14 +102,5 @@ module ElasticAPM
108
102
 
109
103
  batch
110
104
  end
111
-
112
- def should_flush_transactions?
113
- interval = config.flush_interval
114
-
115
- return true if interval.nil?
116
- return true if pending_transactions.length >= config.max_queue_size
117
-
118
- Time.now.utc - @last_sent_transactions >= interval
119
- end
120
105
  end
121
106
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic-apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikkel Malmberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-07 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2018-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: concurrent-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
13
27
  description:
14
28
  email:
15
29
  - mikkel@elastic.co
@@ -22,6 +36,7 @@ files:
22
36
  - ".rspec"
23
37
  - ".rubocop.yml"
24
38
  - ".travis.yml"
39
+ - CHANGELOG.md
25
40
  - CODE_OF_CONDUCT.md
26
41
  - Gemfile
27
42
  - LICENSE
@@ -95,7 +110,6 @@ files:
95
110
  - lib/elastic_apm/stacktrace_builder.rb
96
111
  - lib/elastic_apm/subscriber.rb
97
112
  - lib/elastic_apm/system_info.rb
98
- - lib/elastic_apm/timed_worker.rb
99
113
  - lib/elastic_apm/transaction.rb
100
114
  - lib/elastic_apm/util.rb
101
115
  - lib/elastic_apm/util/dig.rb
@@ -103,6 +117,7 @@ files:
103
117
  - lib/elastic_apm/util/inspector.rb
104
118
  - lib/elastic_apm/util/lru_cache.rb
105
119
  - lib/elastic_apm/version.rb
120
+ - lib/elastic_apm/worker.rb
106
121
  - vendor/.gitkeep
107
122
  homepage: https://github.com/elastic/apm-agent-ruby
108
123
  licenses: