elastic-apm 3.15.1 → 4.2.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/.jenkins_exclude.yml +13 -0
- data/.ci/.jenkins_ruby.yml +0 -1
- data/.ci/Jenkinsfile +1 -0
- data/.github/dependabot.yml +16 -0
- data/.rubocop.yml +0 -7
- data/CHANGELOG.asciidoc +77 -4
- data/Gemfile +4 -1
- data/README.md +12 -0
- data/SECURITY.md +7 -0
- data/bench/report.rb +1 -1
- data/bin/run-bdd +17 -0
- data/bin/run-tests +1 -1
- data/docker-compose.yml +1 -1
- data/docs/configuration.asciidoc +62 -147
- data/docs/release-notes.asciidoc +1 -0
- data/docs/upgrading.asciidoc +0 -27
- data/lib/elastic_apm.rb +12 -1
- data/lib/elastic_apm/agent.rb +7 -3
- data/lib/elastic_apm/central_config.rb +8 -7
- data/lib/elastic_apm/config.rb +2 -88
- data/lib/elastic_apm/config/regexp_list.rb +1 -1
- data/lib/elastic_apm/config/wildcard_pattern_list.rb +1 -1
- data/lib/elastic_apm/context/response.rb +1 -3
- data/lib/elastic_apm/fields.rb +88 -0
- data/lib/elastic_apm/grpc.rb +2 -4
- data/lib/elastic_apm/instrumenter.rb +1 -1
- data/lib/elastic_apm/metadata/cloud_info.rb +32 -5
- data/lib/elastic_apm/metadata/system_info.rb +14 -4
- data/lib/elastic_apm/metrics/cpu_mem_set.rb +1 -1
- data/lib/elastic_apm/normalizers.rb +2 -2
- data/lib/elastic_apm/normalizers/rails/active_record.rb +3 -3
- data/lib/elastic_apm/opentracing.rb +3 -2
- data/lib/elastic_apm/span.rb +26 -1
- data/lib/elastic_apm/span/context.rb +2 -1
- data/lib/elastic_apm/span/context/destination.rb +53 -40
- data/lib/elastic_apm/span_helpers.rb +6 -8
- data/lib/elastic_apm/spies.rb +20 -0
- data/lib/elastic_apm/spies/action_dispatch.rb +10 -9
- data/lib/elastic_apm/spies/azure_storage_table.rb +148 -0
- data/lib/elastic_apm/spies/dynamo_db.rb +12 -12
- data/lib/elastic_apm/spies/elasticsearch.rb +32 -29
- data/lib/elastic_apm/spies/faraday.rb +83 -63
- data/lib/elastic_apm/spies/http.rb +33 -34
- data/lib/elastic_apm/spies/mongo.rb +5 -3
- data/lib/elastic_apm/spies/net_http.rb +59 -56
- data/lib/elastic_apm/spies/rake.rb +28 -26
- data/lib/elastic_apm/spies/redis.rb +11 -10
- data/lib/elastic_apm/spies/resque.rb +18 -21
- data/lib/elastic_apm/spies/s3.rb +14 -15
- data/lib/elastic_apm/spies/sequel.rb +42 -48
- data/lib/elastic_apm/spies/sidekiq.rb +13 -15
- data/lib/elastic_apm/spies/sinatra.rb +20 -21
- data/lib/elastic_apm/spies/sns.rb +39 -44
- data/lib/elastic_apm/spies/sqs.rb +21 -31
- data/lib/elastic_apm/spies/tilt.rb +10 -9
- data/lib/elastic_apm/sql/tokenizer.rb +21 -5
- data/lib/elastic_apm/stacktrace_builder.rb +3 -1
- data/lib/elastic_apm/subscriber.rb +1 -0
- data/lib/elastic_apm/trace_context.rb +5 -13
- data/lib/elastic_apm/trace_context/traceparent.rb +5 -6
- data/lib/elastic_apm/transport/connection.rb +1 -1
- data/lib/elastic_apm/transport/connection/http.rb +4 -2
- data/lib/elastic_apm/transport/connection/proxy_pipe.rb +1 -2
- data/lib/elastic_apm/transport/filters/hash_sanitizer.rb +5 -23
- data/lib/elastic_apm/transport/serializers/metadata_serializer.rb +3 -2
- data/lib/elastic_apm/transport/serializers/metricset_serializer.rb +2 -2
- data/lib/elastic_apm/transport/serializers/span_serializer.rb +12 -12
- data/lib/elastic_apm/transport/user_agent.rb +3 -2
- data/lib/elastic_apm/transport/worker.rb +1 -1
- data/lib/elastic_apm/util/deep_dup.rb +1 -1
- data/lib/elastic_apm/version.rb +1 -1
- metadata +12 -9
- data/lib/elastic_apm/sql.rb +0 -36
- data/lib/elastic_apm/sql_summarizer.rb +0 -53
data/docs/release-notes.asciidoc
CHANGED
data/docs/upgrading.asciidoc
CHANGED
@@ -16,30 +16,3 @@ We love all our products, but sometimes we must say goodbye to a release so that
|
|
16
16
|
forward on future development and innovation.
|
17
17
|
Our https://www.elastic.co/support/eol[End of life policy] defines how long a given release is considered supported,
|
18
18
|
as well as how long a release is considered still in active development or maintenance.
|
19
|
-
The table below is a simplified description of this policy.
|
20
|
-
|
21
|
-
[options="header"]
|
22
|
-
|====
|
23
|
-
|Agent version |EOL Date |Maintained until
|
24
|
-
|3.5.x |2021-07-17 | 3.6
|
25
|
-
|3.4.x |2021-07-10 | 3.5
|
26
|
-
|3.3.x |2021-06-04 | 3.4
|
27
|
-
|3.2.x |2021-05-19 | 3.3
|
28
|
-
|3.1.x |2021-04-21 | 3.2
|
29
|
-
|3.0.x |2021-04-08 | 3.1
|
30
|
-
|2.12.x |2021-04-01 |4.0
|
31
|
-
|2.11.x |2021-03-23 |2.12
|
32
|
-
|2.10.x |2021-03-03 |2.11
|
33
|
-
|2.9.x |2020-12-25 |2.10
|
34
|
-
|2.8.x |2020-11-20 |2.9
|
35
|
-
|2.7.x |2020-11-07 |2.8
|
36
|
-
|2.6.x |2020-09-19 |2.7
|
37
|
-
|2.5.x |2020-09-01 |2.6
|
38
|
-
|2.4.x |2020-08-27 |2.5
|
39
|
-
|2.3.x |2020-07-29 |2.4
|
40
|
-
|2.2.x |2020-07-22 |2.3
|
41
|
-
|2.1.x |2020-06-04 |2.2
|
42
|
-
|2.0.x |2020-05-14 |2.1
|
43
|
-
|1.1.x |2020-03-07 |3.0
|
44
|
-
|1.0.x |2019-12-29 |1.1
|
45
|
-
|====
|
data/lib/elastic_apm.rb
CHANGED
@@ -32,6 +32,7 @@ require 'elastic_apm/internal_error'
|
|
32
32
|
require 'elastic_apm/logging'
|
33
33
|
|
34
34
|
# Core
|
35
|
+
require 'elastic_apm/fields'
|
35
36
|
require 'elastic_apm/agent'
|
36
37
|
require 'elastic_apm/config'
|
37
38
|
require 'elastic_apm/context'
|
@@ -380,6 +381,16 @@ module ElasticAPM
|
|
380
381
|
agent&.set_user(user)
|
381
382
|
end
|
382
383
|
|
384
|
+
# Set destination fields on the current span
|
385
|
+
#
|
386
|
+
# @param address [String] Destination address
|
387
|
+
# @param address [String] Destination address
|
388
|
+
# @param address [Hash] Destination service
|
389
|
+
# @param address [Hash] Destination cloud
|
390
|
+
def set_destination(address: nil, port: nil, service: nil, cloud: nil)
|
391
|
+
agent&.set_destination(address: address, port: port, service: service, cloud: cloud)
|
392
|
+
end
|
393
|
+
|
383
394
|
# Provide a filter to transform payloads before sending them off
|
384
395
|
#
|
385
396
|
# @param key [Symbol] Unique filter key
|
@@ -387,7 +398,7 @@ module ElasticAPM
|
|
387
398
|
# @yield [Hash] A filter. Used if provided. Otherwise using `callback`
|
388
399
|
# @return [Bool] true
|
389
400
|
def add_filter(key, callback = nil, &block)
|
390
|
-
if callback.nil? && !
|
401
|
+
if callback.nil? && !block
|
391
402
|
raise ArgumentError, '#add_filter needs either `callback\' or a block'
|
392
403
|
end
|
393
404
|
|
data/lib/elastic_apm/agent.rb
CHANGED
@@ -127,7 +127,7 @@ module ElasticAPM
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def stop
|
130
|
-
|
130
|
+
info 'Stopping agent'
|
131
131
|
|
132
132
|
central_config.stop
|
133
133
|
metrics.stop
|
@@ -227,6 +227,10 @@ module ElasticAPM
|
|
227
227
|
instrumenter.set_user(user)
|
228
228
|
end
|
229
229
|
|
230
|
+
def set_destination(address: nil, port: nil, service: nil, cloud: nil)
|
231
|
+
current_span&.set_destination(address: nil, port: nil, service: nil, cloud: nil)
|
232
|
+
end
|
233
|
+
|
230
234
|
def build_context(rack_env:, for_type:)
|
231
235
|
@context_builder.build(rack_env: rack_env, for_type: for_type)
|
232
236
|
end
|
@@ -276,8 +280,8 @@ module ElasticAPM
|
|
276
280
|
def detect_forking!
|
277
281
|
return if @pid == Process.pid
|
278
282
|
|
279
|
-
config.logger.debug
|
280
|
-
restarting threads in process [PID:#{Process.pid}]"
|
283
|
+
config.logger.debug(
|
284
|
+
"Forked process detected, restarting threads in process [PID:#{Process.pid}]")
|
281
285
|
|
282
286
|
central_config.handle_forking!
|
283
287
|
transport.handle_forking!
|
@@ -66,9 +66,9 @@ module ElasticAPM
|
|
66
66
|
def fetch_and_apply_config
|
67
67
|
@promise =
|
68
68
|
Concurrent::Promise
|
69
|
-
.execute
|
70
|
-
.on_success(
|
71
|
-
.rescue(
|
69
|
+
.execute { fetch_config }
|
70
|
+
.on_success { |resp| handle_success(resp) }
|
71
|
+
.rescue { |err| handle_error(err) }
|
72
72
|
end
|
73
73
|
|
74
74
|
def fetch_config
|
@@ -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)
|
@@ -164,11 +164,12 @@ module ElasticAPM
|
|
164
164
|
@server_url ||=
|
165
165
|
config.server_url +
|
166
166
|
'/config/v1/agents' \
|
167
|
-
"?service.name=#{CGI.escape(config.service_name)}"
|
167
|
+
"?service.name=#{CGI.escape(config.service_name)}" \
|
168
|
+
"&service.environment=#{CGI.escape(config.environment || '')}"
|
168
169
|
end
|
169
170
|
|
170
171
|
def headers
|
171
|
-
{ '
|
172
|
+
{ 'If-None-Match': @etag }
|
172
173
|
end
|
173
174
|
|
174
175
|
def schedule_next_fetch(resp = nil)
|
@@ -182,7 +183,7 @@ module ElasticAPM
|
|
182
183
|
|
183
184
|
@scheduled_task =
|
184
185
|
Concurrent::ScheduledTask
|
185
|
-
.execute(seconds
|
186
|
+
.execute(seconds) { fetch_and_apply_config }
|
186
187
|
end
|
187
188
|
end
|
188
189
|
end
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -30,14 +30,8 @@ module ElasticAPM
|
|
30
30
|
class Config
|
31
31
|
extend Options
|
32
32
|
|
33
|
-
DEPRECATED_OPTIONS = %i[].freeze
|
34
|
-
|
35
|
-
# DEPRECATED: To align with other agents, change on next major bump to:
|
36
|
-
# "password, passwd, pwd, secret, *key, *token*, *session*, *credit*,
|
37
|
-
# *card*, authorization, set-cookie"
|
38
33
|
SANITIZE_FIELD_NAMES_DEFAULT =
|
39
|
-
%w[
|
40
|
-
*credit* *card* *authorization* *set-cookie*].freeze
|
34
|
+
%w[password passwd pwd secret *key *token* *session* *credit* *card* authorization set-cookie].freeze
|
41
35
|
|
42
36
|
# rubocop:disable Layout/LineLength, Layout/ExtraSpacing
|
43
37
|
option :config_file, type: :string, default: 'config/elastic_apm.yml'
|
@@ -101,7 +95,6 @@ module ElasticAPM
|
|
101
95
|
option :transaction_max_spans, type: :int, default: 500
|
102
96
|
option :transaction_sample_rate, type: :float, default: 1.0, converter: RoundFloat.new
|
103
97
|
option :use_elastic_traceparent_header, type: :bool, default: true
|
104
|
-
option :use_legacy_sql_parser, type: :bool, default: false
|
105
98
|
option :verify_server_cert, type: :bool, default: true
|
106
99
|
|
107
100
|
# rubocop:enable Layout/LineLength, Layout/ExtraSpacing
|
@@ -140,6 +133,7 @@ module ElasticAPM
|
|
140
133
|
def available_instrumentations
|
141
134
|
%w[
|
142
135
|
action_dispatch
|
136
|
+
azure_storage_table
|
143
137
|
delayed_job
|
144
138
|
dynamo_db
|
145
139
|
elasticsearch
|
@@ -168,11 +162,6 @@ module ElasticAPM
|
|
168
162
|
available_instrumentations - disable_instrumentations
|
169
163
|
end
|
170
164
|
|
171
|
-
def method_missing(name, *args)
|
172
|
-
return super unless DEPRECATED_OPTIONS.include?(name)
|
173
|
-
warn "The option `#{name}' has been removed."
|
174
|
-
end
|
175
|
-
|
176
165
|
def replace_options(new_options)
|
177
166
|
return if new_options.nil? || new_options.empty?
|
178
167
|
options_copy = @options.dup
|
@@ -201,15 +190,6 @@ module ElasticAPM
|
|
201
190
|
metrics_interval > 0
|
202
191
|
end
|
203
192
|
|
204
|
-
# DEPRECATED: Remove this in next major version
|
205
|
-
def sanitize_field_names=(value)
|
206
|
-
list = WildcardPatternList.new.call(value)
|
207
|
-
defaults = WildcardPatternList.new.call(SANITIZE_FIELD_NAMES_DEFAULT)
|
208
|
-
# use regex pattern for comparisons
|
209
|
-
get(:sanitize_field_names).value =
|
210
|
-
defaults.concat(list).uniq(&:pattern)
|
211
|
-
end
|
212
|
-
|
213
193
|
def span_frames_min_duration?
|
214
194
|
span_frames_min_duration != 0
|
215
195
|
end
|
@@ -248,72 +228,6 @@ module ElasticAPM
|
|
248
228
|
super.split.first + '>'
|
249
229
|
end
|
250
230
|
|
251
|
-
# Deprecations
|
252
|
-
|
253
|
-
def default_tags=(value)
|
254
|
-
warn '[DEPRECATED] The option default_tags has been renamed to ' \
|
255
|
-
'default_labels.'
|
256
|
-
self.default_labels = value
|
257
|
-
end
|
258
|
-
|
259
|
-
def ignore_url_patterns=(value)
|
260
|
-
unless value == self.class.schema[:ignore_url_patterns][:default]
|
261
|
-
warn '[DEPRECATED] The option ignore_url_patterns is being removed. ' \
|
262
|
-
'Consider using transaction_ignore_urls instead.'
|
263
|
-
end
|
264
|
-
|
265
|
-
set(:ignore_url_patterns, value)
|
266
|
-
end
|
267
|
-
|
268
|
-
def custom_key_filters=(value)
|
269
|
-
unless value == self.class.schema[:custom_key_filters][:default]
|
270
|
-
warn '[DEPRECATED] The option custom_key_filters is being removed. ' \
|
271
|
-
'See sanitize_field_names for an alternative.'
|
272
|
-
end
|
273
|
-
|
274
|
-
set(:custom_key_filters, value)
|
275
|
-
end
|
276
|
-
|
277
|
-
def disabled_instrumentations
|
278
|
-
disable_instrumentations
|
279
|
-
end
|
280
|
-
|
281
|
-
def active
|
282
|
-
enabled
|
283
|
-
end
|
284
|
-
alias active? active
|
285
|
-
|
286
|
-
def server_ca_cert
|
287
|
-
server_ca_cert_file
|
288
|
-
end
|
289
|
-
|
290
|
-
def disabled_instrumentations=(value)
|
291
|
-
warn '[DEPRECATED] The option disabled_instrumentations has been ' \
|
292
|
-
'renamed to disable_instrumentations to align with other agents.'
|
293
|
-
self.disable_instrumentations = value
|
294
|
-
end
|
295
|
-
|
296
|
-
def use_experimental_sql_parser=(_value)
|
297
|
-
warn '[DEPRECATED] The new SQL parser is now the default. To use the ' \
|
298
|
-
'old one, use use_legacy_sql_parser and please report why you ' \
|
299
|
-
'wish to do so.'
|
300
|
-
end
|
301
|
-
|
302
|
-
def active=(value)
|
303
|
-
warn '[DEPRECATED] The option active has been renamed to enabled ' \
|
304
|
-
'to align with other agents and with the remote config.'
|
305
|
-
self.enabled = value
|
306
|
-
end
|
307
|
-
|
308
|
-
def server_ca_cert=(value)
|
309
|
-
unless value == self.class.schema[:server_ca_cert_file][:default]
|
310
|
-
warn '[DEPRECATED] The option server_ca_cert has been ' \
|
311
|
-
'renamed to server_ca_cert_file to align with other agents.'
|
312
|
-
end
|
313
|
-
|
314
|
-
self.server_ca_cert_file = value
|
315
|
-
end
|
316
|
-
|
317
231
|
private
|
318
232
|
|
319
233
|
def load_config_file
|
@@ -0,0 +1,88 @@
|
|
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, optional: true
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# MyThing.new(name: 'AJ').to_h
|
32
|
+
# # => { name: 'AJ' }
|
33
|
+
# MyThing.new().empty?
|
34
|
+
# # => true
|
35
|
+
module Fields
|
36
|
+
module InstanceMethods
|
37
|
+
def initialize(**attrs)
|
38
|
+
attrs.each do |key, value|
|
39
|
+
self.send(:"#{key}=", value)
|
40
|
+
end
|
41
|
+
|
42
|
+
super()
|
43
|
+
end
|
44
|
+
|
45
|
+
def empty?
|
46
|
+
self.class.fields.each do |key|
|
47
|
+
next if send(key)
|
48
|
+
next if optionals.include?(key)
|
49
|
+
|
50
|
+
return true
|
51
|
+
end
|
52
|
+
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_h
|
57
|
+
self.class.fields.each_with_object({}) do |key, fields|
|
58
|
+
fields[key] = send(key)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def optionals
|
65
|
+
self.class.optionals
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module ClassMethods
|
70
|
+
def field(key, optional: false)
|
71
|
+
attr_accessor(key)
|
72
|
+
|
73
|
+
fields.push(key)
|
74
|
+
optionals.push(key) if optional
|
75
|
+
end
|
76
|
+
|
77
|
+
attr_reader :fields, :optionals
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.included(cls)
|
81
|
+
cls.extend(ClassMethods)
|
82
|
+
cls.include(InstanceMethods)
|
83
|
+
|
84
|
+
cls.instance_variable_set(:@fields, [])
|
85
|
+
cls.instance_variable_set(:@optionals, [])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/elastic_apm/grpc.rb
CHANGED
@@ -50,11 +50,9 @@ module ElasticAPM
|
|
50
50
|
|
51
51
|
split_peer = URI.split(peer)
|
52
52
|
destination = ElasticAPM::Span::Context::Destination.new(
|
53
|
-
type: TYPE,
|
54
|
-
name: SUBTYPE,
|
55
|
-
resource: peer,
|
56
53
|
address: split_peer[0],
|
57
|
-
port: split_peer[6]
|
54
|
+
port: split_peer[6],
|
55
|
+
service: { type: TYPE, name: SUBTYPE, resource: peer }
|
58
56
|
)
|
59
57
|
ElasticAPM::Span::Context.new(destination: destination)
|
60
58
|
end
|
@@ -57,9 +57,9 @@ module ElasticAPM
|
|
57
57
|
when "gcp"
|
58
58
|
fetch_gcp
|
59
59
|
when "azure"
|
60
|
-
fetch_azure
|
60
|
+
fetch_azure || read_azure_app_services
|
61
61
|
when "auto"
|
62
|
-
fetch_aws || fetch_gcp || fetch_azure
|
62
|
+
fetch_aws || fetch_gcp || fetch_azure || read_azure_app_services
|
63
63
|
when "none"
|
64
64
|
nil
|
65
65
|
else
|
@@ -76,7 +76,7 @@ module ElasticAPM
|
|
76
76
|
resp = @client.get(AWS_URI)
|
77
77
|
|
78
78
|
return unless resp.status == 200
|
79
|
-
return unless (metadata = JSON.parse(resp.body))
|
79
|
+
return unless (metadata = JSON.parse(resp.body.to_s))
|
80
80
|
|
81
81
|
self.provider = "aws"
|
82
82
|
self.account_id = metadata["accountId"]
|
@@ -92,7 +92,7 @@ module ElasticAPM
|
|
92
92
|
resp = @client.headers("Metadata-Flavor" => "Google").get(GCP_URI)
|
93
93
|
|
94
94
|
return unless resp.status == 200
|
95
|
-
return unless (metadata = JSON.parse(resp.body))
|
95
|
+
return unless (metadata = JSON.parse(resp.body.to_s))
|
96
96
|
|
97
97
|
zone = metadata["instance"]["zone"]&.split("/")&.at(-1)
|
98
98
|
|
@@ -112,7 +112,7 @@ module ElasticAPM
|
|
112
112
|
resp = @client.headers("Metadata" => "true").get(AZURE_URI)
|
113
113
|
|
114
114
|
return unless resp.status == 200
|
115
|
-
return unless (metadata = JSON.parse(resp.body))
|
115
|
+
return unless (metadata = JSON.parse(resp.body.to_s))
|
116
116
|
|
117
117
|
self.provider = 'azure'
|
118
118
|
self.account_id = metadata["subscriptionId"]
|
@@ -125,6 +125,33 @@ module ElasticAPM
|
|
125
125
|
rescue HTTP::TimeoutError, HTTP::ConnectionError
|
126
126
|
nil
|
127
127
|
end
|
128
|
+
|
129
|
+
def read_azure_app_services
|
130
|
+
owner_name, instance_id, site_name, resource_group =
|
131
|
+
ENV.values_at(
|
132
|
+
'WEBSITE_OWNER_NAME',
|
133
|
+
'WEBSITE_INSTANCE_ID',
|
134
|
+
'WEBSITE_SITE_NAME',
|
135
|
+
'WEBSITE_RESOURCE_GROUP'
|
136
|
+
)
|
137
|
+
|
138
|
+
return unless owner_name && instance_id && site_name && resource_group
|
139
|
+
|
140
|
+
self.provider = 'azure'
|
141
|
+
self.instance_id = instance_id
|
142
|
+
self.instance_name = site_name
|
143
|
+
self.project_name = resource_group
|
144
|
+
self.account_id, self.region = parse_azure_app_services_owner_name(owner_name)
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def parse_azure_app_services_owner_name(owner_name)
|
150
|
+
id, rest = owner_name.split('+')
|
151
|
+
*_, region = rest.split('-')
|
152
|
+
region.gsub!(/webspace.*$/, '')
|
153
|
+
[id, region]
|
154
|
+
end
|
128
155
|
end
|
129
156
|
end
|
130
157
|
end
|