elastic-apm 4.1.0 → 4.5.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 +1 -1
- data/.ci/docker/jruby/11-jdk/Dockerfile +1 -1
- data/.ci/docker/jruby/12-jdk/Dockerfile +1 -1
- data/.ci/docker/jruby/13-jdk/Dockerfile +1 -1
- data/.ci/docker/jruby/7-jdk/Dockerfile +1 -1
- data/.ci/docker/jruby/8-jdk/Dockerfile +1 -1
- data/.ci/jobs/apm-agent-ruby-mbp.yml +1 -0
- data/CHANGELOG.asciidoc +51 -0
- data/Gemfile +5 -4
- data/SECURITY.md +7 -0
- data/docker-compose.yml +1 -1
- data/docs/configuration.asciidoc +26 -2
- data/docs/metrics.asciidoc +92 -0
- data/elastic-apm.gemspec +8 -8
- data/lib/elastic_apm/agent.rb +4 -4
- data/lib/elastic_apm/central_config.rb +2 -2
- data/lib/elastic_apm/config.rb +20 -0
- data/lib/elastic_apm/context/request/socket.rb +1 -2
- data/lib/elastic_apm/fields.rb +98 -0
- data/lib/elastic_apm/instrumenter.rb +21 -19
- data/lib/elastic_apm/metadata/service_info.rb +1 -1
- data/lib/elastic_apm/metadata/system_info.rb +2 -1
- data/lib/elastic_apm/metrics/cpu_mem_set.rb +9 -6
- data/lib/elastic_apm/metrics/jvm_set.rb +88 -0
- data/lib/elastic_apm/metrics/metric.rb +2 -0
- data/lib/elastic_apm/metrics.rb +22 -8
- data/lib/elastic_apm/span/context/destination.rb +39 -58
- data/lib/elastic_apm/span.rb +11 -1
- data/lib/elastic_apm/spies/azure_storage_table.rb +148 -0
- data/lib/elastic_apm/spies/dynamo_db.rb +8 -9
- data/lib/elastic_apm/spies/faraday.rb +25 -11
- data/lib/elastic_apm/spies/http.rb +3 -4
- data/lib/elastic_apm/spies/mongo.rb +11 -3
- data/lib/elastic_apm/spies/net_http.rb +21 -14
- data/lib/elastic_apm/spies/s3.rb +11 -5
- data/lib/elastic_apm/spies/sequel.rb +1 -1
- data/lib/elastic_apm/spies/sns.rb +3 -9
- data/lib/elastic_apm/spies/sqs.rb +3 -11
- data/lib/elastic_apm/spies.rb +20 -0
- data/lib/elastic_apm/subscriber.rb +1 -0
- data/lib/elastic_apm/transport/connection/http.rb +3 -1
- data/lib/elastic_apm/transport/serializers/context_serializer.rb +1 -2
- data/lib/elastic_apm/transport/serializers/metadata_serializer.rb +6 -2
- data/lib/elastic_apm/transport/serializers/span_serializer.rb +4 -8
- data/lib/elastic_apm/transport/user_agent.rb +12 -6
- data/lib/elastic_apm/version.rb +1 -1
- data/lib/elastic_apm.rb +6 -2
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c396bc981217532f2d6775de89e9a2aa7a1bcd501100588bbd700d0f4f2eb590
|
|
4
|
+
data.tar.gz: 94f859585a09fc99f02a4bbd261193e0ed1f74bdb9463968692a16f277b1e4f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae66a68c4651f695361b2028bf76132e8bc257fc141d3ad2872786bbab10b8e19bc3609a84478de53e56ad0c15695ad7debbcf62c4af8997833d0cf7cc7f6d23
|
|
7
|
+
data.tar.gz: c6b9fd6f80de4139cac0dd040e45d56f869eb2ff8b3db38df376e898490b8c2a5523a9bb3f1ba73a8583356ae5647ec67835b994597dc3db8d72c62ee506794f
|
data/.ci/Jenkinsfile
CHANGED
|
@@ -39,7 +39,7 @@ pipeline {
|
|
|
39
39
|
quietPeriod(10)
|
|
40
40
|
}
|
|
41
41
|
triggers {
|
|
42
|
-
issueCommentTrigger(
|
|
42
|
+
issueCommentTrigger("(${obltGitHubComments()}|^run benchmark tests)")
|
|
43
43
|
}
|
|
44
44
|
parameters {
|
|
45
45
|
booleanParam(name: 'Run_As_Master_Branch', defaultValue: false, description: 'Allow to run any steps on a PR, some steps normally only run on master branch.')
|
data/CHANGELOG.asciidoc
CHANGED
|
@@ -35,6 +35,57 @@ endif::[]
|
|
|
35
35
|
[[release-notes-4.x]]
|
|
36
36
|
=== Ruby Agent version 4.x
|
|
37
37
|
|
|
38
|
+
[[release-notes-4.5.0]]
|
|
39
|
+
==== 4.5.0
|
|
40
|
+
|
|
41
|
+
[float]
|
|
42
|
+
===== Changed
|
|
43
|
+
|
|
44
|
+
- Stop collecting the field `http.request.socket.encrypted` {pull}1181[#1181]
|
|
45
|
+
|
|
46
|
+
[float]
|
|
47
|
+
===== Fixed
|
|
48
|
+
|
|
49
|
+
- Fixed MongoDB spy thread safety {pull}1202[#1202]
|
|
50
|
+
- Fixed span context fields for DynamoDB instrumentation {pull}1178[#1178]
|
|
51
|
+
- Fixed span context fields for S3 instrumentation {pull}1179[#1179]
|
|
52
|
+
- Update user agent info to match spec {pull}1182[#1182]
|
|
53
|
+
|
|
54
|
+
[[release-notes-4.4.0]]
|
|
55
|
+
==== 4.4.0
|
|
56
|
+
|
|
57
|
+
[float]
|
|
58
|
+
===== Added
|
|
59
|
+
- Optional span to be ended instead of current span {pull}1039[#1039]
|
|
60
|
+
- Config option `log_ecs_formatting` {pull}1053[#1053]
|
|
61
|
+
|
|
62
|
+
[float]
|
|
63
|
+
===== Fixed
|
|
64
|
+
- Fixed detecting Linux on Alpine for CPU/MEM metrics {pull}1057[#1057]
|
|
65
|
+
|
|
66
|
+
[[release-notes-4.3.0]]
|
|
67
|
+
==== 4.3.0
|
|
68
|
+
|
|
69
|
+
[float]
|
|
70
|
+
===== Added
|
|
71
|
+
|
|
72
|
+
- Add JVM memory metrics {pull}1040[#1040]
|
|
73
|
+
|
|
74
|
+
[[release-notes-4.2.0]]
|
|
75
|
+
==== 4.2.0
|
|
76
|
+
|
|
77
|
+
[float]
|
|
78
|
+
===== Added
|
|
79
|
+
|
|
80
|
+
- Add support for AWS Storage Table/CosmosDB {pull}999[#999]
|
|
81
|
+
|
|
82
|
+
[float]
|
|
83
|
+
===== Fixed
|
|
84
|
+
|
|
85
|
+
- Align HTTP span types/subtypes with spec {pull}1014[#1014]
|
|
86
|
+
- Passing a full URL as a path to `Net::HTTP` {pull}1029[#1029]
|
|
87
|
+
- Fix growing number of open file descriptors {pull}1033[#1033]
|
|
88
|
+
|
|
38
89
|
[[release-notes-4.1.0]]
|
|
39
90
|
==== 4.1.0
|
|
40
91
|
|
data/Gemfile
CHANGED
|
@@ -36,6 +36,8 @@ gem 'aws-sdk-dynamodb', require: nil
|
|
|
36
36
|
gem 'aws-sdk-s3', require: nil
|
|
37
37
|
gem 'aws-sdk-sqs', require: nil
|
|
38
38
|
gem 'aws-sdk-sns', require: nil
|
|
39
|
+
gem 'azure-storage-table', require: nil if RUBY_VERSION < '3.0'
|
|
40
|
+
gem 'ecs-logging', require: 'ecs_logging/logger'
|
|
39
41
|
gem 'elasticsearch', require: nil
|
|
40
42
|
gem 'fakeredis', require: nil
|
|
41
43
|
gem 'faraday', require: nil
|
|
@@ -60,10 +62,6 @@ gem 'sucker_punch', '~> 2.0', require: nil
|
|
|
60
62
|
gem 'yard', require: nil
|
|
61
63
|
gem 'yarjuf'
|
|
62
64
|
|
|
63
|
-
# See issue #6547 in the JRuby repo. When that bug is fixed,
|
|
64
|
-
# we can use the latest version of the i18n gem.
|
|
65
|
-
gem 'i18n', '< 1.8.8'
|
|
66
|
-
|
|
67
65
|
## Install Framework
|
|
68
66
|
GITHUB_REPOS = {
|
|
69
67
|
'grape' => 'ruby-grape/grape',
|
|
@@ -99,6 +97,9 @@ if frameworks_versions.key?('rails')
|
|
|
99
97
|
end
|
|
100
98
|
|
|
101
99
|
if RUBY_PLATFORM == 'java'
|
|
100
|
+
# See issue #6547 in the JRuby repo. It is fixed in JRuby 9.3
|
|
101
|
+
gem 'i18n', '< 1.8.8' if JRUBY_VERSION < '9.3'
|
|
102
|
+
|
|
102
103
|
case rails = frameworks_versions['rails']
|
|
103
104
|
when 'main'
|
|
104
105
|
gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter', glob: 'activerecord-jdbcsqlite3-adapter/*.gemspec'
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in the security of our products.
|
|
4
|
+
Our security policy can be found at [https://www.elastic.co/community/security](https://www.elastic.co/community/security).
|
|
5
|
+
|
|
6
|
+
## Reporting a Vulnerability
|
|
7
|
+
Please send security vulnerability reports to security@elastic.co.
|
data/docker-compose.yml
CHANGED
data/docs/configuration.asciidoc
CHANGED
|
@@ -240,7 +240,7 @@ NOTE: This feature requires APM Server and Kibana >= 7.3.
|
|
|
240
240
|
<<dynamic-configuration, image:./images/dynamic-config.svg[] >>
|
|
241
241
|
|
|
242
242
|
|============
|
|
243
|
-
| Environment | `Config` key | Default | Example
|
|
243
|
+
| Environment | `Config` key | Default | Example
|
|
244
244
|
| `ELASTIC_APM_CAPTURE_BODY` | `capture_body` | `"off"` | `"all"`
|
|
245
245
|
|============
|
|
246
246
|
|
|
@@ -502,7 +502,31 @@ Use this option to ignore certain URL patterns such as healthchecks or admin sec
|
|
|
502
502
|
| `ELASTIC_APM_INSTRUMENTED_RAKE_TASKS` | `instrumented_rake_tasks` | `[]` | `['my_task']`
|
|
503
503
|
|============
|
|
504
504
|
|
|
505
|
-
Elastic APM can instrument your Rake tasks.
|
|
505
|
+
Elastic APM can instrument your Rake tasks. This is an opt-in field, as they are used are for a multitude of things.
|
|
506
|
+
|
|
507
|
+
[float]
|
|
508
|
+
[[config-log-ecs-formatting]]
|
|
509
|
+
==== `log_ecs_formatting`
|
|
510
|
+
|
|
511
|
+
[options="header"]
|
|
512
|
+
|============
|
|
513
|
+
| Environment | `Config` key | Default
|
|
514
|
+
| `ELASTIC_APM_LOG_ECS_FORMATTING` | `log_ecs_formatting` | `off`
|
|
515
|
+
|============
|
|
516
|
+
|
|
517
|
+
This is an experimental option that configures the agent to use the logger from the `ecs-logging` gem. The two
|
|
518
|
+
valid options are `off` and `override`.
|
|
519
|
+
|
|
520
|
+
Setting this option to `override` will set the agent logger to a `EcsLogging::Logger` instance and all logged output
|
|
521
|
+
will be in ECS-compatible json.
|
|
522
|
+
|
|
523
|
+
The `ecs-logging` gem must be installed before the agent is started. If `log_ecs_formatting` is set to `override`,
|
|
524
|
+
the agent will attempt to require the gem and if it cannot be loaded, it will fall back to using the standard Ruby
|
|
525
|
+
`::Logger` and log the load error.
|
|
526
|
+
|
|
527
|
+
Note that if you're using Rails, the agent will ignore this option and use the Rails logger. If you want to use a
|
|
528
|
+
`EcsLogging::Logger` when using Rails, set the agent's logger config option explicitly to a `EcsLogging::Logger`
|
|
529
|
+
instance.
|
|
506
530
|
|
|
507
531
|
[float]
|
|
508
532
|
[[config-log-level]]
|
data/docs/metrics.asciidoc
CHANGED
|
@@ -141,3 +141,95 @@ The total time spent in garbage collection.
|
|
|
141
141
|
|
|
142
142
|
**NB:** You need to enable Ruby's GC Profiler for this to get reported.
|
|
143
143
|
You can do this at any time when your application boots by calling `GC::Profiler.enable`.
|
|
144
|
+
|
|
145
|
+
[float]
|
|
146
|
+
[[metrics-jvm-metrics]]
|
|
147
|
+
=== JVM Metrics
|
|
148
|
+
|
|
149
|
+
The following metrics are available when using JRuby. They use the ruby java API to gather metrics via MXBean.
|
|
150
|
+
|
|
151
|
+
[float]
|
|
152
|
+
[[metric-jvm.memory.heap.used]]
|
|
153
|
+
==== `jvm.memory.heap.used`
|
|
154
|
+
|
|
155
|
+
* *Type:* Long
|
|
156
|
+
* *Format:* Bytes
|
|
157
|
+
|
|
158
|
+
The amount of used heap memory in bytes.
|
|
159
|
+
|
|
160
|
+
[float]
|
|
161
|
+
[[metric-jvm.memory.heap.committed]]
|
|
162
|
+
==== `jvm.memory.heap.committed`
|
|
163
|
+
|
|
164
|
+
* *Type:* Long
|
|
165
|
+
* *Format:* Bytes
|
|
166
|
+
|
|
167
|
+
The amount of heap memory in bytes that is committed for the Java virtual machine to use. This amount of memory is
|
|
168
|
+
guaranteed for the Java virtual machine to use.
|
|
169
|
+
|
|
170
|
+
[float]
|
|
171
|
+
[[metric-jvm.memory.heap.max]]
|
|
172
|
+
==== `jvm.memory.heap.max`
|
|
173
|
+
|
|
174
|
+
* *Type:* Long
|
|
175
|
+
* *Format:* Bytes
|
|
176
|
+
|
|
177
|
+
The amount of heap memory in bytes that is committed for the Java virtual machine to use. This amount of memory is
|
|
178
|
+
guaranteed for the Java virtual machine to use.
|
|
179
|
+
|
|
180
|
+
[float]
|
|
181
|
+
[[metric-jvm.memory.non_heap.used]]
|
|
182
|
+
==== `jvm.memory.non_heap.used`
|
|
183
|
+
|
|
184
|
+
* *Type:* Long
|
|
185
|
+
* *Format:* Bytes
|
|
186
|
+
|
|
187
|
+
The amount of used non-heap memory in bytes.
|
|
188
|
+
|
|
189
|
+
[float]
|
|
190
|
+
[[metric-jvm.memory.non_heap.committed]]
|
|
191
|
+
==== `jvm.memory.non_heap.committed`
|
|
192
|
+
|
|
193
|
+
* *Type:* Long
|
|
194
|
+
* *Format:* Bytes
|
|
195
|
+
|
|
196
|
+
The amount of non-heap memory in bytes that is committed for the Java virtual machine to use. This amount of memory is
|
|
197
|
+
guaranteed for the Java virtual machine to use.
|
|
198
|
+
|
|
199
|
+
[float]
|
|
200
|
+
[[metric-jvm.memory.non_heap.max]]
|
|
201
|
+
==== `jvm.memory.non_heap.max`
|
|
202
|
+
|
|
203
|
+
* *Type:* Long
|
|
204
|
+
* *Format:* Bytes
|
|
205
|
+
|
|
206
|
+
The maximum amount of non-heap memory in bytes that can be used for memory management. If the maximum memory size is
|
|
207
|
+
undefined, the value is -1.
|
|
208
|
+
|
|
209
|
+
[float]
|
|
210
|
+
[[metric-jvm.memory.heap.pool.used]]
|
|
211
|
+
==== `jvm.memory.heap.pool.used`
|
|
212
|
+
|
|
213
|
+
* *Type:* Long
|
|
214
|
+
* *Format:* Bytes
|
|
215
|
+
|
|
216
|
+
The amount of used memory in bytes of the memory pool.
|
|
217
|
+
|
|
218
|
+
[float]
|
|
219
|
+
[[metric-jvm.memory.heap.pool.committed]]
|
|
220
|
+
==== `jvm.memory.heap.pool.committed`
|
|
221
|
+
|
|
222
|
+
* *Type:* Long
|
|
223
|
+
* *Format:* Bytes
|
|
224
|
+
|
|
225
|
+
The amount of memory in bytes that is committed for the memory pool. This amount of memory is guaranteed for this
|
|
226
|
+
specific pool.
|
|
227
|
+
|
|
228
|
+
[float]
|
|
229
|
+
[[metric-jvm.memory.heap.pool.max]]
|
|
230
|
+
==== `jvm.memory.heap.pool.max`
|
|
231
|
+
|
|
232
|
+
* *Type:* Long
|
|
233
|
+
* *Format:* Bytes
|
|
234
|
+
|
|
235
|
+
The maximum amount of memory in bytes that can be used for the memory pool.
|
data/elastic-apm.gemspec
CHANGED
|
@@ -20,15 +20,15 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
20
20
|
require 'elastic_apm/version'
|
|
21
21
|
|
|
22
22
|
Gem::Specification.new do |spec|
|
|
23
|
-
spec.name
|
|
24
|
-
spec.version
|
|
25
|
-
spec.authors
|
|
26
|
-
spec.email
|
|
23
|
+
spec.name = 'elastic-apm'
|
|
24
|
+
spec.version = ElasticAPM::VERSION
|
|
25
|
+
spec.authors = ['Mikkel Malmberg']
|
|
26
|
+
spec.email = ['mikkel@elastic.co']
|
|
27
27
|
|
|
28
|
-
spec.summary
|
|
29
|
-
spec.homepage
|
|
30
|
-
spec.metadata
|
|
31
|
-
spec.license
|
|
28
|
+
spec.summary = 'The official Elastic APM agent for Ruby'
|
|
29
|
+
spec.homepage = 'https://github.com/elastic/apm-agent-ruby'
|
|
30
|
+
spec.metadata = { 'source_code_uri' => 'https://github.com/elastic/apm-agent-ruby' }
|
|
31
|
+
spec.license = 'Apache-2.0'
|
|
32
32
|
spec.required_ruby_version = ">= 2.3.0"
|
|
33
33
|
|
|
34
34
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
data/lib/elastic_apm/agent.rb
CHANGED
|
@@ -211,8 +211,8 @@ module ElasticAPM
|
|
|
211
211
|
end
|
|
212
212
|
# rubocop:enable Metrics/ParameterLists
|
|
213
213
|
|
|
214
|
-
def end_span
|
|
215
|
-
instrumenter.end_span
|
|
214
|
+
def end_span(span = nil)
|
|
215
|
+
instrumenter.end_span(span)
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
def set_label(key, value)
|
|
@@ -280,8 +280,8 @@ module ElasticAPM
|
|
|
280
280
|
def detect_forking!
|
|
281
281
|
return if @pid == Process.pid
|
|
282
282
|
|
|
283
|
-
config.logger.debug
|
|
284
|
-
restarting threads in process [PID:#{Process.pid}]"
|
|
283
|
+
config.logger.debug(
|
|
284
|
+
"Forked process detected, restarting threads in process [PID:#{Process.pid}]")
|
|
285
285
|
|
|
286
286
|
central_config.handle_forking!
|
|
287
287
|
transport.handle_forking!
|
|
@@ -119,7 +119,7 @@ module ElasticAPM
|
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
if resp.status == 304
|
|
122
|
-
|
|
122
|
+
debug 'Received 304 Not Modified'
|
|
123
123
|
else
|
|
124
124
|
if resp.body && !resp.body.empty?
|
|
125
125
|
update = JSON.parse(resp.body.to_s)
|
|
@@ -169,7 +169,7 @@ module ElasticAPM
|
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
def headers
|
|
172
|
-
{ '
|
|
172
|
+
{ 'If-None-Match': @etag }
|
|
173
173
|
end
|
|
174
174
|
|
|
175
175
|
def schedule_next_fetch(resp = nil)
|
data/lib/elastic_apm/config.rb
CHANGED
|
@@ -70,6 +70,7 @@ module ElasticAPM
|
|
|
70
70
|
option :ignore_url_patterns, type: :list, default: [], converter: RegexpList.new
|
|
71
71
|
option :instrument, type: :bool, default: true
|
|
72
72
|
option :instrumented_rake_tasks, type: :list, default: []
|
|
73
|
+
option :log_ecs_formatting, type: :string, default: 'off'
|
|
73
74
|
option :log_level, type: :int, default: Logger::INFO, converter: LogLevelMap.new
|
|
74
75
|
option :log_path, type: :string
|
|
75
76
|
option :metrics_interval, type: :int, default: '30s', converter: Duration.new
|
|
@@ -133,6 +134,7 @@ module ElasticAPM
|
|
|
133
134
|
def available_instrumentations
|
|
134
135
|
%w[
|
|
135
136
|
action_dispatch
|
|
137
|
+
azure_storage_table
|
|
136
138
|
delayed_job
|
|
137
139
|
dynamo_db
|
|
138
140
|
elasticsearch
|
|
@@ -245,11 +247,29 @@ module ElasticAPM
|
|
|
245
247
|
end
|
|
246
248
|
|
|
247
249
|
def build_logger
|
|
250
|
+
if self.log_ecs_formatting == 'override'
|
|
251
|
+
begin
|
|
252
|
+
return build_ecs_logger
|
|
253
|
+
rescue LoadError
|
|
254
|
+
logger.info "Attempted to use EcsLogging::Logger but the gem couldn't be " \
|
|
255
|
+
"loaded so a ::Logger was created instead. Check if you have the `ecs-logging` " \
|
|
256
|
+
"gem installed and attempt to start the agent again."
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
248
260
|
Logger.new(log_path == '-' ? $stdout : log_path).tap do |logger|
|
|
249
261
|
logger.level = log_level
|
|
250
262
|
end
|
|
251
263
|
end
|
|
252
264
|
|
|
265
|
+
def build_ecs_logger
|
|
266
|
+
require 'ecs_logging/logger'
|
|
267
|
+
|
|
268
|
+
::EcsLogging::Logger.new(log_path == '-' ? $stdout : log_path).tap do |logger|
|
|
269
|
+
logger.level = log_level
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
253
273
|
def app_type?(app)
|
|
254
274
|
if defined?(::Rails::Application) && app.is_a?(::Rails::Application)
|
|
255
275
|
return :rails
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
#
|
|
18
|
+
# frozen_string_literal: true
|
|
19
|
+
|
|
20
|
+
module ElasticAPM
|
|
21
|
+
# An interface for creating simple, value holding objects that correspond to
|
|
22
|
+
# object fields in the API.
|
|
23
|
+
#
|
|
24
|
+
# Example:
|
|
25
|
+
# class MyThing
|
|
26
|
+
# include Fields
|
|
27
|
+
# field :name
|
|
28
|
+
# field :address, default: 'There'
|
|
29
|
+
# end
|
|
30
|
+
#
|
|
31
|
+
# MyThing.new(name: 'AJ').to_h
|
|
32
|
+
# # => { name: 'AJ' }
|
|
33
|
+
# MyThing.new().empty?
|
|
34
|
+
# # => true
|
|
35
|
+
module Fields
|
|
36
|
+
class Field
|
|
37
|
+
def initialize(key, default: nil)
|
|
38
|
+
@key = key
|
|
39
|
+
@default = default
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
attr_reader :key, :default
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module InstanceMethods
|
|
46
|
+
def initialize(**attrs)
|
|
47
|
+
schema.each do |key, field|
|
|
48
|
+
send(:"#{key}=", field.default)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
attrs.each do |key, value|
|
|
52
|
+
send(:"#{key}=", value)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
super()
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def empty?
|
|
59
|
+
self.class.schema.each do |key, field|
|
|
60
|
+
next if send(key).nil?
|
|
61
|
+
return false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
true
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def to_h
|
|
68
|
+
schema.each_with_object({}) do |(key, field), hsh|
|
|
69
|
+
hsh[key] = send(key)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def schema
|
|
76
|
+
self.class.schema
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
module ClassMethods
|
|
81
|
+
def field(key, default: nil)
|
|
82
|
+
field = Field.new(key, default: default)
|
|
83
|
+
schema[key] = field
|
|
84
|
+
|
|
85
|
+
attr_accessor(key)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
attr_reader :schema
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.included(cls)
|
|
92
|
+
cls.extend(ClassMethods)
|
|
93
|
+
cls.include(InstanceMethods)
|
|
94
|
+
|
|
95
|
+
cls.instance_variable_set(:@schema, {})
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -179,7 +179,8 @@ module ElasticAPM
|
|
|
179
179
|
context: nil,
|
|
180
180
|
trace_context: nil,
|
|
181
181
|
parent: nil,
|
|
182
|
-
sync: nil
|
|
182
|
+
sync: nil,
|
|
183
|
+
exit_span: nil
|
|
183
184
|
)
|
|
184
185
|
|
|
185
186
|
transaction =
|
|
@@ -197,6 +198,15 @@ module ElasticAPM
|
|
|
197
198
|
|
|
198
199
|
parent ||= (current_span || current_transaction)
|
|
199
200
|
|
|
201
|
+
# To not mess with breakdown metric stats, exit spans MUST not add
|
|
202
|
+
# sub-spans unless they share the same type and subtype.
|
|
203
|
+
if parent && parent.is_a?(Span) && parent.exit_span?
|
|
204
|
+
if parent.type != type || parent.subtype != subtype
|
|
205
|
+
debug "Skipping new span '#{name}' as its parent is an exit_span"
|
|
206
|
+
return
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
200
210
|
span = Span.new(
|
|
201
211
|
name: name,
|
|
202
212
|
subtype: subtype,
|
|
@@ -207,7 +217,8 @@ module ElasticAPM
|
|
|
207
217
|
type: type,
|
|
208
218
|
context: context,
|
|
209
219
|
stacktrace_builder: stacktrace_builder,
|
|
210
|
-
sync: sync
|
|
220
|
+
sync: sync,
|
|
221
|
+
exit_span: exit_span
|
|
211
222
|
)
|
|
212
223
|
|
|
213
224
|
if backtrace && transaction.span_frames_min_duration
|
|
@@ -222,8 +233,14 @@ module ElasticAPM
|
|
|
222
233
|
# rubocop:enable Metrics/CyclomaticComplexity
|
|
223
234
|
# rubocop:enable Metrics/PerceivedComplexity
|
|
224
235
|
|
|
225
|
-
def end_span
|
|
226
|
-
|
|
236
|
+
def end_span(span = nil)
|
|
237
|
+
if span
|
|
238
|
+
current_spans.delete(span)
|
|
239
|
+
else
|
|
240
|
+
span = current_spans.pop
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
return unless span
|
|
227
244
|
|
|
228
245
|
span.done
|
|
229
246
|
|
|
@@ -273,24 +290,9 @@ module ElasticAPM
|
|
|
273
290
|
'transaction.type': transaction.type
|
|
274
291
|
}
|
|
275
292
|
|
|
276
|
-
@metrics.get(:transaction).timer(
|
|
277
|
-
:'transaction.duration.sum.us',
|
|
278
|
-
tags: tags, reset_on_collect: true
|
|
279
|
-
).update(transaction.duration)
|
|
280
|
-
|
|
281
|
-
@metrics.get(:transaction).counter(
|
|
282
|
-
:'transaction.duration.count',
|
|
283
|
-
tags: tags, reset_on_collect: true
|
|
284
|
-
).inc!
|
|
285
|
-
|
|
286
293
|
return unless transaction.sampled?
|
|
287
294
|
return unless transaction.breakdown_metrics
|
|
288
295
|
|
|
289
|
-
@metrics.get(:breakdown).counter(
|
|
290
|
-
:'transaction.breakdown.count',
|
|
291
|
-
tags: tags, reset_on_collect: true
|
|
292
|
-
).inc!
|
|
293
|
-
|
|
294
296
|
span_tags = tags.merge('span.type': 'app')
|
|
295
297
|
|
|
296
298
|
@metrics.get(:breakdown).timer(
|
|
@@ -49,7 +49,7 @@ module ElasticAPM
|
|
|
49
49
|
)
|
|
50
50
|
@language = Language.new(name: 'ruby', version: RUBY_VERSION)
|
|
51
51
|
@runtime = lookup_runtime
|
|
52
|
-
@version = @config.service_version
|
|
52
|
+
@version = @config.service_version
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
attr_reader :name, :node_name, :environment, :agent, :framework,
|