elastic-apm 2.5.0 → 2.6.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/CHANGELOG.md +23 -0
- data/CONTRIBUTING.md +3 -2
- data/Jenkinsfile +5 -3
- data/README.md +1 -1
- data/docs/api.asciidoc +1 -0
- data/docs/configuration.asciidoc +35 -3
- data/lib/elastic_apm.rb +22 -6
- data/lib/elastic_apm/agent.rb +6 -4
- data/lib/elastic_apm/config.rb +37 -5
- data/lib/elastic_apm/context.rb +15 -3
- data/lib/elastic_apm/context/user.rb +4 -0
- data/lib/elastic_apm/context_builder.rb +19 -12
- data/lib/elastic_apm/error.rb +2 -8
- data/lib/elastic_apm/error_builder.rb +18 -17
- data/lib/elastic_apm/metrics/cpu_mem.rb +13 -2
- data/lib/elastic_apm/middleware.rb +8 -5
- data/lib/elastic_apm/railtie.rb +35 -11
- data/lib/elastic_apm/spies/action_dispatch.rb +3 -1
- data/lib/elastic_apm/spies/faraday.rb +4 -0
- data/lib/elastic_apm/transport/connection.rb +27 -7
- data/lib/elastic_apm/transport/serializers/context_serializer.rb +2 -0
- data/lib/elastic_apm/transport/serializers/error_serializer.rb +7 -4
- data/lib/elastic_apm/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 461871ffc956519fbd712017336bcc012f0c41d6b1696dc32a3117860b3b736d
|
4
|
+
data.tar.gz: 468207605feaa4d888fbf1bfcd665c8f7bb0953d0b5c7e1e92d4f266c85855f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b22550a4a59b6311e55a86306ab9c5af705f65754e7f7f0afa7509565724f68c4ada5781c17354bc724da181acc2158c45f8447297dea1ead99bdc20f74094a9
|
7
|
+
data.tar.gz: 15b61ed7489a8468a56983c0e8a33418441695bcc28c08e477110204ba8b53e1a022ebfbd660720e8a3227004ac0adc1b8eeb34523cceba902f78129421baabe
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## 2.6.0 (2019-03-19)
|
8
|
+
|
9
|
+
### Deprecated
|
10
|
+
|
11
|
+
- `ElasticAPM.build_context` now takes two keyword arguments instead of a single, normal argument. [Docs](https://www.elastic.co/guide/en/apm/agent/ruby/2.x/api.html#api-agent-build-context).
|
12
|
+
- The option `capture_body` has a string value instead of boolean. [Docs](https://www.elastic.co/guide/en/apm/agent/ruby/2.x/configuration.html#config-capture-body).
|
13
|
+
|
14
|
+
Both APIs are backwards compatible with fallbacks and deprecation warnings, scheduled for removal in next major release.
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- Configuration options to use an HTTP proxy ([#352](https://github.com/elastic/apm-agent-ruby/pull/352))
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
|
22
|
+
- Errors get their own contexts, perhaps leading to slightly different (but more correct) results. ([#335](https://github.com/elastic/apm-agent-ruby/pull/335))
|
23
|
+
- The agent no longer starts automatically inside Rails' console ([#343](https://github.com/elastic/apm-agent-ruby/pull/343))
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
- Fixed reading available memory on older Linux kernels ([#351](https://github.com/elastic/apm-agent-ruby/pull/351))
|
28
|
+
- Don't apply filters to original response headers ([#354](https://github.com/elastic/apm-agent-ruby/pull/354))
|
29
|
+
|
7
30
|
## 2.5.0 (2019-03-01)
|
8
31
|
|
9
32
|
### Added
|
data/CONTRIBUTING.md
CHANGED
@@ -85,8 +85,9 @@ $ spec/scripts/spec.sh ruby-2.6 rails-5.2
|
|
85
85
|
To release a new version:
|
86
86
|
|
87
87
|
1. Update `VERSION` in `lib/elastic_apm/version.rb` according to the changes (major, minor, patch).
|
88
|
-
2. Update `CHANGELOG.md` to reflect the new version
|
89
|
-
3.
|
88
|
+
2. Update `CHANGELOG.md` to reflect the new version – change _Unreleased_ section to _Version (release date)_.
|
89
|
+
3. Make a new commit with the changes above, with a message in the style of `vX.X.X`.
|
90
|
+
4. Run `rake release`. This will...
|
90
91
|
1. Tag the current commit as new version.
|
91
92
|
2. Push the tag to GitHub.
|
92
93
|
3. Build the gem and upload to Rubygems (local user needs to be signed in and authorized.)
|
data/Jenkinsfile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env groovy
|
2
|
-
@Library('apm@
|
2
|
+
@Library('apm@current') _
|
3
3
|
|
4
4
|
import co.elastic.matrix.*
|
5
5
|
import groovy.transform.Field
|
@@ -25,6 +25,8 @@ pipeline {
|
|
25
25
|
ansiColor('xterm')
|
26
26
|
disableResume()
|
27
27
|
durabilityHint('PERFORMANCE_OPTIMIZED')
|
28
|
+
rateLimitBuilds(throttle: [count: 60, durationName: 'hour', userBoost: true])
|
29
|
+
quietPeriod(10)
|
28
30
|
}
|
29
31
|
triggers {
|
30
32
|
issueCommentTrigger('.*(?:jenkins\\W+)?run\\W+(?:the\\W+)?tests(?:\\W+please)?.*')
|
@@ -39,7 +41,7 @@ pipeline {
|
|
39
41
|
Checkout the code and stash it, to use it on other stages.
|
40
42
|
*/
|
41
43
|
stage('Checkout') {
|
42
|
-
agent { label '
|
44
|
+
agent { label 'master || immutable' }
|
43
45
|
options { skipDefaultCheckout() }
|
44
46
|
steps {
|
45
47
|
deleteDir()
|
@@ -51,7 +53,7 @@ pipeline {
|
|
51
53
|
Execute unit tests.
|
52
54
|
*/
|
53
55
|
stage('Test') {
|
54
|
-
agent { label '
|
56
|
+
agent { label 'linux && immutable' }
|
55
57
|
options { skipDefaultCheckout() }
|
56
58
|
steps {
|
57
59
|
deleteDir()
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# elastic-apm
|
2
2
|
## Elastic APM agent for ♦️Ruby
|
3
3
|
|
4
|
-
[![Jenkins](https://
|
4
|
+
[![Jenkins](https://apm-ci.elastic.co/buildStatus/icon?job=apm-agent-ruby/apm-agent-ruby-mbp/master)](https://apm-ci.elastic.co/job/apm-agent-ruby/apm-agent-ruby-mbp/master) [![Gem](https://img.shields.io/gem/v/elastic-apm.svg)](https://rubygems.org/gems/elastic-apm) [![codecov](https://codecov.io/gh/elastic/apm-agent-ruby/branch/master/graph/badge.svg)](https://codecov.io/gh/elastic/apm-agent-ruby)
|
5
5
|
|
6
6
|
The official Rubygem for [Elastic][] [APM][].
|
7
7
|
|
data/docs/api.asciidoc
CHANGED
@@ -182,6 +182,7 @@ A context provides information about the current request, response, user and mor
|
|
182
182
|
Arguments:
|
183
183
|
|
184
184
|
* `rack_env`: An instance of Rack::Env
|
185
|
+
* `for_type`: Symbol representing type of event, eg. `:transaction` or `error`
|
185
186
|
|
186
187
|
Returns the built context.
|
187
188
|
|
data/docs/configuration.asciidoc
CHANGED
@@ -177,11 +177,21 @@ It has to be provided in *<<config-format-duration, duration format>>*.
|
|
177
177
|
[[config-capture-body]]
|
178
178
|
==== `capture_body`
|
179
179
|
|============
|
180
|
-
| Environment | `Config` key | Default
|
181
|
-
| `ELASTIC_APM_CAPTURE_BODY` | `capture_body` | `
|
180
|
+
| Environment | `Config` key | Default | Example |
|
181
|
+
| `ELASTIC_APM_CAPTURE_BODY` | `capture_body` | `"off"` | `"all"`
|
182
182
|
|============
|
183
183
|
|
184
|
-
|
184
|
+
For transactions that are HTTP requests,
|
185
|
+
the Ruby agent can optionally capture the request body (e.g. `POST` variables or JSON data).
|
186
|
+
|
187
|
+
Possible values: `"errors"`, `"transactions"`, `"all"`, `"off"`.
|
188
|
+
|
189
|
+
If the request has a body and this setting is disabled, the body will be shown as `[SKIPPED]`.
|
190
|
+
|
191
|
+
WARNING: request bodies often contain sensitive values like passwords, credit card numbers etc.
|
192
|
+
We try to strip sensitive looking data from form bodies but don't touch text bodies like JSON.
|
193
|
+
If your service handles data like this, we advise to only enable this feature with care.
|
194
|
+
|
185
195
|
|
186
196
|
[float]
|
187
197
|
[[config-capture-headers]]
|
@@ -442,6 +452,28 @@ This makes sure the agent doesn't block the main thread any more than necessary.
|
|
442
452
|
If you have high load and get warnings about the buffer being full, increasing
|
443
453
|
the worker pool size might help.
|
444
454
|
|
455
|
+
[float]
|
456
|
+
[[config-proxy-address]]
|
457
|
+
==== `proxy_address`
|
458
|
+
|
459
|
+
[options="header"]
|
460
|
+
|============
|
461
|
+
| Environment | `Config` key | Default | Example
|
462
|
+
| N/A | `proxy_address` | `nil` | `"example.com"`
|
463
|
+
|============
|
464
|
+
|
465
|
+
An address to use as a proxy for the HTTP client.
|
466
|
+
|
467
|
+
Options available are:
|
468
|
+
|
469
|
+
- `proxy_address`
|
470
|
+
- `proxy_headers`
|
471
|
+
- `proxy_password`
|
472
|
+
- `proxy_port`
|
473
|
+
- `proxy_username`
|
474
|
+
|
475
|
+
See https://github.com/httprb/http/wiki/Proxy-Support[Http.rb's docs].
|
476
|
+
|
445
477
|
[float]
|
446
478
|
[[config-service-name]]
|
447
479
|
==== `service_name`
|
data/lib/elastic_apm.rb
CHANGED
@@ -285,8 +285,17 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
|
|
285
285
|
#
|
286
286
|
# @param rack_env [Rack::Env] A Rack env
|
287
287
|
# @return [Context] The built context
|
288
|
-
def build_context(
|
289
|
-
|
288
|
+
def build_context(
|
289
|
+
deprecated_env = nil,
|
290
|
+
rack_env: nil,
|
291
|
+
for_type: :transaction
|
292
|
+
)
|
293
|
+
if !rack_env && (rack_env = deprecated_env)
|
294
|
+
warn "[ElasticAPM] [DEPRECATED] `build_context' expects two keyword" \
|
295
|
+
"arguments, `rack_env:' and `for_type:'"
|
296
|
+
end
|
297
|
+
|
298
|
+
agent&.build_context(rack_env: rack_env, for_type: for_type)
|
290
299
|
end
|
291
300
|
|
292
301
|
### Errors
|
@@ -294,18 +303,25 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
|
|
294
303
|
# Report and exception to APM
|
295
304
|
#
|
296
305
|
# @param exception [Exception] The exception
|
306
|
+
# @param context [Context] An optional [Context]
|
297
307
|
# @param handled [Boolean] Whether the exception was rescued
|
298
308
|
# @return [Error] The generated [Error]
|
299
|
-
def report(exception, handled: true)
|
300
|
-
agent&.report(exception, handled: handled)
|
309
|
+
def report(exception, context: nil, handled: true)
|
310
|
+
agent&.report(exception, context: context, handled: handled)
|
301
311
|
end
|
302
312
|
|
303
313
|
# Report a custom string error message to APM
|
304
314
|
#
|
305
315
|
# @param message [String] The message
|
316
|
+
# @param context [Context] An optional [Context]
|
306
317
|
# @return [Error] The generated [Error]
|
307
|
-
def report_message(message, **attrs)
|
308
|
-
agent&.report_message(
|
318
|
+
def report_message(message, context: nil, **attrs)
|
319
|
+
agent&.report_message(
|
320
|
+
message,
|
321
|
+
context: context,
|
322
|
+
backtrace: caller,
|
323
|
+
**attrs
|
324
|
+
)
|
309
325
|
end
|
310
326
|
|
311
327
|
### Context
|
data/lib/elastic_apm/agent.rb
CHANGED
@@ -169,25 +169,27 @@ module ElasticAPM
|
|
169
169
|
instrumenter.set_user(user)
|
170
170
|
end
|
171
171
|
|
172
|
-
def build_context(rack_env)
|
173
|
-
@context_builder.build(rack_env)
|
172
|
+
def build_context(rack_env:, for_type:)
|
173
|
+
@context_builder.build(rack_env: rack_env, for_type: for_type)
|
174
174
|
end
|
175
175
|
|
176
176
|
# errors
|
177
177
|
|
178
|
-
def report(exception, handled: true)
|
178
|
+
def report(exception, context: nil, handled: true)
|
179
179
|
return if config.filter_exception_types.include?(exception.class.to_s)
|
180
180
|
|
181
181
|
error = @error_builder.build_exception(
|
182
182
|
exception,
|
183
|
+
context: context,
|
183
184
|
handled: handled
|
184
185
|
)
|
185
186
|
enqueue error
|
186
187
|
end
|
187
188
|
|
188
|
-
def report_message(message, backtrace: nil, **attrs)
|
189
|
+
def report_message(message, context: nil, backtrace: nil, **attrs)
|
189
190
|
error = @error_builder.build_log(
|
190
191
|
message,
|
192
|
+
context: context,
|
191
193
|
backtrace: backtrace,
|
192
194
|
**attrs
|
193
195
|
)
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -23,7 +23,7 @@ module ElasticAPM
|
|
23
23
|
api_buffer_size: 256,
|
24
24
|
api_request_size: '750kb',
|
25
25
|
api_request_time: '10s',
|
26
|
-
capture_body:
|
26
|
+
capture_body: 'off',
|
27
27
|
capture_headers: true,
|
28
28
|
capture_env: true,
|
29
29
|
current_user_email_method: :email,
|
@@ -64,7 +64,7 @@ module ElasticAPM
|
|
64
64
|
'ELASTIC_APM_API_BUFFER_SIZE' => [:int, 'api_buffer_size'],
|
65
65
|
'ELASTIC_APM_API_REQUEST_SIZE' => [:int, 'api_request_size'],
|
66
66
|
'ELASTIC_APM_API_REQUEST_TIME' => 'api_request_time',
|
67
|
-
'ELASTIC_APM_CAPTURE_BODY' =>
|
67
|
+
'ELASTIC_APM_CAPTURE_BODY' => 'capture_body',
|
68
68
|
'ELASTIC_APM_CAPTURE_HEADERS' => [:bool, 'capture_headers'],
|
69
69
|
'ELASTIC_APM_CAPTURE_ENV' => [:bool, 'capture_env'],
|
70
70
|
'ELASTIC_APM_CUSTOM_KEY_FILTERS' => [:list, 'custom_key_filters'],
|
@@ -137,9 +137,8 @@ module ElasticAPM
|
|
137
137
|
attr_accessor :api_buffer_size
|
138
138
|
attr_accessor :api_request_size
|
139
139
|
attr_accessor :api_request_time
|
140
|
-
attr_accessor :capture_body
|
141
|
-
attr_accessor :capture_headers
|
142
140
|
attr_accessor :capture_env
|
141
|
+
attr_accessor :capture_headers
|
143
142
|
attr_accessor :current_user_email_method
|
144
143
|
attr_accessor :current_user_id_method
|
145
144
|
attr_accessor :current_user_method
|
@@ -160,6 +159,11 @@ module ElasticAPM
|
|
160
159
|
attr_accessor :logger
|
161
160
|
attr_accessor :metrics_interval
|
162
161
|
attr_accessor :pool_size
|
162
|
+
attr_accessor :proxy_address
|
163
|
+
attr_accessor :proxy_headers
|
164
|
+
attr_accessor :proxy_password
|
165
|
+
attr_accessor :proxy_port
|
166
|
+
attr_accessor :proxy_username
|
163
167
|
attr_accessor :server_ca_cert
|
164
168
|
attr_accessor :service_name
|
165
169
|
attr_accessor :service_version
|
@@ -171,11 +175,14 @@ module ElasticAPM
|
|
171
175
|
attr_accessor :transaction_sample_rate
|
172
176
|
attr_accessor :verify_server_cert
|
173
177
|
|
178
|
+
attr_reader :capture_body
|
174
179
|
attr_reader :custom_key_filters
|
175
180
|
attr_reader :ignore_url_patterns
|
176
181
|
attr_reader :span_frames_min_duration
|
177
182
|
attr_reader :span_frames_min_duration_us
|
178
183
|
|
184
|
+
attr_writer :alert_logger
|
185
|
+
|
179
186
|
attr_accessor :view_paths
|
180
187
|
attr_accessor :root_path
|
181
188
|
|
@@ -296,6 +303,31 @@ module ElasticAPM
|
|
296
303
|
metrics_interval != 0
|
297
304
|
end
|
298
305
|
|
306
|
+
# rubocop:disable Metrics/MethodLength
|
307
|
+
def capture_body=(value)
|
308
|
+
if value =~ /(all|transactions|errors|off)/
|
309
|
+
@capture_body = value
|
310
|
+
return
|
311
|
+
end
|
312
|
+
|
313
|
+
case value
|
314
|
+
when true
|
315
|
+
alert_logger.warn "Boolean value for option `capture_body' has " \
|
316
|
+
"been deprecated. Setting to 'all'"
|
317
|
+
@capture_body = 'all'
|
318
|
+
when false
|
319
|
+
alert_logger.warn "Boolean value for option `capture_body' has " \
|
320
|
+
"been deprecated. Setting to 'off'"
|
321
|
+
@capture_body = 'off'
|
322
|
+
else
|
323
|
+
default = DEFAULTS[:capture_body]
|
324
|
+
alert_logger.warn "Unknown value `#{value}' for option "\
|
325
|
+
"`capture_body'. Defaulting to `#{default}'"
|
326
|
+
@capture_body = default
|
327
|
+
end
|
328
|
+
end
|
329
|
+
# rubocop:enable Metrics/MethodLength
|
330
|
+
|
299
331
|
private
|
300
332
|
|
301
333
|
def assign(options)
|
@@ -376,7 +408,7 @@ module ElasticAPM
|
|
376
408
|
end
|
377
409
|
|
378
410
|
def format_name(str)
|
379
|
-
str.gsub('::', '_')
|
411
|
+
str && str.gsub('::', '_')
|
380
412
|
end
|
381
413
|
|
382
414
|
def normalize_durations
|
data/lib/elastic_apm/context.rb
CHANGED
@@ -9,13 +9,25 @@ require 'elastic_apm/context/user'
|
|
9
9
|
module ElasticAPM
|
10
10
|
# @api private
|
11
11
|
class Context
|
12
|
-
attr_accessor :request, :response, :user
|
13
|
-
attr_reader :custom, :tags
|
14
|
-
|
15
12
|
def initialize(custom: {}, tags: {}, user: nil)
|
16
13
|
@custom = custom
|
17
14
|
@tags = tags
|
18
15
|
@user = user || User.new
|
19
16
|
end
|
17
|
+
|
18
|
+
attr_accessor :request
|
19
|
+
attr_accessor :response
|
20
|
+
attr_accessor :user
|
21
|
+
attr_reader :custom
|
22
|
+
attr_reader :tags
|
23
|
+
|
24
|
+
def empty?
|
25
|
+
return false if tags.any?
|
26
|
+
return false if custom.any?
|
27
|
+
return false if user.any?
|
28
|
+
return false if request || response
|
29
|
+
|
30
|
+
true
|
31
|
+
end
|
20
32
|
end
|
21
33
|
end
|
@@ -12,16 +12,16 @@ module ElasticAPM
|
|
12
12
|
|
13
13
|
attr_reader :config
|
14
14
|
|
15
|
-
def build(rack_env)
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
def build(rack_env:, for_type:)
|
16
|
+
Context.new.tap do |context|
|
17
|
+
apply_to_request(context, rack_env: rack_env, for_type: for_type)
|
18
|
+
end
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
23
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
24
|
-
def apply_to_request(context, rack_env)
|
24
|
+
def apply_to_request(context, rack_env:, for_type:)
|
25
25
|
req = rails_req?(rack_env) ? rack_env : Rack::Request.new(rack_env)
|
26
26
|
|
27
27
|
context.request = Context::Request.new unless context.request
|
@@ -32,7 +32,7 @@ module ElasticAPM
|
|
32
32
|
request.method = req.request_method
|
33
33
|
request.url = Context::Request::Url.new(req)
|
34
34
|
|
35
|
-
request.body =
|
35
|
+
request.body = should_capture_body?(for_type) ? get_body(req) : SKIPPED
|
36
36
|
|
37
37
|
headers, env = get_headers_and_env(rack_env)
|
38
38
|
request.headers = headers if config.capture_headers?
|
@@ -42,12 +42,20 @@ module ElasticAPM
|
|
42
42
|
end
|
43
43
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
44
44
|
|
45
|
+
def should_capture_body?(for_type)
|
46
|
+
option = config.capture_body
|
47
|
+
|
48
|
+
return true if option == 'all'
|
49
|
+
return true if option == 'transactions' && for_type == :transaction
|
50
|
+
return true if option == 'errors' && for_type == :error
|
51
|
+
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
45
55
|
def get_body(req)
|
46
56
|
case req.media_type
|
47
|
-
when 'application/x-www-form-urlencoded'
|
48
|
-
req.POST
|
49
|
-
when 'multipart/form-data'
|
50
|
-
req.POST
|
57
|
+
when 'application/x-www-form-urlencoded', 'multipart/form-data'
|
58
|
+
req.POST.dup
|
51
59
|
else
|
52
60
|
body = req.body.read
|
53
61
|
req.body.rewind
|
@@ -56,8 +64,7 @@ module ElasticAPM
|
|
56
64
|
end
|
57
65
|
|
58
66
|
def rails_req?(env)
|
59
|
-
defined?(ActionDispatch::Request) &&
|
60
|
-
env.is_a?(ActionDispatch::Request)
|
67
|
+
defined?(ActionDispatch::Request) && env.is_a?(ActionDispatch::Request)
|
61
68
|
end
|
62
69
|
|
63
70
|
def get_headers_and_env(rack_env)
|
data/lib/elastic_apm/error.rb
CHANGED
@@ -8,17 +8,11 @@ require 'elastic_apm/error/log'
|
|
8
8
|
module ElasticAPM
|
9
9
|
# @api private
|
10
10
|
class Error
|
11
|
-
def initialize(culprit: nil)
|
11
|
+
def initialize(culprit: nil, context: nil)
|
12
12
|
@id = SecureRandom.hex(16)
|
13
|
-
@trace_id = nil
|
14
13
|
@culprit = culprit
|
15
|
-
|
16
14
|
@timestamp = Util.micros
|
17
|
-
@context =
|
18
|
-
|
19
|
-
@transaction_id = nil
|
20
|
-
@transaction = nil
|
21
|
-
@parent_id = nil
|
15
|
+
@context = context
|
22
16
|
end
|
23
17
|
|
24
18
|
attr_accessor :id, :culprit, :exception, :log, :transaction_id,
|
@@ -7,37 +7,28 @@ module ElasticAPM
|
|
7
7
|
@agent = agent
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
error = Error.new
|
10
|
+
def build_exception(exception, context: nil, handled: true)
|
11
|
+
error = Error.new context: context || Context.new
|
13
12
|
error.exception = Error::Exception.new(exception, handled: handled)
|
14
13
|
|
15
14
|
if exception.backtrace
|
16
15
|
add_stacktrace error, :exception, exception.backtrace
|
17
16
|
end
|
18
17
|
|
19
|
-
add_current_transaction_fields error
|
20
|
-
|
21
|
-
if (transaction = ElasticAPM.current_transaction)
|
22
|
-
error.context = transaction.context.dup
|
23
|
-
error.trace_id = transaction.trace_id
|
24
|
-
error.transaction_id = transaction.id
|
25
|
-
error.parent_id = ElasticAPM.current_span&.id || transaction.id
|
26
|
-
end
|
18
|
+
add_current_transaction_fields error, ElasticAPM.current_transaction
|
27
19
|
|
28
20
|
error
|
29
21
|
end
|
30
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
31
22
|
|
32
|
-
def build_log(message, backtrace: nil, **attrs)
|
33
|
-
error = Error.new
|
23
|
+
def build_log(message, context: nil, backtrace: nil, **attrs)
|
24
|
+
error = Error.new context: context || Context.new
|
34
25
|
error.log = Error::Log.new(message, **attrs)
|
35
26
|
|
36
27
|
if backtrace
|
37
28
|
add_stacktrace error, :log, backtrace
|
38
29
|
end
|
39
30
|
|
40
|
-
add_current_transaction_fields error
|
31
|
+
add_current_transaction_fields error, ElasticAPM.current_transaction
|
41
32
|
|
42
33
|
error
|
43
34
|
end
|
@@ -59,10 +50,20 @@ module ElasticAPM
|
|
59
50
|
error.culprit = stacktrace.frames.first.function
|
60
51
|
end
|
61
52
|
|
62
|
-
|
63
|
-
|
53
|
+
# rubocop:disable Metrics/AbcSize
|
54
|
+
def add_current_transaction_fields(error, transaction)
|
55
|
+
return unless transaction
|
56
|
+
|
64
57
|
error.transaction_id = transaction.id
|
65
58
|
error.transaction = { sampled: transaction.sampled? }
|
59
|
+
error.trace_id = transaction.trace_id
|
60
|
+
error.parent_id = ElasticAPM.current_span&.id || transaction.id
|
61
|
+
|
62
|
+
return unless transaction.context
|
63
|
+
|
64
|
+
Util.reverse_merge!(error.context.tags, transaction.context.tags)
|
65
|
+
Util.reverse_merge!(error.context.custom, transaction.context.custom)
|
66
66
|
end
|
67
|
+
# rubocop:enable Metrics/AbcSize
|
67
68
|
end
|
68
69
|
end
|
@@ -198,6 +198,8 @@ module ElasticAPM
|
|
198
198
|
attr_reader :total, :available, :page_size
|
199
199
|
|
200
200
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
201
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
202
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
201
203
|
def read!
|
202
204
|
# rubocop:disable Style/RescueModifier
|
203
205
|
@page_size = `getconf PAGESIZE`.chomp.to_i rescue 4096
|
@@ -211,16 +213,25 @@ module ElasticAPM
|
|
211
213
|
hsh[:total] = line.split[1].to_i * 1024
|
212
214
|
elsif line.start_with?('MemAvailable:')
|
213
215
|
hsh[:available] = line.split[1].to_i * 1024
|
216
|
+
elsif line.start_with?('MemFree:')
|
217
|
+
hsh[:free] = line.split[1].to_i * 1024
|
218
|
+
elsif line.start_with?('Buffers:')
|
219
|
+
hsh[:buffers] = line.split[1].to_i * 1024
|
220
|
+
elsif line.start_with?('Cached:')
|
221
|
+
hsh[:cached] = line.split[1].to_i * 1024
|
214
222
|
end
|
215
223
|
|
216
|
-
break hsh if hsh
|
224
|
+
break hsh if hsh[:total] && hsh[:available]
|
217
225
|
end
|
218
226
|
|
219
227
|
@total = info[:total]
|
220
|
-
@available =
|
228
|
+
@available =
|
229
|
+
info[:available] || info[:free] + info[:buffers] + info[:cached]
|
221
230
|
|
222
231
|
self
|
223
232
|
end
|
233
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
234
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
224
235
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
225
236
|
end
|
226
237
|
end
|
@@ -10,7 +10,7 @@ module ElasticAPM
|
|
10
10
|
@app = app
|
11
11
|
end
|
12
12
|
|
13
|
-
# rubocop:disable Metrics/MethodLength
|
13
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
14
14
|
def call(env)
|
15
15
|
begin
|
16
16
|
if running? && !path_ignored?(env)
|
@@ -21,12 +21,13 @@ module ElasticAPM
|
|
21
21
|
rescue InternalError
|
22
22
|
raise # Don't report ElasticAPM errors
|
23
23
|
rescue ::Exception => e
|
24
|
-
ElasticAPM.
|
24
|
+
context = ElasticAPM.build_context(rack_env: env, for_type: :error)
|
25
|
+
ElasticAPM.report(e, context: context, handled: false)
|
25
26
|
raise
|
26
27
|
ensure
|
27
28
|
if resp && transaction
|
28
29
|
status, headers, _body = resp
|
29
|
-
transaction.add_response(status, headers: headers)
|
30
|
+
transaction.add_response(status, headers: headers.dup)
|
30
31
|
end
|
31
32
|
|
32
33
|
ElasticAPM.end_transaction http_result(status)
|
@@ -34,7 +35,7 @@ module ElasticAPM
|
|
34
35
|
|
35
36
|
resp
|
36
37
|
end
|
37
|
-
# rubocop:enable Metrics/MethodLength
|
38
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
38
39
|
|
39
40
|
private
|
40
41
|
|
@@ -49,8 +50,10 @@ module ElasticAPM
|
|
49
50
|
end
|
50
51
|
|
51
52
|
def start_transaction(env)
|
53
|
+
context = ElasticAPM.build_context(rack_env: env, for_type: :transaction)
|
54
|
+
|
52
55
|
ElasticAPM.start_transaction 'Rack', 'request',
|
53
|
-
context:
|
56
|
+
context: context,
|
54
57
|
trace_context: trace_context(env)
|
55
58
|
end
|
56
59
|
|
data/lib/elastic_apm/railtie.rb
CHANGED
@@ -17,22 +17,46 @@ module ElasticAPM
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
if agent
|
24
|
-
agent.instrumenter.subscriber = ElasticAPM::Subscriber.new(agent)
|
25
|
-
|
26
|
-
app.middleware.insert 0, Middleware
|
27
|
-
end
|
28
|
-
rescue StandardError => e
|
29
|
-
config.alert_logger.error format('Failed to start: %s', e.message)
|
30
|
-
config.alert_logger.debug "Backtrace:\n" + e.backtrace.join("\n")
|
20
|
+
if start(config)
|
21
|
+
app.middleware.insert 0, Middleware
|
31
22
|
end
|
32
23
|
end
|
33
24
|
|
34
25
|
config.after_initialize do
|
35
26
|
require 'elastic_apm/spies/action_dispatch'
|
36
27
|
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
32
|
+
def start(config)
|
33
|
+
if (reason = should_skip?(config))
|
34
|
+
config.alert_logger.info "Skipping because: #{reason}. " \
|
35
|
+
"Start manually with `ElasticAPM.start'"
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
ElasticAPM.start(config).tap do |agent|
|
40
|
+
attach_subscriber(agent)
|
41
|
+
end
|
42
|
+
rescue StandardError => e
|
43
|
+
config.alert_logger.error format('Failed to start: %s', e.message)
|
44
|
+
config.alert_logger.debug "Backtrace:\n" + e.backtrace.join("\n")
|
45
|
+
end
|
46
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
47
|
+
|
48
|
+
def should_skip?(_config)
|
49
|
+
if Rails.const_defined? :Console
|
50
|
+
return 'Rails console'
|
51
|
+
end
|
52
|
+
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def attach_subscriber(agent)
|
57
|
+
return unless agent
|
58
|
+
|
59
|
+
agent.instrumenter.subscriber = ElasticAPM::Subscriber.new(agent)
|
60
|
+
end
|
37
61
|
end
|
38
62
|
end
|
@@ -10,7 +10,9 @@ module ElasticAPM
|
|
10
10
|
alias render_exception_without_apm render_exception
|
11
11
|
|
12
12
|
def render_exception(env, exception)
|
13
|
-
ElasticAPM.
|
13
|
+
context = ElasticAPM.build_context(rack_env: env, for_type: :error)
|
14
|
+
ElasticAPM.report(exception, context: context, handled: false)
|
15
|
+
|
14
16
|
render_exception_without_apm env, exception
|
15
17
|
end
|
16
18
|
end
|
@@ -6,6 +6,8 @@ module ElasticAPM
|
|
6
6
|
# @api private
|
7
7
|
class FaradaySpy
|
8
8
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
9
|
+
# rubocop:disable Metrics/BlockLength, Metrics/PerceivedComplexity
|
10
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
9
11
|
def install
|
10
12
|
::Faraday::Connection.class_eval do
|
11
13
|
alias run_request_without_apm run_request
|
@@ -43,6 +45,8 @@ module ElasticAPM
|
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
48
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
49
|
+
# rubocop:enable Metrics/BlockLength, Metrics/PerceivedComplexity
|
46
50
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
47
51
|
end
|
48
52
|
|
@@ -28,7 +28,7 @@ module ElasticAPM
|
|
28
28
|
}.freeze
|
29
29
|
GZIP_HEADERS = HEADERS.merge('Content-Encoding' => 'gzip').freeze
|
30
30
|
|
31
|
-
# rubocop:disable Metrics/MethodLength
|
31
|
+
# rubocop:disable Metrics/MethodLength
|
32
32
|
def initialize(config, metadata)
|
33
33
|
@config = config
|
34
34
|
@metadata = metadata.to_json
|
@@ -42,16 +42,36 @@ module ElasticAPM
|
|
42
42
|
headers['Authorization'] = "Bearer #{token}"
|
43
43
|
end
|
44
44
|
|
45
|
-
if config.use_ssl? && config.server_ca_cert
|
46
|
-
@ssl_context = OpenSSL::SSL::SSLContext.new
|
47
|
-
@ssl_context.ca_file = config.server_ca_cert
|
48
|
-
end
|
49
|
-
|
50
45
|
@client = HTTP.headers(headers).persistent(@url)
|
51
46
|
|
47
|
+
configure_proxy
|
48
|
+
configure_ssl
|
49
|
+
|
52
50
|
@mutex = Mutex.new
|
53
51
|
end
|
54
|
-
# rubocop:enable Metrics/MethodLength
|
52
|
+
# rubocop:enable Metrics/MethodLength
|
53
|
+
|
54
|
+
def configure_proxy
|
55
|
+
unless @config.proxy_address && @config.proxy_port
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
@client = @client.via(
|
60
|
+
@config.proxy_address,
|
61
|
+
@config.proxy_port,
|
62
|
+
@config.proxy_username,
|
63
|
+
@config.proxy_password,
|
64
|
+
@config.proxy_headers
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def configure_ssl
|
69
|
+
return unless @config.use_ssl? && @config.server_ca_cert
|
70
|
+
|
71
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new.tap do |context|
|
72
|
+
context.ca_file = @config.server_ca_cert
|
73
|
+
end
|
74
|
+
end
|
55
75
|
|
56
76
|
def write(str)
|
57
77
|
return if @config.disable_send
|
@@ -9,7 +9,7 @@ module ElasticAPM
|
|
9
9
|
@context_serializer ||= ContextSerializer.new(config)
|
10
10
|
end
|
11
11
|
|
12
|
-
# rubocop:disable Metrics/MethodLength
|
12
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
13
13
|
def build(error)
|
14
14
|
base = {
|
15
15
|
id: error.id,
|
@@ -19,10 +19,13 @@ module ElasticAPM
|
|
19
19
|
parent_id: error.parent_id,
|
20
20
|
|
21
21
|
culprit: error.culprit,
|
22
|
-
timestamp: error.timestamp
|
23
|
-
context: context_serializer.build(error.context)
|
22
|
+
timestamp: error.timestamp
|
24
23
|
}
|
25
24
|
|
25
|
+
if (context = context_serializer.build(error.context))
|
26
|
+
base[:context] = context
|
27
|
+
end
|
28
|
+
|
26
29
|
if (exception = error.exception)
|
27
30
|
base[:exception] = build_exception exception
|
28
31
|
end
|
@@ -33,7 +36,7 @@ module ElasticAPM
|
|
33
36
|
|
34
37
|
{ error: base }
|
35
38
|
end
|
36
|
-
# rubocop:enable Metrics/MethodLength
|
39
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
37
40
|
|
38
41
|
private
|
39
42
|
|
data/lib/elastic_apm/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic-apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.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: 2019-03-
|
11
|
+
date: 2019-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -182,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
182
|
- !ruby/object:Gem::Version
|
183
183
|
version: '0'
|
184
184
|
requirements: []
|
185
|
-
rubygems_version: 3.0.
|
185
|
+
rubygems_version: 3.0.3
|
186
186
|
signing_key:
|
187
187
|
specification_version: 4
|
188
188
|
summary: The official Elastic APM agent for Ruby
|