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 +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:
|