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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +31 -0
- data/docs/api.asciidoc +63 -5
- data/docs/configuration.asciidoc +61 -0
- data/elastic-apm.gemspec +2 -0
- data/lib/elastic_apm/agent.rb +15 -4
- data/lib/elastic_apm/config.rb +13 -0
- data/lib/elastic_apm/filters.rb +3 -1
- data/lib/elastic_apm/http.rb +3 -1
- data/lib/elastic_apm/instrumenter.rb +9 -2
- data/lib/elastic_apm/middleware.rb +30 -9
- data/lib/elastic_apm/normalizers/action_mailer.rb +2 -3
- data/lib/elastic_apm/span.rb +3 -3
- data/lib/elastic_apm/system_info.rb +1 -1
- data/lib/elastic_apm/transaction.rb +15 -21
- data/lib/elastic_apm/version.rb +1 -1
- data/lib/elastic_apm/{timed_worker.rb → worker.rb} +25 -40
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3de476b7401d77bda31a38d7ba12a62eba3d0baa31827ad4ce255adaeb1d406d
|
4
|
+
data.tar.gz: e2f1752eeea668ab5dcbb3ea0f9eaea6b8378a40a8196350b08a3b03ada9c013
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28ceced097366bc0576da434bfd9e8c21924335caf7dba8e09df3cc25cd1510b063aa79a2b3df103b6c5903d07191ed62a4dae5ab2ecf62e0650ed1451420145
|
7
|
+
data.tar.gz: b1ca5cf053a35c9b07ee8255363257e023cdc0c1e9d0f948c1591bdfd8dcba7e5239704996b43d59f2c81acd5bf7d2df531c5acee02fd8a3d048fd71ab9de7ff
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -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'
|
data/docs/api.asciidoc
CHANGED
@@ -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[
|
269
|
-
t[
|
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
|
-
|
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
|
-
|
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
|
-
|
348
|
+
A `Context` provides more information to transactions. Build one with `ElasticAPM.build_context`.
|
291
349
|
|
data/docs/configuration.asciidoc
CHANGED
@@ -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]]
|
data/elastic-apm.gemspec
CHANGED
data/lib/elastic_apm/agent.rb
CHANGED
@@ -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/
|
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(
|
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
|
-
|
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 <<
|
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'
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -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[
|
data/lib/elastic_apm/filters.rb
CHANGED
data/lib/elastic_apm/http.rb
CHANGED
@@ -33,7 +33,9 @@ module ElasticAPM
|
|
33
33
|
|
34
34
|
def post(path, payload = {})
|
35
35
|
payload.merge! @base_payload
|
36
|
-
|
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/
|
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
|
-
|
14
|
-
|
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(
|
12
|
-
|
13
|
-
[transaction.name, TYPE, nil]
|
11
|
+
def normalize(_transaction, _name, payload)
|
12
|
+
[endpoint(payload), TYPE, nil]
|
14
13
|
end
|
15
14
|
|
16
15
|
private
|
data/lib/elastic_apm/span.rb
CHANGED
@@ -30,8 +30,8 @@ module ElasticAPM
|
|
30
30
|
end
|
31
31
|
# rubocop:enable Metrics/ParameterLists
|
32
32
|
|
33
|
-
attr_accessor :name, :
|
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
|
-
|
46
|
+
@stacktrace =
|
47
47
|
@transaction.instrumenter.agent.stacktrace_builder.build(
|
48
48
|
original_backtrace, type: :span
|
49
49
|
)
|
@@ -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 :
|
41
|
-
attr_reader :context, :duration, :dropped_spans, :root_span,
|
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
|
-
|
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
|
data/lib/elastic_apm/version.rb
CHANGED
@@ -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
|
7
|
+
class Worker
|
6
8
|
include Log
|
7
9
|
|
8
|
-
|
10
|
+
# @api private
|
11
|
+
class StopMsg; end
|
9
12
|
|
10
13
|
# @api private
|
11
|
-
class
|
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
|
55
|
-
|
40
|
+
def run_forever
|
41
|
+
@timer_task = build_timer_task.execute
|
56
42
|
|
57
|
-
while (msg = messages.pop
|
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.
|
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-
|
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:
|