elastic-apm 0.7.4 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.

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: