elastic-apm 2.0.1 → 2.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +9 -9
- data/docs/advanced.asciidoc +8 -0
- data/docs/api.asciidoc +1 -1
- data/docs/configuration.asciidoc +1 -1
- data/docs/context.asciidoc +0 -1
- data/docs/index.asciidoc +7 -25
- data/docs/introduction.asciidoc +33 -0
- data/lib/elastic_apm/agent.rb +0 -1
- data/lib/elastic_apm/config.rb +35 -7
- data/lib/elastic_apm/context.rb +0 -2
- data/lib/elastic_apm/context/request.rb +0 -2
- data/lib/elastic_apm/context/request/socket.rb +0 -2
- data/lib/elastic_apm/context/request/url.rb +0 -2
- data/lib/elastic_apm/context/response.rb +0 -2
- data/lib/elastic_apm/context/user.rb +1 -3
- data/lib/elastic_apm/context_builder.rb +2 -2
- data/lib/elastic_apm/metadata.rb +11 -13
- data/lib/elastic_apm/metadata/process_info.rb +5 -13
- data/lib/elastic_apm/metadata/service_info.rb +38 -33
- data/lib/elastic_apm/metadata/system_info.rb +7 -13
- data/lib/elastic_apm/railtie.rb +2 -2
- data/lib/elastic_apm/span/context.rb +0 -6
- data/lib/elastic_apm/spies/faraday.rb +41 -0
- data/lib/elastic_apm/spies/net_http.rb +25 -0
- data/lib/elastic_apm/stacktrace/frame.rb +2 -0
- data/lib/elastic_apm/transport/base.rb +1 -2
- data/lib/elastic_apm/transport/connection.rb +4 -5
- data/lib/elastic_apm/transport/serializers.rb +22 -3
- data/lib/elastic_apm/transport/serializers/context_serializer.rb +69 -0
- data/lib/elastic_apm/transport/serializers/error_serializer.rb +11 -7
- data/lib/elastic_apm/transport/serializers/metadata_serializer.rb +64 -0
- data/lib/elastic_apm/transport/serializers/span_serializer.rb +49 -5
- data/lib/elastic_apm/transport/serializers/transaction_serializer.rb +10 -6
- data/lib/elastic_apm/transport/worker.rb +5 -3
- data/lib/elastic_apm/util.rb +7 -0
- data/lib/elastic_apm/util/prefixed_logger.rb +18 -0
- data/lib/elastic_apm/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df3dedd32ff6829fff4db353e0f6990d378d57313112cba444f717cb958565bd
|
|
4
|
+
data.tar.gz: 9e822ce49bc71ebf13ab70e0bf67e8c156a19f0f5c68e5dcca895fcebbf64edb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9cd54124d6b4278d5cef85347eacc071a1a9d6511dc31c30fa551d9e9827d5288e1f91fad7c89cec32b4642897f13f92c16ed8a61b494f9e3b9bb4a60c8eacfc
|
|
7
|
+
data.tar.gz: ff0c2bff7f2d9f5d1a920a54a9dd120938c8a91e02cc024e3ecb9e420a50673f75b8ec2535643b794f34319ac2f2eb005a9a907dcc0e1b79869178fc3278305c
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ 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.1.0 (2018-12-04)
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Support for Faraday ([#249](https://github.com/elastic/apm-agent-ruby/pull/249))
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Truncate keyword fields to 1024 chars ([#240](https://github.com/elastic/apm-agent-ruby/pull/240))
|
|
16
|
+
- Lazy boot worker threads on first event. Fixes apps using Puma's `preload_app!` ([#239](https://github.com/elastic/apm-agent-ruby/pull/239))
|
|
17
|
+
- Fix missing `disable_send` implementation ([#257](https://github.com/elastic/apm-agent-ruby/pull/257))
|
|
18
|
+
- Add warnings for invalid config options ([#254](https://github.com/elastic/apm-agent-ruby/pull/254))
|
|
19
|
+
|
|
7
20
|
## 2.0.1 (2018-11-15)
|
|
8
21
|
|
|
9
22
|
### Fixed
|
data/README.md
CHANGED
|
@@ -11,21 +11,21 @@ The official Rubygem for [Elastic][] [APM][].
|
|
|
11
11
|
|
|
12
12
|
## Documentation
|
|
13
13
|
|
|
14
|
-
[Full documentation at Elasti.co](https://www.elastic.co/guide/en/apm/agent/ruby/index.html).
|
|
14
|
+
[Full documentation at Elasti.co](https://www.elastic.co/guide/en/apm/agent/ruby/2.x/index.html).
|
|
15
15
|
|
|
16
16
|
<ul>
|
|
17
|
-
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/
|
|
18
|
-
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/
|
|
19
|
-
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/
|
|
20
|
-
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/
|
|
17
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/introduction.html">Introduction</a></li>
|
|
18
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/getting-started-rails.html">Getting started with Rails</a></li>
|
|
19
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/getting-started-rack.html">Getting started with Rack</a></li>
|
|
20
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/configuration.html">Configuration</a></li>
|
|
21
21
|
<li>
|
|
22
|
-
<a href="https://www.elastic.co/guide/en/apm/agent/ruby/
|
|
22
|
+
<a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/advanced.html">Advanced Topics</a>
|
|
23
23
|
<ul>
|
|
24
|
-
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/
|
|
25
|
-
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/1.x/spies.html">Spies — instrumented libraries</a></li>
|
|
24
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/custom-instrumentation.html">Custom instrumentation</a></li>
|
|
26
25
|
</ul>
|
|
27
26
|
</li>
|
|
28
|
-
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/
|
|
27
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/supported-technologies.html">Supported Technologies</a></li>
|
|
28
|
+
<li><a href="https://www.elastic.co/guide/en/apm/agent/ruby/2.x/api.html">Public API</a></li>
|
|
29
29
|
</ul>
|
|
30
30
|
|
|
31
31
|
---
|
data/docs/api.asciidoc
CHANGED
|
@@ -98,7 +98,7 @@ Wrap a block in a Transaction, starting and ending around the block
|
|
|
98
98
|
|
|
99
99
|
[source,ruby]
|
|
100
100
|
----
|
|
101
|
-
ElasticAPM.
|
|
101
|
+
ElasticAPM.with_transaction 'Do things' do |transaction|
|
|
102
102
|
do_work # ...
|
|
103
103
|
|
|
104
104
|
transaction.result = 'success'
|
data/docs/configuration.asciidoc
CHANGED
|
@@ -319,7 +319,7 @@ Elastic APM can instrument your Rake tasks but given that they are used for a mu
|
|
|
319
319
|
[options="header"]
|
|
320
320
|
|============
|
|
321
321
|
| Environment | `Config` key | Default
|
|
322
|
-
| `ELASTIC_APM_LOG_LEVEL` | `log_level` | `Logger::
|
|
322
|
+
| `ELASTIC_APM_LOG_LEVEL` | `log_level` | `Logger::INFO # => 1`
|
|
323
323
|
|============
|
|
324
324
|
|
|
325
325
|
By default Elastic APM logs to `stdout` or uses `Rails.log` when used with Rails.
|
data/docs/context.asciidoc
CHANGED
data/docs/index.asciidoc
CHANGED
|
@@ -2,42 +2,24 @@
|
|
|
2
2
|
include::{asciidoc-dir}/../../shared/attributes.asciidoc[]
|
|
3
3
|
|
|
4
4
|
ifdef::env-github[]
|
|
5
|
-
NOTE: For the best reading experience,
|
|
5
|
+
NOTE: For the best reading experience,
|
|
6
|
+
please view this documentation at
|
|
6
7
|
https://www.elastic.co/guide/en/apm/agent/ruby[elastic.co]
|
|
7
8
|
endif::[]
|
|
8
9
|
|
|
9
10
|
= APM Ruby Agent Reference
|
|
10
11
|
|
|
11
|
-
[
|
|
12
|
-
== Introduction
|
|
13
|
-
|
|
14
|
-
The Elastic APM Ruby Agent sends performance metrics and error logs to an
|
|
15
|
-
Elastic APM Server.
|
|
16
|
-
|
|
17
|
-
It has built-in support for <<getting-started-rails,Ruby on Rails>> and other
|
|
18
|
-
<<getting-started-rack,Rack-compatible>> applications.
|
|
19
|
-
|
|
20
|
-
This agent is one of several components you need to get started collecting APM
|
|
21
|
-
data. See also:
|
|
22
|
-
|
|
23
|
-
* {apm-server-ref}[APM Server]
|
|
24
|
-
|
|
25
|
-
[[framework-support]]
|
|
26
|
-
The Elastic APM Ruby Agent officially supports Ruby on Rails versions 4.x on
|
|
27
|
-
onwards, see <<getting-started-rails,Getting started with Ruby on Rails>>.
|
|
28
|
-
|
|
29
|
-
For Sinatra and other Rack compatible frameworks, see
|
|
30
|
-
<<getting-started-rack,Getting started with Rack>>.
|
|
12
|
+
include::./introduction.asciidoc[]
|
|
31
13
|
|
|
32
14
|
include::./getting-started-rails.asciidoc[]
|
|
15
|
+
|
|
33
16
|
include::./getting-started-rack.asciidoc[]
|
|
17
|
+
|
|
34
18
|
include::./configuration.asciidoc[]
|
|
35
19
|
|
|
36
|
-
[
|
|
37
|
-
== Advanced Topics
|
|
38
|
-
include::./context.asciidoc[]
|
|
39
|
-
include::./custom-instrumentation.asciidoc[]
|
|
20
|
+
include::./advanced.asciidoc[]
|
|
40
21
|
|
|
41
22
|
include::./supported-technologies.asciidoc[]
|
|
23
|
+
|
|
42
24
|
include::./api.asciidoc[]
|
|
43
25
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[[introduction]]
|
|
2
|
+
|
|
3
|
+
ifdef::env-github[]
|
|
4
|
+
NOTE: For the best reading experience,
|
|
5
|
+
please view this documentation at
|
|
6
|
+
https://www.elastic.co/guide/en/apm/agent/ruby/current/introduction.html[elastic.co]
|
|
7
|
+
endif::[]
|
|
8
|
+
|
|
9
|
+
== Introduction
|
|
10
|
+
|
|
11
|
+
Welcome to the APM Ruby Agent documentation.
|
|
12
|
+
|
|
13
|
+
The Elastic APM Ruby Agent sends performance metrics and error logs to an
|
|
14
|
+
Elastic APM Server.
|
|
15
|
+
It has built-in support for <<getting-started-rails,Ruby on Rails>> and other
|
|
16
|
+
<<getting-started-rack,Rack-compatible>> applications.
|
|
17
|
+
|
|
18
|
+
[float]
|
|
19
|
+
[[additional-components]]
|
|
20
|
+
=== Additional Components
|
|
21
|
+
|
|
22
|
+
APM Agents work in conjunction with the {apm-server-ref}/index.html[APM Server], {ref}/index.html[Elasticsearch], and {kibana-ref}/index.html[Kibana].
|
|
23
|
+
Please view the {apm-get-started-ref}/index.html[APM Overview] for details on how these components work together.
|
|
24
|
+
|
|
25
|
+
[float]
|
|
26
|
+
[[framework-support]]
|
|
27
|
+
=== Framework Support
|
|
28
|
+
|
|
29
|
+
The Elastic APM Ruby Agent officially supports Ruby on Rails versions 4.x on
|
|
30
|
+
onwards, see <<getting-started-rails,Getting started with Ruby on Rails>>.
|
|
31
|
+
|
|
32
|
+
For Sinatra and other Rack compatible frameworks, see
|
|
33
|
+
<<getting-started-rack,Getting started with Rack>>.
|
data/lib/elastic_apm/agent.rb
CHANGED
data/lib/elastic_apm/config.rb
CHANGED
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
require 'logger'
|
|
4
4
|
require 'yaml'
|
|
5
5
|
|
|
6
|
+
require 'elastic_apm/util/prefixed_logger'
|
|
6
7
|
require 'elastic_apm/config/duration'
|
|
7
8
|
require 'elastic_apm/config/size'
|
|
8
9
|
|
|
9
10
|
module ElasticAPM
|
|
11
|
+
class ConfigError < StandardError; end
|
|
12
|
+
|
|
10
13
|
# rubocop:disable Metrics/ClassLength
|
|
11
14
|
# @api private
|
|
12
15
|
class Config
|
|
@@ -144,10 +147,10 @@ module ElasticAPM
|
|
|
144
147
|
attr_accessor :transaction_sample_rate
|
|
145
148
|
attr_accessor :verify_server_cert
|
|
146
149
|
|
|
147
|
-
attr_reader
|
|
148
|
-
attr_reader
|
|
149
|
-
attr_reader
|
|
150
|
-
attr_reader
|
|
150
|
+
attr_reader :custom_key_filters
|
|
151
|
+
attr_reader :ignore_url_patterns
|
|
152
|
+
attr_reader :span_frames_min_duration
|
|
153
|
+
attr_reader :span_frames_min_duration_us
|
|
151
154
|
|
|
152
155
|
attr_accessor :view_paths
|
|
153
156
|
attr_accessor :root_path
|
|
@@ -157,6 +160,10 @@ module ElasticAPM
|
|
|
157
160
|
alias :instrument? :instrument
|
|
158
161
|
alias :verify_server_cert? :verify_server_cert
|
|
159
162
|
|
|
163
|
+
def alert_logger
|
|
164
|
+
@alert_logger ||= PrefixedLogger.new($stdout, prefix: Logging::PREFIX)
|
|
165
|
+
end
|
|
166
|
+
|
|
160
167
|
def app=(app)
|
|
161
168
|
case app_type?(app)
|
|
162
169
|
when :sinatra
|
|
@@ -198,6 +205,7 @@ module ElasticAPM
|
|
|
198
205
|
action_dispatch
|
|
199
206
|
delayed_job
|
|
200
207
|
elasticsearch
|
|
208
|
+
faraday
|
|
201
209
|
http
|
|
202
210
|
json
|
|
203
211
|
mongo
|
|
@@ -234,12 +242,22 @@ module ElasticAPM
|
|
|
234
242
|
].freeze
|
|
235
243
|
|
|
236
244
|
def respond_to_missing?(name)
|
|
237
|
-
DEPRECATED_OPTIONS.include? name
|
|
245
|
+
return true if DEPRECATED_OPTIONS.include? name
|
|
246
|
+
return true if name.to_s.end_with?('=')
|
|
247
|
+
false
|
|
238
248
|
end
|
|
239
249
|
|
|
240
250
|
def method_missing(name, *args)
|
|
241
|
-
|
|
242
|
-
|
|
251
|
+
if DEPRECATED_OPTIONS.include?(name)
|
|
252
|
+
alert_logger.warn "The option `#{name}' has been removed."
|
|
253
|
+
return
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
if name.to_s.end_with?('=')
|
|
257
|
+
raise ConfigError, "No such option `#{name.to_s.delete('=')}'"
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
super
|
|
243
261
|
end
|
|
244
262
|
|
|
245
263
|
private
|
|
@@ -280,11 +298,21 @@ module ElasticAPM
|
|
|
280
298
|
|
|
281
299
|
def set_from_args(options)
|
|
282
300
|
assign(options)
|
|
301
|
+
rescue ConfigError => e
|
|
302
|
+
alert_logger.warn format(
|
|
303
|
+
'Failed to configure from arguments: %s',
|
|
304
|
+
e.message
|
|
305
|
+
)
|
|
283
306
|
end
|
|
284
307
|
|
|
285
308
|
def set_from_config_file
|
|
286
309
|
return unless File.exist?(config_file)
|
|
287
310
|
assign(YAML.load_file(config_file) || {})
|
|
311
|
+
rescue ConfigError => e
|
|
312
|
+
alert_logger.warn format(
|
|
313
|
+
'Failed to configure from config file: %s',
|
|
314
|
+
e.message
|
|
315
|
+
)
|
|
288
316
|
end
|
|
289
317
|
|
|
290
318
|
def set_sinatra(app)
|
data/lib/elastic_apm/context.rb
CHANGED
|
@@ -4,12 +4,10 @@ module ElasticAPM
|
|
|
4
4
|
class Context
|
|
5
5
|
# @api private
|
|
6
6
|
class User
|
|
7
|
-
include NaivelyHashable
|
|
8
|
-
|
|
9
7
|
def initialize(config, record)
|
|
10
8
|
return unless record
|
|
11
9
|
|
|
12
|
-
@id = safe_get(record, config.current_user_id_method)
|
|
10
|
+
@id = safe_get(record, config.current_user_id_method)&.to_s
|
|
13
11
|
@email = safe_get(record, config.current_user_email_method)
|
|
14
12
|
@username = safe_get(record, config.current_user_username_method)
|
|
15
13
|
end
|
|
@@ -21,10 +21,10 @@ module ElasticAPM
|
|
|
21
21
|
context.request = Context::Request.new unless context.request
|
|
22
22
|
request = context.request
|
|
23
23
|
|
|
24
|
-
request.socket = Context::Request::Socket.new(req)
|
|
24
|
+
request.socket = Context::Request::Socket.new(req)
|
|
25
25
|
request.http_version = build_http_version rack_env
|
|
26
26
|
request.method = req.request_method
|
|
27
|
-
request.url = Context::Request::Url.new(req)
|
|
27
|
+
request.url = Context::Request::Url.new(req)
|
|
28
28
|
request.headers, request.env = get_headers_and_env(rack_env)
|
|
29
29
|
request.body = get_body(req)
|
|
30
30
|
|
data/lib/elastic_apm/metadata.rb
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'elastic_apm/metadata/service_info'
|
|
4
|
-
require 'elastic_apm/metadata/system_info'
|
|
5
|
-
require 'elastic_apm/metadata/process_info'
|
|
6
|
-
|
|
7
3
|
module ElasticAPM
|
|
8
4
|
# @api private
|
|
9
|
-
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
process: Metadata::ProcessInfo.build(config),
|
|
15
|
-
system: Metadata::SystemInfo.build(config)
|
|
16
|
-
}
|
|
17
|
-
}.to_json
|
|
5
|
+
class Metadata
|
|
6
|
+
def initialize(config)
|
|
7
|
+
@service = ServiceInfo.new(config)
|
|
8
|
+
@process = ProcessInfo.new(config)
|
|
9
|
+
@system = SystemInfo.new(config)
|
|
18
10
|
end
|
|
11
|
+
|
|
12
|
+
attr_reader :service, :process, :system
|
|
19
13
|
end
|
|
20
14
|
end
|
|
15
|
+
|
|
16
|
+
require 'elastic_apm/metadata/service_info'
|
|
17
|
+
require 'elastic_apm/metadata/system_info'
|
|
18
|
+
require 'elastic_apm/metadata/process_info'
|
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ElasticAPM
|
|
4
|
-
|
|
4
|
+
class Metadata
|
|
5
5
|
# @api private
|
|
6
6
|
class ProcessInfo
|
|
7
7
|
def initialize(config)
|
|
8
8
|
@config = config
|
|
9
|
-
end
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
pid = $PID || Process.pid
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
argv: ARGV,
|
|
16
|
-
pid: pid,
|
|
17
|
-
title: $PROGRAM_NAME
|
|
18
|
-
}
|
|
10
|
+
@argv = ARGV
|
|
11
|
+
@pid = $PID || Process.pid
|
|
12
|
+
@title = $PROGRAM_NAME
|
|
19
13
|
end
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
new(config).build
|
|
23
|
-
end
|
|
15
|
+
attr_reader :argv, :pid, :title
|
|
24
16
|
end
|
|
25
17
|
end
|
|
26
18
|
end
|
|
@@ -1,56 +1,61 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ElasticAPM
|
|
4
|
-
|
|
4
|
+
class Metadata
|
|
5
5
|
# @api private
|
|
6
6
|
class ServiceInfo
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
# @api private
|
|
8
|
+
class Versioned
|
|
9
|
+
def initialize(name: nil, version: nil)
|
|
10
|
+
@name = name
|
|
11
|
+
@version = version
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :name, :version
|
|
9
15
|
end
|
|
16
|
+
class Agent < Versioned; end
|
|
17
|
+
class Framework < Versioned; end
|
|
18
|
+
class Language < Versioned; end
|
|
19
|
+
class Runtime < Versioned; end
|
|
10
20
|
|
|
11
21
|
# rubocop:disable Metrics/MethodLength
|
|
12
|
-
def
|
|
13
|
-
|
|
14
|
-
name: @config.service_name,
|
|
15
|
-
environment: @config.environment,
|
|
16
|
-
agent: {
|
|
17
|
-
name: 'ruby',
|
|
18
|
-
version: VERSION
|
|
19
|
-
},
|
|
20
|
-
framework: nil,
|
|
21
|
-
language: {
|
|
22
|
-
name: 'ruby',
|
|
23
|
-
version: RUBY_VERSION
|
|
24
|
-
},
|
|
25
|
-
runtime: runtime,
|
|
26
|
-
version: @config.service_version || Util.git_sha
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if @config.framework_name
|
|
30
|
-
base[:framework] = {
|
|
31
|
-
name: @config.framework_name,
|
|
32
|
-
version: @config.framework_version
|
|
33
|
-
}
|
|
34
|
-
end
|
|
22
|
+
def initialize(config)
|
|
23
|
+
@config = config
|
|
35
24
|
|
|
36
|
-
|
|
25
|
+
@name = @config.service_name
|
|
26
|
+
@environment = @config.environment
|
|
27
|
+
@agent = Agent.new(name: 'ruby', version: VERSION)
|
|
28
|
+
@framework = Framework.new(
|
|
29
|
+
name: @config.framework_name,
|
|
30
|
+
version: @config.framework_version
|
|
31
|
+
)
|
|
32
|
+
@language = Language.new(name: 'ruby', version: RUBY_VERSION)
|
|
33
|
+
@runtime = lookup_runtime
|
|
34
|
+
@version = @config.service_version || Util.git_sha
|
|
37
35
|
end
|
|
38
36
|
# rubocop:enable Metrics/MethodLength
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
end
|
|
38
|
+
attr_reader :name, :environment, :agent, :framework, :language, :runtime,
|
|
39
|
+
:version
|
|
43
40
|
|
|
44
41
|
private
|
|
45
42
|
|
|
46
|
-
|
|
43
|
+
# rubocop:disable Metrics/MethodLength
|
|
44
|
+
def lookup_runtime
|
|
47
45
|
case RUBY_ENGINE
|
|
48
46
|
when 'ruby'
|
|
49
|
-
|
|
47
|
+
Runtime.new(
|
|
48
|
+
name: RUBY_ENGINE,
|
|
49
|
+
version: RUBY_VERSION || RUBY_ENGINE_VERSION
|
|
50
|
+
)
|
|
50
51
|
when 'jruby'
|
|
51
|
-
|
|
52
|
+
Runtime.new(
|
|
53
|
+
name: RUBY_ENGINE,
|
|
54
|
+
version: JRUBY_VERSION || RUBY_ENGINE_VERSION
|
|
55
|
+
)
|
|
52
56
|
end
|
|
53
57
|
end
|
|
58
|
+
# rubocop:enable Metrics/MethodLength
|
|
54
59
|
end
|
|
55
60
|
end
|
|
56
61
|
end
|
|
@@ -1,29 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ElasticAPM
|
|
4
|
-
|
|
4
|
+
class Metadata
|
|
5
5
|
# @api private
|
|
6
6
|
class SystemInfo
|
|
7
7
|
def initialize(config)
|
|
8
8
|
@config = config
|
|
9
|
-
end
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
architecture: platform.cpu,
|
|
15
|
-
platform: platform.os
|
|
16
|
-
}
|
|
10
|
+
@hostname = @config.hostname || `hostname`.chomp
|
|
11
|
+
@architecture = gem_platform.cpu
|
|
12
|
+
@platform = gem_platform.os
|
|
17
13
|
end
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
new(config).build
|
|
21
|
-
end
|
|
15
|
+
attr_reader :hostname, :architecture, :platform
|
|
22
16
|
|
|
23
17
|
private
|
|
24
18
|
|
|
25
|
-
def
|
|
26
|
-
@
|
|
19
|
+
def gem_platform
|
|
20
|
+
@gem_platform ||= Gem::Platform.local
|
|
27
21
|
end
|
|
28
22
|
end
|
|
29
23
|
end
|
data/lib/elastic_apm/railtie.rb
CHANGED
|
@@ -26,8 +26,8 @@ module ElasticAPM
|
|
|
26
26
|
app.middleware.insert 0, Middleware
|
|
27
27
|
end
|
|
28
28
|
rescue StandardError => e
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
config.alert_logger.error format('Failed to start: %s', e.message)
|
|
30
|
+
config.alert_logger.debug e.backtrace.join("\n")
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -4,8 +4,6 @@ module ElasticAPM
|
|
|
4
4
|
class Span
|
|
5
5
|
# @api private
|
|
6
6
|
class Context
|
|
7
|
-
include NaivelyHashable
|
|
8
|
-
|
|
9
7
|
def initialize(db: nil, http: nil)
|
|
10
8
|
@db = db && Db.new(db)
|
|
11
9
|
@http = http && Http.new(http)
|
|
@@ -15,8 +13,6 @@ module ElasticAPM
|
|
|
15
13
|
|
|
16
14
|
# @api private
|
|
17
15
|
class Db
|
|
18
|
-
include NaivelyHashable
|
|
19
|
-
|
|
20
16
|
def initialize(instance: nil, statement: nil, type: nil, user: nil)
|
|
21
17
|
@instance = instance
|
|
22
18
|
@statement = statement
|
|
@@ -29,8 +25,6 @@ module ElasticAPM
|
|
|
29
25
|
|
|
30
26
|
# @api private
|
|
31
27
|
class Http
|
|
32
|
-
include NaivelyHashable
|
|
33
|
-
|
|
34
28
|
def initialize(url: nil, status_code: nil, method: nil)
|
|
35
29
|
@url = url
|
|
36
30
|
@status_code = status_code
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ElasticAPM
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class FaradaySpy
|
|
8
|
+
# rubocop:disable Metrics/MethodLength
|
|
9
|
+
def install
|
|
10
|
+
::Faraday::Connection.class_eval do
|
|
11
|
+
alias run_request_without_apm run_request
|
|
12
|
+
|
|
13
|
+
def run_request(method, url, body, headers, &block)
|
|
14
|
+
unless (transaction = ElasticAPM.current_transaction)
|
|
15
|
+
return run_request_without_apm(method, url, body, headers, &block)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
host = URI(url).host
|
|
19
|
+
|
|
20
|
+
name = "#{method.upcase} #{host}"
|
|
21
|
+
type = "ext.faraday.#{method}"
|
|
22
|
+
|
|
23
|
+
ElasticAPM.with_span name, type do |span|
|
|
24
|
+
ElasticAPM::Spies::NetHTTPSpy.disable_in do
|
|
25
|
+
run_request_without_apm(method, url, body, headers) do |req|
|
|
26
|
+
req['Elastic-Apm-Traceparent'] =
|
|
27
|
+
transaction.traceparent.to_header(span_id: span.id)
|
|
28
|
+
|
|
29
|
+
yield req if block_given?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
# rubocop:enable Metrics/MethodLength
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
register 'Faraday', 'faraday', FaradaySpy.new
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -5,7 +5,29 @@ module ElasticAPM
|
|
|
5
5
|
module Spies
|
|
6
6
|
# @api private
|
|
7
7
|
class NetHTTPSpy
|
|
8
|
+
KEY = :__elastic_apm_net_http_disabled
|
|
9
|
+
|
|
8
10
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
11
|
+
class << self
|
|
12
|
+
def disabled=(disabled)
|
|
13
|
+
Thread.current[KEY] = disabled
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def disabled?
|
|
17
|
+
Thread.current[KEY] ||= false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def disable_in
|
|
21
|
+
self.disabled = true
|
|
22
|
+
|
|
23
|
+
begin
|
|
24
|
+
yield
|
|
25
|
+
ensure
|
|
26
|
+
self.disabled = false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
9
31
|
def install
|
|
10
32
|
Net::HTTP.class_eval do
|
|
11
33
|
alias request_without_apm request
|
|
@@ -14,6 +36,9 @@ module ElasticAPM
|
|
|
14
36
|
unless (transaction = ElasticAPM.current_transaction)
|
|
15
37
|
return request_without_apm(req, body, &block)
|
|
16
38
|
end
|
|
39
|
+
if ElasticAPM::Spies::NetHTTPSpy.disabled?
|
|
40
|
+
return request_without_apm(req, body, &block)
|
|
41
|
+
end
|
|
17
42
|
|
|
18
43
|
host, = req['host'] && req['host'].split(':')
|
|
19
44
|
method = req.method
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'elastic_apm/metadata'
|
|
3
4
|
require 'elastic_apm/transport/connection'
|
|
4
5
|
require 'elastic_apm/transport/worker'
|
|
5
|
-
|
|
6
6
|
require 'elastic_apm/transport/serializers'
|
|
7
7
|
require 'elastic_apm/transport/filters'
|
|
8
8
|
|
|
@@ -25,7 +25,6 @@ module ElasticAPM
|
|
|
25
25
|
attr_reader :config, :queue, :workers, :filters
|
|
26
26
|
|
|
27
27
|
def start
|
|
28
|
-
ensure_worker_count
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
def stop
|
|
@@ -4,8 +4,6 @@ require 'http'
|
|
|
4
4
|
require 'concurrent'
|
|
5
5
|
require 'zlib'
|
|
6
6
|
|
|
7
|
-
require 'elastic_apm/metadata'
|
|
8
|
-
|
|
9
7
|
module ElasticAPM
|
|
10
8
|
module Transport
|
|
11
9
|
# @api private
|
|
@@ -30,8 +28,9 @@ module ElasticAPM
|
|
|
30
28
|
}.freeze
|
|
31
29
|
GZIP_HEADERS = HEADERS.merge('Content-Encoding' => 'gzip').freeze
|
|
32
30
|
|
|
33
|
-
def initialize(config)
|
|
31
|
+
def initialize(config, metadata)
|
|
34
32
|
@config = config
|
|
33
|
+
@metadata = metadata.to_json
|
|
35
34
|
|
|
36
35
|
@url = config.server_url + '/intake/v2/events'
|
|
37
36
|
|
|
@@ -44,12 +43,12 @@ module ElasticAPM
|
|
|
44
43
|
|
|
45
44
|
@client = HTTP.headers(headers).persistent(@url)
|
|
46
45
|
|
|
47
|
-
@metadata = Metadata.build(config)
|
|
48
|
-
|
|
49
46
|
@mutex = Mutex.new
|
|
50
47
|
end
|
|
51
48
|
|
|
52
49
|
def write(str)
|
|
50
|
+
return if @config.disable_send
|
|
51
|
+
|
|
53
52
|
connect_unless_connected
|
|
54
53
|
|
|
55
54
|
@mutex.synchronize { append(str) }
|
|
@@ -15,11 +15,23 @@ module ElasticAPM
|
|
|
15
15
|
@config = config
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
attr_reader :config
|
|
19
|
+
|
|
18
20
|
private
|
|
19
21
|
|
|
20
22
|
def ms(micros)
|
|
21
23
|
micros.to_f / 1_000
|
|
22
24
|
end
|
|
25
|
+
|
|
26
|
+
def keyword_field(value)
|
|
27
|
+
Util.truncate(value)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def keyword_object(hash)
|
|
31
|
+
hash.tap do |h|
|
|
32
|
+
h.each { |k, v| hash[k] = keyword_field(v) }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
23
35
|
end
|
|
24
36
|
|
|
25
37
|
# @api private
|
|
@@ -28,10 +40,12 @@ module ElasticAPM
|
|
|
28
40
|
@transaction = Serializers::TransactionSerializer.new(config)
|
|
29
41
|
@span = Serializers::SpanSerializer.new(config)
|
|
30
42
|
@error = Serializers::ErrorSerializer.new(config)
|
|
43
|
+
@metadata = Serializers::MetadataSerializer.new(config)
|
|
31
44
|
end
|
|
32
45
|
|
|
33
|
-
attr_reader :transaction, :span, :error
|
|
46
|
+
attr_reader :transaction, :span, :error, :metadata
|
|
34
47
|
|
|
48
|
+
# rubocop:disable Metrics/MethodLength
|
|
35
49
|
def serialize(resource)
|
|
36
50
|
case resource
|
|
37
51
|
when Transaction
|
|
@@ -40,10 +54,13 @@ module ElasticAPM
|
|
|
40
54
|
span.build(resource)
|
|
41
55
|
when Error
|
|
42
56
|
error.build(resource)
|
|
57
|
+
when Metadata
|
|
58
|
+
metadata.build(resource)
|
|
43
59
|
else
|
|
44
60
|
raise UnrecognizedResource, resource.inspect
|
|
45
61
|
end
|
|
46
62
|
end
|
|
63
|
+
# rubocop:enable Metrics/MethodLength
|
|
47
64
|
end
|
|
48
65
|
|
|
49
66
|
def self.new(config)
|
|
@@ -53,6 +70,8 @@ module ElasticAPM
|
|
|
53
70
|
end
|
|
54
71
|
end
|
|
55
72
|
|
|
56
|
-
require 'elastic_apm/transport/serializers/
|
|
57
|
-
require 'elastic_apm/transport/serializers/span_serializer'
|
|
73
|
+
require 'elastic_apm/transport/serializers/context_serializer'
|
|
58
74
|
require 'elastic_apm/transport/serializers/error_serializer'
|
|
75
|
+
require 'elastic_apm/transport/serializers/metadata_serializer'
|
|
76
|
+
require 'elastic_apm/transport/serializers/span_serializer'
|
|
77
|
+
require 'elastic_apm/transport/serializers/transaction_serializer'
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ElasticAPM
|
|
4
|
+
module Transport
|
|
5
|
+
module Serializers
|
|
6
|
+
# @api private
|
|
7
|
+
class ContextSerializer < Serializer
|
|
8
|
+
def build(context)
|
|
9
|
+
{
|
|
10
|
+
custom: context.custom,
|
|
11
|
+
tags: keyword_object(context.tags),
|
|
12
|
+
request: build_request(context.request),
|
|
13
|
+
response: build_response(context.response),
|
|
14
|
+
user: build_user(context.user)
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# rubocop:disable Metrics/MethodLength
|
|
21
|
+
def build_request(request)
|
|
22
|
+
return unless request
|
|
23
|
+
|
|
24
|
+
{
|
|
25
|
+
body: request.body,
|
|
26
|
+
cookies: request.cookies,
|
|
27
|
+
env: request.env,
|
|
28
|
+
headers: request.headers,
|
|
29
|
+
http_version: keyword_field(request.http_version),
|
|
30
|
+
method: keyword_field(request.method),
|
|
31
|
+
socket: build_socket(request.socket),
|
|
32
|
+
url: request.url
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
# rubocop:enable Metrics/MethodLength
|
|
36
|
+
|
|
37
|
+
def build_response(response)
|
|
38
|
+
return unless response
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
status_code: response.status_code,
|
|
42
|
+
headers: response.headers,
|
|
43
|
+
headers_sent: response.headers_sent,
|
|
44
|
+
finished: response.finished
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def build_user(user)
|
|
49
|
+
return unless user
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
id: keyword_field(user.id),
|
|
53
|
+
email: keyword_field(user.email),
|
|
54
|
+
username: keyword_field(user.username)
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def build_socket(socket)
|
|
59
|
+
return unless socket
|
|
60
|
+
|
|
61
|
+
{
|
|
62
|
+
remote_addr: socket.remote_addr,
|
|
63
|
+
encrypted: socket.encrypted
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -5,6 +5,10 @@ module ElasticAPM
|
|
|
5
5
|
module Serializers
|
|
6
6
|
# @api private
|
|
7
7
|
class ErrorSerializer < Serializer
|
|
8
|
+
def context_serializer
|
|
9
|
+
@context_serializer ||= ContextSerializer.new(config)
|
|
10
|
+
end
|
|
11
|
+
|
|
8
12
|
# rubocop:disable Metrics/MethodLength
|
|
9
13
|
def build(error)
|
|
10
14
|
base = {
|
|
@@ -15,7 +19,7 @@ module ElasticAPM
|
|
|
15
19
|
|
|
16
20
|
culprit: error.culprit,
|
|
17
21
|
timestamp: error.timestamp,
|
|
18
|
-
context: error.context
|
|
22
|
+
context: context_serializer.build(error.context)
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
if (exception = error.exception)
|
|
@@ -35,9 +39,9 @@ module ElasticAPM
|
|
|
35
39
|
def build_exception(exception)
|
|
36
40
|
{
|
|
37
41
|
message: exception.message,
|
|
38
|
-
type: exception.type,
|
|
39
|
-
module: exception.module,
|
|
40
|
-
code: exception.code,
|
|
42
|
+
type: keyword_field(exception.type),
|
|
43
|
+
module: keyword_field(exception.module),
|
|
44
|
+
code: keyword_field(exception.code),
|
|
41
45
|
attributes: exception.attributes,
|
|
42
46
|
stacktrace: exception.stacktrace.to_a,
|
|
43
47
|
handled: exception.handled
|
|
@@ -47,9 +51,9 @@ module ElasticAPM
|
|
|
47
51
|
def build_log(log)
|
|
48
52
|
{
|
|
49
53
|
message: log.message,
|
|
50
|
-
level: log.level,
|
|
51
|
-
logger_name: log.logger_name,
|
|
52
|
-
param_message: log.param_message,
|
|
54
|
+
level: keyword_field(log.level),
|
|
55
|
+
logger_name: keyword_field(log.logger_name),
|
|
56
|
+
param_message: keyword_field(log.param_message),
|
|
53
57
|
stacktrace: log.stacktrace.to_a
|
|
54
58
|
}
|
|
55
59
|
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ElasticAPM
|
|
4
|
+
module Transport
|
|
5
|
+
module Serializers
|
|
6
|
+
# @api private
|
|
7
|
+
class MetadataSerializer < Serializer
|
|
8
|
+
def build(metadata)
|
|
9
|
+
{
|
|
10
|
+
metadata: {
|
|
11
|
+
service: build_service(metadata.service),
|
|
12
|
+
process: build_process(metadata.process),
|
|
13
|
+
system: build_system(metadata.system)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
21
|
+
def build_service(service)
|
|
22
|
+
{
|
|
23
|
+
name: keyword_field(service.name),
|
|
24
|
+
environment: keyword_field(service.environment),
|
|
25
|
+
version: keyword_field(service.version),
|
|
26
|
+
agent: {
|
|
27
|
+
name: keyword_field(service.agent.name),
|
|
28
|
+
version: keyword_field(service.agent.version)
|
|
29
|
+
},
|
|
30
|
+
framework: {
|
|
31
|
+
name: keyword_field(service.framework.name),
|
|
32
|
+
version: keyword_field(service.framework.version)
|
|
33
|
+
},
|
|
34
|
+
language: {
|
|
35
|
+
name: keyword_field(service.language.name),
|
|
36
|
+
version: keyword_field(service.language.version)
|
|
37
|
+
},
|
|
38
|
+
runtime: {
|
|
39
|
+
name: keyword_field(service.runtime.name),
|
|
40
|
+
version: keyword_field(service.runtime.version)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
45
|
+
|
|
46
|
+
def build_process(process)
|
|
47
|
+
{
|
|
48
|
+
pid: process.pid,
|
|
49
|
+
title: keyword_field(process.title),
|
|
50
|
+
argv: process.argv
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def build_system(system)
|
|
55
|
+
{
|
|
56
|
+
hostname: keyword_field(system.hostname),
|
|
57
|
+
architecture: keyword_field(system.architecture),
|
|
58
|
+
platform: keyword_field(system.platform)
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -5,24 +5,68 @@ module ElasticAPM
|
|
|
5
5
|
module Serializers
|
|
6
6
|
# @api private
|
|
7
7
|
class SpanSerializer < Serializer
|
|
8
|
-
|
|
8
|
+
def initialize(config)
|
|
9
|
+
super
|
|
10
|
+
|
|
11
|
+
@context_serializer = ContextSerializer.new(config)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :context_serializer
|
|
15
|
+
|
|
16
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
9
17
|
def build(span)
|
|
10
18
|
{
|
|
11
19
|
span: {
|
|
12
20
|
id: span.id,
|
|
13
21
|
transaction_id: span.transaction_id,
|
|
14
22
|
parent_id: span.parent_id,
|
|
15
|
-
name: span.name,
|
|
16
|
-
type: span.type,
|
|
23
|
+
name: keyword_field(span.name),
|
|
24
|
+
type: keyword_field(span.type),
|
|
17
25
|
duration: ms(span.duration),
|
|
18
|
-
context: span.context
|
|
26
|
+
context: context_serializer.build(span.context),
|
|
19
27
|
stacktrace: span.stacktrace.to_a,
|
|
20
28
|
timestamp: span.timestamp,
|
|
21
29
|
trace_id: span.trace_id
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
end
|
|
25
|
-
# rubocop:enable Metrics/MethodLength
|
|
33
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
34
|
+
|
|
35
|
+
# @api private
|
|
36
|
+
class ContextSerializer < Serializer
|
|
37
|
+
def build(context)
|
|
38
|
+
return unless context
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
sync: context.sync,
|
|
42
|
+
db: build_db(context.db),
|
|
43
|
+
http: build_http(context.http)
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def build_db(db)
|
|
50
|
+
return unless db
|
|
51
|
+
|
|
52
|
+
{
|
|
53
|
+
instance: db.instance,
|
|
54
|
+
statement: db.statement,
|
|
55
|
+
type: db.type,
|
|
56
|
+
user: db.user
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def build_http(http)
|
|
61
|
+
return unless http
|
|
62
|
+
|
|
63
|
+
{
|
|
64
|
+
url: http.url,
|
|
65
|
+
status_code: http.status_code,
|
|
66
|
+
method: keyword_field(http.method)
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
end
|
|
26
70
|
end
|
|
27
71
|
end
|
|
28
72
|
end
|
|
@@ -5,20 +5,24 @@ module ElasticAPM
|
|
|
5
5
|
module Serializers
|
|
6
6
|
# @api private
|
|
7
7
|
class TransactionSerializer < Serializer
|
|
8
|
-
|
|
8
|
+
def context_serializer
|
|
9
|
+
@context_serializer ||= ContextSerializer.new(config)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
9
13
|
def build(transaction)
|
|
10
14
|
{
|
|
11
15
|
transaction: {
|
|
12
16
|
id: transaction.id,
|
|
13
17
|
trace_id: transaction.trace_id,
|
|
14
18
|
parent_id: transaction.parent_id,
|
|
15
|
-
name: transaction.name,
|
|
16
|
-
type: transaction.type,
|
|
17
|
-
result: transaction.result.to_s,
|
|
19
|
+
name: keyword_field(transaction.name),
|
|
20
|
+
type: keyword_field(transaction.type),
|
|
21
|
+
result: keyword_field(transaction.result.to_s),
|
|
18
22
|
duration: ms(transaction.duration),
|
|
19
23
|
timestamp: transaction.timestamp,
|
|
20
24
|
sampled: transaction.sampled?,
|
|
21
|
-
context: transaction.context
|
|
25
|
+
context: context_serializer.build(transaction.context),
|
|
22
26
|
span_count: {
|
|
23
27
|
started: transaction.started_spans,
|
|
24
28
|
dropped: transaction.dropped_spans
|
|
@@ -26,7 +30,7 @@ module ElasticAPM
|
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
end
|
|
29
|
-
# rubocop:enable Metrics/MethodLength
|
|
33
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
30
34
|
end
|
|
31
35
|
end
|
|
32
36
|
end
|
|
@@ -24,9 +24,11 @@ module ElasticAPM
|
|
|
24
24
|
|
|
25
25
|
@stopping = false
|
|
26
26
|
|
|
27
|
-
@connection = conn_adapter.new(config)
|
|
28
27
|
@serializers = serializers
|
|
29
28
|
@filters = filters
|
|
29
|
+
|
|
30
|
+
metadata = serializers.serialize(Metadata.new(config))
|
|
31
|
+
@connection = conn_adapter.new(config, metadata)
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
attr_reader :queue, :filters, :name, :connection, :serializers
|
|
@@ -39,7 +41,7 @@ module ElasticAPM
|
|
|
39
41
|
@stopping
|
|
40
42
|
end
|
|
41
43
|
|
|
42
|
-
# rubocop:disable Metrics/MethodLength
|
|
44
|
+
# rubocop:disable Metrics/MethodLength
|
|
43
45
|
def work_forever
|
|
44
46
|
while (msg = queue.pop)
|
|
45
47
|
case msg
|
|
@@ -59,7 +61,7 @@ module ElasticAPM
|
|
|
59
61
|
warn 'Worker died with exception: %s', e.inspect
|
|
60
62
|
debug e.backtrace.join("\n")
|
|
61
63
|
end
|
|
62
|
-
# rubocop:enable Metrics/MethodLength
|
|
64
|
+
# rubocop:enable Metrics/MethodLength
|
|
63
65
|
|
|
64
66
|
private
|
|
65
67
|
|
data/lib/elastic_apm/util.rb
CHANGED
|
@@ -24,5 +24,12 @@ module ElasticAPM
|
|
|
24
24
|
def self.reverse_merge!(first, second)
|
|
25
25
|
first.merge!(second) { |_, old, _| old }
|
|
26
26
|
end
|
|
27
|
+
|
|
28
|
+
def self.truncate(value, max_length: 1024)
|
|
29
|
+
return unless value
|
|
30
|
+
return value if value.length <= max_length
|
|
31
|
+
|
|
32
|
+
value[0...(max_length - 1)] + '…'
|
|
33
|
+
end
|
|
27
34
|
end
|
|
28
35
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ElasticAPM
|
|
4
|
+
# @api private
|
|
5
|
+
class PrefixedLogger < Logger
|
|
6
|
+
def initialize(logdev, prefix: '', **args)
|
|
7
|
+
super(logdev, **args)
|
|
8
|
+
|
|
9
|
+
@prefix = prefix
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_reader :prefix
|
|
13
|
+
|
|
14
|
+
def add(severity, message = nil, progname = nil)
|
|
15
|
+
super(severity, format('%s%s', prefix, message), progname)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
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.0
|
|
4
|
+
version: 2.1.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-
|
|
11
|
+
date: 2018-12-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -66,6 +66,7 @@ files:
|
|
|
66
66
|
- bin/console
|
|
67
67
|
- bin/setup
|
|
68
68
|
- bin/with_framework
|
|
69
|
+
- docs/advanced.asciidoc
|
|
69
70
|
- docs/api.asciidoc
|
|
70
71
|
- docs/configuration.asciidoc
|
|
71
72
|
- docs/context.asciidoc
|
|
@@ -73,6 +74,7 @@ files:
|
|
|
73
74
|
- docs/getting-started-rack.asciidoc
|
|
74
75
|
- docs/getting-started-rails.asciidoc
|
|
75
76
|
- docs/index.asciidoc
|
|
77
|
+
- docs/introduction.asciidoc
|
|
76
78
|
- docs/supported-technologies.asciidoc
|
|
77
79
|
- elastic-apm.gemspec
|
|
78
80
|
- lib/elastic-apm.rb
|
|
@@ -115,6 +117,7 @@ files:
|
|
|
115
117
|
- lib/elastic_apm/spies/action_dispatch.rb
|
|
116
118
|
- lib/elastic_apm/spies/delayed_job.rb
|
|
117
119
|
- lib/elastic_apm/spies/elasticsearch.rb
|
|
120
|
+
- lib/elastic_apm/spies/faraday.rb
|
|
118
121
|
- lib/elastic_apm/spies/http.rb
|
|
119
122
|
- lib/elastic_apm/spies/json.rb
|
|
120
123
|
- lib/elastic_apm/spies/mongo.rb
|
|
@@ -138,13 +141,16 @@ files:
|
|
|
138
141
|
- lib/elastic_apm/transport/filters/request_body_filter.rb
|
|
139
142
|
- lib/elastic_apm/transport/filters/secrets_filter.rb
|
|
140
143
|
- lib/elastic_apm/transport/serializers.rb
|
|
144
|
+
- lib/elastic_apm/transport/serializers/context_serializer.rb
|
|
141
145
|
- lib/elastic_apm/transport/serializers/error_serializer.rb
|
|
146
|
+
- lib/elastic_apm/transport/serializers/metadata_serializer.rb
|
|
142
147
|
- lib/elastic_apm/transport/serializers/span_serializer.rb
|
|
143
148
|
- lib/elastic_apm/transport/serializers/transaction_serializer.rb
|
|
144
149
|
- lib/elastic_apm/transport/worker.rb
|
|
145
150
|
- lib/elastic_apm/util.rb
|
|
146
151
|
- lib/elastic_apm/util/inflector.rb
|
|
147
152
|
- lib/elastic_apm/util/lru_cache.rb
|
|
153
|
+
- lib/elastic_apm/util/prefixed_logger.rb
|
|
148
154
|
- lib/elastic_apm/version.rb
|
|
149
155
|
- vendor/.gitkeep
|
|
150
156
|
homepage: https://github.com/elastic/apm-agent-ruby
|