elastic-apm 3.0.0 → 3.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/.ci/Jenkinsfile +4 -1
- data/CHANGELOG.asciidoc +497 -0
- data/CHANGELOG.md +1 -359
- data/Rakefile +2 -2
- data/docs/advanced.asciidoc +0 -2
- data/docs/api.asciidoc +12 -1
- data/docs/configuration.asciidoc +15 -4
- data/docs/custom-instrumentation.asciidoc +2 -2
- data/docs/debugging.asciidoc +1 -1
- data/docs/getting-started-rack.asciidoc +4 -1
- data/docs/getting-started-rails.asciidoc +2 -2
- data/docs/index.asciidoc +8 -9
- data/docs/introduction.asciidoc +17 -15
- data/docs/opentracing.asciidoc +13 -13
- data/docs/release-notes.asciidoc +11 -1
- data/docs/set-up.asciidoc +16 -0
- data/docs/supported-technologies.asciidoc +2 -4
- data/lib/elastic_apm.rb +2 -2
- data/lib/elastic_apm/agent.rb +4 -4
- data/lib/elastic_apm/central_config.rb +7 -3
- data/lib/elastic_apm/config.rb +2 -2
- data/lib/elastic_apm/config/options.rb +6 -0
- data/lib/elastic_apm/context.rb +15 -1
- data/lib/elastic_apm/instrumenter.rb +8 -7
- data/lib/elastic_apm/normalizers.rb +0 -9
- data/lib/elastic_apm/normalizers/rails.rb +10 -0
- data/lib/elastic_apm/normalizers/{action_controller.rb → rails/action_controller.rb} +0 -0
- data/lib/elastic_apm/normalizers/{action_mailer.rb → rails/action_mailer.rb} +0 -0
- data/lib/elastic_apm/normalizers/{action_view.rb → rails/action_view.rb} +0 -0
- data/lib/elastic_apm/normalizers/{active_record.rb → rails/active_record.rb} +0 -0
- data/lib/elastic_apm/rails.rb +1 -0
- data/lib/elastic_apm/sinatra.rb +36 -0
- data/lib/elastic_apm/transaction.rb +13 -6
- data/lib/elastic_apm/transport/serializers/context_serializer.rb +13 -1
- data/lib/elastic_apm/version.rb +1 -1
- metadata +10 -6
@@ -1,12 +1,12 @@
|
|
1
1
|
[[custom-instrumentation]]
|
2
2
|
=== Custom instrumentation
|
3
3
|
|
4
|
-
When
|
4
|
+
When installed and properly configured,
|
5
5
|
ElasticAPM will automatically wrap your app's request/responses in transactions
|
6
6
|
and report its errors.
|
7
7
|
It also wraps each background job if you use Sidekiq or DelayedJob.
|
8
8
|
|
9
|
-
But it is possible to create your own transactions as well as provide spans for
|
9
|
+
But it is also possible to create your own transactions as well as provide spans for
|
10
10
|
any automatic or custom transaction.
|
11
11
|
|
12
12
|
See <<api-agent-start_transaction,`ElasticAPM.start_transaction`>> and
|
data/docs/debugging.asciidoc
CHANGED
@@ -5,7 +5,7 @@ https://www.elastic.co/guide/en/apm/agent/ruby/current/introduction.html[elastic
|
|
5
5
|
endif::[]
|
6
6
|
|
7
7
|
[[getting-started-rack]]
|
8
|
-
|
8
|
+
=== Getting started with Rack
|
9
9
|
|
10
10
|
Add the gem to your `Gemfile`:
|
11
11
|
|
@@ -64,6 +64,9 @@ end
|
|
64
64
|
# Takes optional ElasticAPM::Config values
|
65
65
|
ElasticAPM.start(app: MySinatraApp, ...)
|
66
66
|
|
67
|
+
# You can also do the following, which is equivalent to the above:
|
68
|
+
# ElasticAPM::Sinatra.start(MySinatraApp, ...)
|
69
|
+
|
67
70
|
run MySinatraApp
|
68
71
|
|
69
72
|
at_exit { ElasticAPM.stop }
|
@@ -5,10 +5,10 @@ https://www.elastic.co/guide/en/apm/agent/ruby/current/introduction.html[elastic
|
|
5
5
|
endif::[]
|
6
6
|
|
7
7
|
[[getting-started-rails]]
|
8
|
-
|
8
|
+
=== Getting started with Rails
|
9
9
|
|
10
10
|
[float]
|
11
|
-
|
11
|
+
==== Setup
|
12
12
|
|
13
13
|
Add the gem to your `Gemfile`:
|
14
14
|
|
data/docs/index.asciidoc
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
:server-branch: 6.5
|
1
|
+
include::{asciidoc-dir}/../../shared/versions/stack/current.asciidoc[]
|
3
2
|
include::{asciidoc-dir}/../../shared/attributes.asciidoc[]
|
4
3
|
|
5
4
|
ifdef::env-github[]
|
@@ -12,21 +11,21 @@ endif::[]
|
|
12
11
|
|
13
12
|
include::./introduction.asciidoc[]
|
14
13
|
|
15
|
-
include::./
|
14
|
+
include::./set-up.asciidoc[]
|
16
15
|
|
17
|
-
include::./
|
16
|
+
include::./supported-technologies.asciidoc[]
|
18
17
|
|
19
18
|
include::./configuration.asciidoc[]
|
20
19
|
|
21
|
-
include::./
|
20
|
+
include::./advanced.asciidoc[]
|
22
21
|
|
23
|
-
include::./
|
22
|
+
include::./api.asciidoc[]
|
24
23
|
|
25
|
-
include::./
|
24
|
+
include::./metrics.asciidoc[]
|
26
25
|
|
27
|
-
include::./
|
26
|
+
include::./opentracing.asciidoc[]
|
28
27
|
|
29
|
-
include::./
|
28
|
+
include::./log-correlation.asciidoc[]
|
30
29
|
|
31
30
|
include::./debugging.asciidoc[]
|
32
31
|
|
data/docs/introduction.asciidoc
CHANGED
@@ -5,15 +5,27 @@ https://www.elastic.co/guide/en/apm/agent/ruby/current/introduction.html[elastic
|
|
5
5
|
endif::[]
|
6
6
|
|
7
7
|
[[introduction]]
|
8
|
-
|
9
8
|
== Introduction
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
The Elastic APM Ruby Agent sends performance metrics and error logs to an
|
14
|
-
Elastic APM Server.
|
10
|
+
The Elastic APM Ruby Agent sends performance metrics and error logs to the APM Server.
|
15
11
|
It has built-in support for <<getting-started-rails,Ruby on Rails>> and other
|
16
12
|
<<getting-started-rack,Rack-compatible>> applications.
|
13
|
+
It also offers an API which allows you to instrument any application.
|
14
|
+
|
15
|
+
[float]
|
16
|
+
[[how-it-works]]
|
17
|
+
=== How does the Agent work?
|
18
|
+
|
19
|
+
The agent auto-instruments <<supported-technologies,supported technologies>> and records interesting events,
|
20
|
+
like HTTP requests and database queries. To do this, it uses relevant public APIs when they are provided by the libraries. Otherwise, it carefully wraps the necessary internal methods.
|
21
|
+
This means that for the supported technologies, there are no code changes required.
|
22
|
+
|
23
|
+
The Agent automatically keeps track of queries to your data stores to measure their duration and metadata (like the DB statement),
|
24
|
+
as well as HTTP related information (like the URL, parameters, and headers).
|
25
|
+
|
26
|
+
These events, called Transactions and Spans, are sent to the APM Server.
|
27
|
+
The APM Server converts them to a format suitable for Elasticsearch, and sends them to an Elasticsearch cluster.
|
28
|
+
You can then use the APM app in Kibana to gain insight into latency issues and error culprits within your application.
|
17
29
|
|
18
30
|
[float]
|
19
31
|
[[additional-components]]
|
@@ -21,13 +33,3 @@ It has built-in support for <<getting-started-rails,Ruby on Rails>> and other
|
|
21
33
|
|
22
34
|
APM Agents work in conjunction with the {apm-server-ref-v}/index.html[APM Server], {ref}/index.html[Elasticsearch], and {kibana-ref}/index.html[Kibana].
|
23
35
|
Please view the {apm-overview-ref-v}/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/docs/opentracing.asciidoc
CHANGED
@@ -4,7 +4,7 @@ please view this documentation at https://www.elastic.co/guide/en/apm/agent/ruby
|
|
4
4
|
endif::[]
|
5
5
|
|
6
6
|
[[opentracing]]
|
7
|
-
|
7
|
+
== OpenTracing API
|
8
8
|
|
9
9
|
The Elastic APM OpenTracing bridge allows to create Elastic APM `Transactions` and `Spans`,
|
10
10
|
using the OpenTracing API.
|
@@ -16,7 +16,7 @@ subsequent spans are mapped to Elastic APM `Span`.
|
|
16
16
|
|
17
17
|
[float]
|
18
18
|
[[operation-modes]]
|
19
|
-
|
19
|
+
== Operation Modes
|
20
20
|
|
21
21
|
This bridge allows for different operation modes in combination with the Elastic APM Agent.
|
22
22
|
|
@@ -34,12 +34,12 @@ This bridge allows for different operation modes in combination with the Elastic
|
|
34
34
|
|
35
35
|
[float]
|
36
36
|
[[getting-started]]
|
37
|
-
|
37
|
+
== Getting started
|
38
38
|
Either `require 'elastic_apm/opentracing'` during the boot of your app or specify the `require:` argument to your `Gemfile`, eg. `gem 'elastic_apm', require: 'elastic_apm/opentracing'`.
|
39
39
|
|
40
40
|
[float]
|
41
41
|
[[init-tracer]]
|
42
|
-
|
42
|
+
== Set Elastic APM as the global tracer
|
43
43
|
|
44
44
|
[source,ruby]
|
45
45
|
----
|
@@ -48,47 +48,47 @@ Either `require 'elastic_apm/opentracing'` during the boot of your app or specif
|
|
48
48
|
|
49
49
|
[float]
|
50
50
|
[[elastic-apm-tags]]
|
51
|
-
|
51
|
+
== Elastic APM specific tags
|
52
52
|
|
53
53
|
Elastic APM defines some tags which are not included in the OpenTracing API but are relevant in the context of Elastic APM.
|
54
54
|
|
55
55
|
- `type` - sets the type of the transaction,
|
56
56
|
for example `request`, `ext` or `db`
|
57
57
|
- `user.id` - sets the user id,
|
58
|
-
appears in the "User" tab in the transaction details in the Elastic APM
|
58
|
+
appears in the "User" tab in the transaction details in the Elastic APM app
|
59
59
|
- `user.email` - sets the user email,
|
60
|
-
appears in the "User" tab in the transaction details in the Elastic APM
|
60
|
+
appears in the "User" tab in the transaction details in the Elastic APM app
|
61
61
|
- `user.username` - sets the user name,
|
62
|
-
appears in the "User" tab in the transaction details in the Elastic APM
|
62
|
+
appears in the "User" tab in the transaction details in the Elastic APM app
|
63
63
|
- `result` - sets the result of the transaction. Overrides the default value of `success`.
|
64
64
|
If the `error` tag is set to `true`, the default value is `error`.
|
65
65
|
|
66
66
|
[float]
|
67
67
|
[[unsupported]]
|
68
|
-
|
68
|
+
== Caveats
|
69
69
|
Not all features of the OpenTracing API are supported.
|
70
70
|
|
71
71
|
[float]
|
72
72
|
[[propagation]]
|
73
|
-
|
73
|
+
=== Context propagation
|
74
74
|
This bridge only supports the format `OpenTracing::FORMAT_RACK`, using HTTP headers with capitalized names, prefixed with `HTTP_` as Rack does it.
|
75
75
|
|
76
76
|
`OpenTracing::FORMAT_BINARY` is currently not supported.
|
77
77
|
|
78
78
|
[float]
|
79
79
|
[[references]]
|
80
|
-
|
80
|
+
=== Span References
|
81
81
|
Currently, this bridge only supports `child_of` references.
|
82
82
|
Other references,
|
83
83
|
like `follows_from` are not supported yet.
|
84
84
|
|
85
85
|
[float]
|
86
86
|
[[baggage]]
|
87
|
-
|
87
|
+
=== Baggage
|
88
88
|
The `Span.set_baggage` method is not supported.
|
89
89
|
Baggage items are dropped with a warning log message.
|
90
90
|
|
91
91
|
[float]
|
92
92
|
[[logs]]
|
93
|
-
|
93
|
+
=== Logs
|
94
94
|
Logs are currently not supported.
|
data/docs/release-notes.asciidoc
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
+
:pull: https://github.com/elastic/apm-server/pull/
|
2
|
+
|
1
3
|
[[release-notes]]
|
2
4
|
== Release notes
|
3
5
|
|
4
|
-
|
6
|
+
All notable changes to this project will be documented here.
|
7
|
+
This project adheres to http://semver.org/spec/v2.0.0.html[Semantic Versioning].
|
8
|
+
|
9
|
+
* <<release-notes-3.x>>
|
10
|
+
* <<release-notes-2.x>>
|
11
|
+
* <<release-notes-1.x>>
|
12
|
+
* <<release-notes-0.x>>
|
13
|
+
|
14
|
+
include::../CHANGELOG.asciidoc[]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
ifdef::env-github[]
|
2
|
+
NOTE: For the best reading experience,
|
3
|
+
please view this documentation at
|
4
|
+
https://www.elastic.co/guide/en/apm/agent/ruby/current/set-up.html[elastic.co]
|
5
|
+
endif::[]
|
6
|
+
|
7
|
+
[[set-up]]
|
8
|
+
== Set up the Agent
|
9
|
+
|
10
|
+
To get you off the ground, we’ve prepared guides for setting up the Agent with different frameworks:
|
11
|
+
|
12
|
+
include::./getting-started-rails.asciidoc[]
|
13
|
+
|
14
|
+
include::./getting-started-rack.asciidoc[]
|
15
|
+
|
16
|
+
For custom instrumentation, see the <<api>>.
|
@@ -7,10 +7,8 @@ endif::[]
|
|
7
7
|
== Supported technologies
|
8
8
|
|
9
9
|
The Elastic APM Ruby Agent has built-in support for many frameworks and
|
10
|
-
libraries.
|
11
|
-
|
12
|
-
Generally we want to support all the most popular libraries, so if your favorite
|
13
|
-
is missing feel free so request it in an issue or better yet supply a pull
|
10
|
+
libraries. Generally, we want to support all of the most popular libraries. If your favorite
|
11
|
+
is missing, feel free to request it in an issue, or better yet, create a pull
|
14
12
|
request.
|
15
13
|
|
16
14
|
[float]
|
data/lib/elastic_apm.rb
CHANGED
@@ -14,6 +14,7 @@ require 'elastic_apm/util'
|
|
14
14
|
require 'elastic_apm/middleware'
|
15
15
|
|
16
16
|
require 'elastic_apm/railtie' if defined?(::Rails::Railtie)
|
17
|
+
require 'elastic_apm/sinatra' if defined?(::Sinatra)
|
17
18
|
|
18
19
|
# ElasticAPM
|
19
20
|
module ElasticAPM # rubocop:disable Metrics/ModuleLength
|
@@ -80,7 +81,6 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
|
|
80
81
|
end
|
81
82
|
# rubocop:enable Metrics/AbcSize
|
82
83
|
|
83
|
-
# rubocop:disable Metrics/MethodLength
|
84
84
|
# Start a new transaction
|
85
85
|
#
|
86
86
|
# @param name [String] A description of the transaction, eg
|
@@ -102,7 +102,6 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
|
|
102
102
|
trace_context: trace_context
|
103
103
|
)
|
104
104
|
end
|
105
|
-
# rubocop:enable Metrics/MethodLength
|
106
105
|
|
107
106
|
# Ends the current transaction with `result`
|
108
107
|
#
|
@@ -150,6 +149,7 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
|
|
150
149
|
end
|
151
150
|
# rubocop:enable Metrics/MethodLength
|
152
151
|
|
152
|
+
# rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
153
153
|
# Start a new span
|
154
154
|
#
|
155
155
|
# @param name [String] A description of the span, eq `SELECT FROM "users"`
|
data/lib/elastic_apm/agent.rb
CHANGED
@@ -17,6 +17,7 @@ module ElasticAPM
|
|
17
17
|
# @api private
|
18
18
|
class Agent
|
19
19
|
include Logging
|
20
|
+
extend Forwardable
|
20
21
|
|
21
22
|
LOCK = Mutex.new
|
22
23
|
|
@@ -61,10 +62,7 @@ module ElasticAPM
|
|
61
62
|
!!@instance
|
62
63
|
end
|
63
64
|
|
64
|
-
# rubocop:disable Metrics/MethodLength
|
65
65
|
def initialize(config)
|
66
|
-
@config = config
|
67
|
-
|
68
66
|
@stacktrace_builder = StacktraceBuilder.new(config)
|
69
67
|
@context_builder = ContextBuilder.new(config)
|
70
68
|
@error_builder = ErrorBuilder.new(self)
|
@@ -77,7 +75,6 @@ module ElasticAPM
|
|
77
75
|
) { |event| enqueue event }
|
78
76
|
@metrics = Metrics.new(config) { |event| enqueue event }
|
79
77
|
end
|
80
|
-
# rubocop:enable Metrics/MethodLength
|
81
78
|
|
82
79
|
attr_reader(
|
83
80
|
:central_config,
|
@@ -90,6 +87,8 @@ module ElasticAPM
|
|
90
87
|
:transport
|
91
88
|
)
|
92
89
|
|
90
|
+
def_delegator :@central_config, :config
|
91
|
+
|
93
92
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
94
93
|
def start
|
95
94
|
unless config.disable_start_message
|
@@ -150,6 +149,7 @@ module ElasticAPM
|
|
150
149
|
instrumenter.start_transaction(
|
151
150
|
name,
|
152
151
|
type,
|
152
|
+
config: config,
|
153
153
|
context: context,
|
154
154
|
trace_context: trace_context
|
155
155
|
)
|
@@ -81,11 +81,15 @@ module ElasticAPM
|
|
81
81
|
update[key] = @modified_options.delete(key)
|
82
82
|
end
|
83
83
|
|
84
|
-
|
84
|
+
update_config(update)
|
85
85
|
end
|
86
86
|
|
87
87
|
private
|
88
88
|
|
89
|
+
def update_config(new_options)
|
90
|
+
@config = config.dup.tap { |new_config| new_config.assign(new_options) }
|
91
|
+
end
|
92
|
+
|
89
93
|
# rubocop:disable Metrics/MethodLength
|
90
94
|
def handle_success(resp)
|
91
95
|
if resp.status == 304
|
@@ -107,7 +111,7 @@ module ElasticAPM
|
|
107
111
|
# rubocop:enable Metrics/MethodLength
|
108
112
|
|
109
113
|
def handle_error(error)
|
110
|
-
|
114
|
+
debug(
|
111
115
|
'Failed fetching config: %s, trying again in %d seconds',
|
112
116
|
error.response.body, DEFAULT_MAX_AGE
|
113
117
|
)
|
@@ -119,7 +123,7 @@ module ElasticAPM
|
|
119
123
|
|
120
124
|
def perform_request
|
121
125
|
Http.post(
|
122
|
-
config.server_url + '/
|
126
|
+
config.server_url + '/config/v1/agents',
|
123
127
|
body: @service_info,
|
124
128
|
headers: { etag: 1, content_type: 'application/json' }
|
125
129
|
)
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -21,7 +21,7 @@ module ElasticAPM
|
|
21
21
|
|
22
22
|
# rubocop:disable Metrics/LineLength, Layout/ExtraSpacing
|
23
23
|
option :config_file, type: :string, default: 'config/elastic_apm.yml'
|
24
|
-
option :server_url, type: :
|
24
|
+
option :server_url, type: :url, default: 'http://localhost:8200'
|
25
25
|
option :secret_token, type: :string
|
26
26
|
|
27
27
|
option :active, type: :bool, default: true
|
@@ -215,7 +215,7 @@ module ElasticAPM
|
|
215
215
|
def set_sinatra(app)
|
216
216
|
self.service_name = format_name(service_name || app.to_s)
|
217
217
|
self.framework_name = framework_name || 'Sinatra'
|
218
|
-
self.framework_version = framework_version || Sinatra::VERSION
|
218
|
+
self.framework_version = framework_version || ::Sinatra::VERSION
|
219
219
|
self.__root_path = Dir.pwd
|
220
220
|
end
|
221
221
|
|
@@ -48,6 +48,7 @@ module ElasticAPM
|
|
48
48
|
when :bool then normalize_bool(val)
|
49
49
|
when :list then normalize_list(val)
|
50
50
|
when :dict then normalize_dict(val)
|
51
|
+
when :url then normalize_url(val)
|
51
52
|
else
|
52
53
|
# raise "Unknown options type '#{type.inspect}'"
|
53
54
|
val
|
@@ -69,6 +70,11 @@ module ElasticAPM
|
|
69
70
|
return val unless val.is_a?(String)
|
70
71
|
Hash[val.split(/[&,]/).map { |kv| kv.split('=') }]
|
71
72
|
end
|
73
|
+
|
74
|
+
def normalize_url(val)
|
75
|
+
val = val.to_s
|
76
|
+
val.end_with?('/') ? val.chomp('/') : val
|
77
|
+
end
|
72
78
|
end
|
73
79
|
|
74
80
|
# @api private
|
data/lib/elastic_apm/context.rb
CHANGED
@@ -9,25 +9,39 @@ require 'elastic_apm/context/user'
|
|
9
9
|
module ElasticAPM
|
10
10
|
# @api private
|
11
11
|
class Context
|
12
|
-
def initialize(custom: {}, labels: {}, user: nil)
|
12
|
+
def initialize(custom: {}, labels: {}, user: nil, service: nil)
|
13
13
|
@custom = custom
|
14
14
|
@labels = labels
|
15
15
|
@user = user || User.new
|
16
|
+
@service = service
|
16
17
|
end
|
17
18
|
|
19
|
+
Service = Struct.new(:framework)
|
20
|
+
Framework = Struct.new(:name, :version)
|
21
|
+
|
18
22
|
attr_accessor :request
|
19
23
|
attr_accessor :response
|
20
24
|
attr_accessor :user
|
21
25
|
attr_reader :custom
|
22
26
|
attr_reader :labels
|
27
|
+
attr_reader :service
|
23
28
|
|
29
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
24
30
|
def empty?
|
25
31
|
return false if labels.any?
|
26
32
|
return false if custom.any?
|
27
33
|
return false if user.any?
|
34
|
+
return false if service
|
28
35
|
return false if request || response
|
29
36
|
|
30
37
|
true
|
31
38
|
end
|
39
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
40
|
+
|
41
|
+
def set_service(framework_name: nil, framework_version: nil)
|
42
|
+
@service = Service.new(
|
43
|
+
Framework.new(framework_name, framework_version)
|
44
|
+
)
|
45
|
+
end
|
32
46
|
end
|
33
47
|
end
|