elastic-apm 4.5.0 → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.ci/.jenkins_exclude.yml +86 -29
  3. data/.ci/.jenkins_framework.yml +4 -3
  4. data/.ci/{.jenkins_master_framework.yml → .jenkins_main_framework.yml} +0 -0
  5. data/.ci/.jenkins_ruby.yml +1 -1
  6. data/.ci/.jenkins_ruby_benchmarks.yml +6 -0
  7. data/.ci/Jenkinsfile +16 -37
  8. data/.ci/jobs/apm-agent-ruby-mbp.yml +1 -1
  9. data/.github/PULL_REQUEST_TEMPLATE.md +5 -5
  10. data/.pre-commit-config.yaml +2 -2
  11. data/CHANGELOG.asciidoc +38 -0
  12. data/CONTRIBUTING.md +2 -2
  13. data/Gemfile +11 -2
  14. data/README.md +1 -1
  15. data/Rakefile +2 -2
  16. data/bench/report.rb +1 -1
  17. data/docs/api.asciidoc +2 -2
  18. data/docs/configuration.asciidoc +7 -5
  19. data/docs/introduction.asciidoc +3 -3
  20. data/docs/log-correlation.asciidoc +1 -1
  21. data/docs/upgrading.asciidoc +1 -1
  22. data/elastic-apm.gemspec +3 -2
  23. data/lib/elastic_apm/central_config.rb +5 -0
  24. data/lib/elastic_apm/config/server_info.rb +50 -0
  25. data/lib/elastic_apm/config.rb +25 -4
  26. data/lib/elastic_apm/error.rb +2 -1
  27. data/lib/elastic_apm/error_builder.rb +1 -0
  28. data/lib/elastic_apm/instrumenter.rb +4 -2
  29. data/lib/elastic_apm/metadata/system_info/container_info.rb +4 -3
  30. data/lib/elastic_apm/metadata/system_info.rb +1 -1
  31. data/lib/elastic_apm/metrics.rb +1 -4
  32. data/lib/elastic_apm/span/context/links.rb +32 -0
  33. data/lib/elastic_apm/span/context/service.rb +55 -0
  34. data/lib/elastic_apm/span/context.rb +19 -3
  35. data/lib/elastic_apm/span.rb +3 -0
  36. data/lib/elastic_apm/span_helpers.rb +2 -2
  37. data/lib/elastic_apm/spies/elasticsearch.rb +11 -1
  38. data/lib/elastic_apm/spies/mongo.rb +5 -12
  39. data/lib/elastic_apm/spies/racecar.rb +77 -0
  40. data/lib/elastic_apm/spies/redis.rb +1 -1
  41. data/lib/elastic_apm/spies/sequel.rb +9 -0
  42. data/lib/elastic_apm/spies/sns.rb +1 -1
  43. data/lib/elastic_apm/spies/sqs.rb +1 -0
  44. data/lib/elastic_apm/trace_context/tracestate.rb +1 -1
  45. data/lib/elastic_apm/trace_context.rb +1 -1
  46. data/lib/elastic_apm/transport/base.rb +1 -3
  47. data/lib/elastic_apm/transport/serializers/span_serializer.rb +25 -0
  48. data/lib/elastic_apm/version.rb +1 -1
  49. data/lib/elastic_apm.rb +1 -0
  50. metadata +29 -9
data/elastic-apm.gemspec CHANGED
@@ -22,8 +22,8 @@ require 'elastic_apm/version'
22
22
  Gem::Specification.new do |spec|
23
23
  spec.name = 'elastic-apm'
24
24
  spec.version = ElasticAPM::VERSION
25
- spec.authors = ['Mikkel Malmberg']
26
- spec.email = ['mikkel@elastic.co']
25
+ spec.authors = ['Mikkel Malmberg', 'Emily Stolfo']
26
+ spec.email = ['info@elastic.co']
27
27
 
28
28
  spec.summary = 'The official Elastic APM agent for Ruby'
29
29
  spec.homepage = 'https://github.com/elastic/apm-agent-ruby'
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
 
38
38
  spec.add_dependency('concurrent-ruby', '~> 1.0')
39
39
  spec.add_dependency('http', '>= 3.0')
40
+ spec.add_runtime_dependency('ruby2_keywords')
40
41
 
41
42
  spec.require_paths = ['lib']
42
43
  end
@@ -181,6 +181,11 @@ module ElasticAPM
181
181
  DEFAULT_MAX_AGE
182
182
  end
183
183
 
184
+ if seconds < 5
185
+ debug "Next fetch is too low (#{seconds}s) - increasing to default"
186
+ seconds = 5
187
+ end
188
+
184
189
  @scheduled_task =
185
190
  Concurrent::ScheduledTask
186
191
  .execute(seconds) { fetch_and_apply_config }
@@ -0,0 +1,50 @@
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
+ class Config
22
+ # @api private
23
+ class ServerInfo
24
+ attr_reader :payload, :config, :http
25
+
26
+ VERSION_8_0 = '8.0'
27
+ VERSION_0 = '0'
28
+
29
+ def initialize(config)
30
+ @config = config
31
+ @http = Transport::Connection::Http.new(config)
32
+ end
33
+
34
+ def execute
35
+ resp = http.get(config.server_url)
36
+ @payload = JSON.parse(resp.body)
37
+ rescue
38
+ @payload = { "version" => VERSION_0 }
39
+ end
40
+
41
+ def version
42
+ @version ||= begin
43
+ execute
44
+ payload["version"] ? payload["version"].to_s : VERSION_0
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -24,14 +24,17 @@ require 'elastic_apm/config/options'
24
24
  require 'elastic_apm/config/round_float'
25
25
  require 'elastic_apm/config/regexp_list'
26
26
  require 'elastic_apm/config/wildcard_pattern_list'
27
+ require 'elastic_apm/deprecations'
28
+ require 'elastic_apm/config/server_info'
27
29
 
28
30
  module ElasticAPM
29
31
  # @api private
30
32
  class Config
31
33
  extend Options
34
+ extend Deprecations
32
35
 
33
36
  SANITIZE_FIELD_NAMES_DEFAULT =
34
- %w[password passwd pwd secret *key *token* *session* *credit* *card* authorization set-cookie].freeze
37
+ %w[password passwd pwd secret *key *token* *session* *credit* *card* *auth* set-cookie].freeze
35
38
 
36
39
  # rubocop:disable Layout/LineLength, Layout/ExtraSpacing
37
40
  option :config_file, type: :string, default: 'config/elastic_apm.yml'
@@ -70,7 +73,7 @@ module ElasticAPM
70
73
  option :ignore_url_patterns, type: :list, default: [], converter: RegexpList.new
71
74
  option :instrument, type: :bool, default: true
72
75
  option :instrumented_rake_tasks, type: :list, default: []
73
- option :log_ecs_formatting, type: :string, default: 'off'
76
+ option :log_ecs_reformatting, type: :string, default: 'off'
74
77
  option :log_level, type: :int, default: Logger::INFO, converter: LogLevelMap.new
75
78
  option :log_path, type: :string
76
79
  option :metrics_interval, type: :int, default: '30s', converter: Duration.new
@@ -98,6 +101,16 @@ module ElasticAPM
98
101
  option :use_elastic_traceparent_header, type: :bool, default: true
99
102
  option :verify_server_cert, type: :bool, default: true
100
103
 
104
+ def log_ecs_formatting
105
+ log_ecs_reformatting
106
+ end
107
+
108
+ def log_ecs_formatting=(value)
109
+ @options[:log_ecs_reformatting].set(value)
110
+ end
111
+
112
+ deprecate :log_ecs_formatting, :log_ecs_reformatting
113
+
101
114
  # rubocop:enable Layout/LineLength, Layout/ExtraSpacing
102
115
  def initialize(options = {})
103
116
  @options = load_schema
@@ -116,7 +129,9 @@ module ElasticAPM
116
129
 
117
130
  yield self if block_given?
118
131
 
119
- self.logger ||= build_logger
132
+ if self.logger.nil? || self.log_path
133
+ self.logger = build_logger
134
+ end
120
135
 
121
136
  @__view_paths ||= []
122
137
  @__root_path ||= Dir.pwd
@@ -144,6 +159,7 @@ module ElasticAPM
144
159
  mongo
145
160
  net_http
146
161
  rake
162
+ racecar
147
163
  redis
148
164
  resque
149
165
  s3
@@ -229,6 +245,10 @@ module ElasticAPM
229
245
  super.split.first + '>'
230
246
  end
231
247
 
248
+ def version
249
+ @version ||= ServerInfo.new(self).version
250
+ end
251
+
232
252
  private
233
253
 
234
254
  def load_config_file
@@ -247,7 +267,7 @@ module ElasticAPM
247
267
  end
248
268
 
249
269
  def build_logger
250
- if self.log_ecs_formatting == 'override'
270
+ if self.log_ecs_reformatting == 'override'
251
271
  begin
252
272
  return build_ecs_logger
253
273
  rescue LoadError
@@ -294,6 +314,7 @@ module ElasticAPM
294
314
  self.framework_name ||= 'Ruby on Rails'
295
315
  self.framework_version ||= ::Rails::VERSION::STRING
296
316
  self.logger ||= ::Rails.logger
317
+ self.log_level ||= ::Rails.logger.log_level
297
318
 
298
319
  self.__root_path = ::Rails.root.to_s
299
320
  self.__view_paths = app.config.paths['app/views'].existent +
@@ -33,7 +33,7 @@ module ElasticAPM
33
33
  end
34
34
 
35
35
  attr_accessor :id, :culprit, :exception, :log, :transaction_id,
36
- :transaction, :context, :parent_id, :trace_id
36
+ :transaction_name, :transaction, :context, :parent_id, :trace_id
37
37
  attr_reader :timestamp
38
38
 
39
39
  def inspect
@@ -41,6 +41,7 @@ module ElasticAPM
41
41
  " culprit:#{culprit}" \
42
42
  " timestamp:#{timestamp}" \
43
43
  " transaction_id:#{transaction_id}" \
44
+ " transaction_name:#{transaction_name}" \
44
45
  " trace_id:#{trace_id}" \
45
46
  " exception:#{exception.inspect}" \
46
47
  '>'
@@ -74,6 +74,7 @@ module ElasticAPM
74
74
  return unless transaction
75
75
 
76
76
  error.transaction_id = transaction.id
77
+ error.transaction_name = transaction.name
77
78
  error.transaction = {
78
79
  sampled: transaction.sampled?,
79
80
  type: transaction.type
@@ -124,7 +124,7 @@ module ElasticAPM
124
124
  sample_rate = trace_context.tracestate.sample_rate
125
125
  else
126
126
  sampled = random_sample?(config)
127
- sample_rate = config.transaction_sample_rate
127
+ sample_rate = sampled ? config.transaction_sample_rate : 0
128
128
  end
129
129
 
130
130
  transaction =
@@ -150,7 +150,9 @@ module ElasticAPM
150
150
 
151
151
  transaction.done result
152
152
 
153
- enqueue.call transaction
153
+ if transaction.sampled? || @config.version < Config::ServerInfo::VERSION_8_0
154
+ enqueue.call transaction
155
+ end
154
156
 
155
157
  update_transaction_metrics(transaction)
156
158
 
@@ -33,14 +33,15 @@ module ElasticAPM
33
33
 
34
34
  attr_reader :cgroup_path
35
35
 
36
- def read!
36
+ def read!(hostname)
37
37
  read_from_cgroup!
38
+ self.kubernetes_pod_name = hostname if kubernetes_pod_uid
38
39
  read_from_env!
39
40
  self
40
41
  end
41
42
 
42
- def self.read!
43
- new.read!
43
+ def self.read!(hostname)
44
+ new.read!(hostname)
44
45
  end
45
46
 
46
47
  def container
@@ -29,7 +29,7 @@ module ElasticAPM
29
29
  @architecture = gem_platform.cpu
30
30
  @platform = gem_platform.os
31
31
 
32
- container_info = ContainerInfo.read!
32
+ container_info = ContainerInfo.read!(@detected_hostname)
33
33
  @container = container_info.container
34
34
  @kubernetes = container_info.kubernetes
35
35
  end
@@ -36,8 +36,6 @@ module ElasticAPM
36
36
  class Registry
37
37
  include Logging
38
38
 
39
- TIMEOUT_INTERVAL = 5 # seconds
40
-
41
39
  def initialize(config, &block)
42
40
  @config = config
43
41
  @callback = block
@@ -76,8 +74,7 @@ module ElasticAPM
76
74
 
77
75
  @timer_task = Concurrent::TimerTask.execute(
78
76
  run_now: true,
79
- execution_interval: config.metrics_interval,
80
- timeout_interval: TIMEOUT_INTERVAL
77
+ execution_interval: config.metrics_interval
81
78
  ) do
82
79
  begin
83
80
  debug 'Collecting metrics'
@@ -0,0 +1,32 @@
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
+ class Span
22
+ class Context
23
+ # @api private
24
+ class Links < Array
25
+ # @api private
26
+ class Link < Struct.new(:trace_id, :span_id)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,55 @@
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
+ class Span
22
+ class Context
23
+ # @api private
24
+ class Service
25
+ include Fields
26
+
27
+ field :target
28
+
29
+ # @api private
30
+ class Target
31
+ include Fields
32
+
33
+ field :name, default: ''
34
+ field :type, default: ''
35
+ end
36
+
37
+ def initialize(target: nil, **attrs)
38
+ super(**attrs)
39
+
40
+ self.target = build_target(target)
41
+ end
42
+
43
+ private
44
+
45
+ def build_target(target = nil)
46
+ return Target.new unless target
47
+ return target if target.is_a?(Target)
48
+
49
+ Target.new(**target)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
@@ -27,7 +27,9 @@ module ElasticAPM
27
27
  http: nil,
28
28
  labels: {},
29
29
  sync: nil,
30
- message: nil
30
+ message: nil,
31
+ service: nil,
32
+ links: nil
31
33
  )
32
34
  @sync = sync
33
35
  @db = db && Db.new(**db)
@@ -43,6 +45,16 @@ module ElasticAPM
43
45
  when Hash then Message.new(**message)
44
46
  end
45
47
  @labels = labels
48
+ @service =
49
+ case service
50
+ when Service then service
51
+ when Hash then Service.new(**service)
52
+ end
53
+ @links =
54
+ case links
55
+ when Links then links
56
+ when Array then Links.new(links)
57
+ end
46
58
  end
47
59
 
48
60
  attr_reader(
@@ -50,10 +62,11 @@ module ElasticAPM
50
62
  :http,
51
63
  :labels,
52
64
  :sync,
53
- :message
65
+ :message,
66
+ :links
54
67
  )
55
68
 
56
- attr_accessor :destination
69
+ attr_accessor :destination, :service
57
70
  end
58
71
  end
59
72
  end
@@ -62,3 +75,6 @@ require 'elastic_apm/span/context/db'
62
75
  require 'elastic_apm/span/context/http'
63
76
  require 'elastic_apm/span/context/destination'
64
77
  require 'elastic_apm/span/context/message'
78
+ require 'elastic_apm/span/context/service'
79
+ require 'elastic_apm/span/context/links'
80
+
@@ -145,6 +145,9 @@ module ElasticAPM
145
145
  service: service,
146
146
  cloud: cloud
147
147
  )
148
+ context.service = Span::Context::Service.new(
149
+ target: Span::Context::Service::Target.new(name: context.destination.service.name, type: context.destination.service.type )
150
+ )
148
151
  end
149
152
 
150
153
  def inspect
@@ -37,7 +37,7 @@ module ElasticAPM
37
37
  type ||= Span::DEFAULT_TYPE
38
38
 
39
39
  klass.prepend(Module.new do
40
- define_method(method) do |*args, &block|
40
+ ruby2_keywords(define_method(method) do |*args, &block|
41
41
  unless ElasticAPM.current_transaction
42
42
  return super(*args, &block)
43
43
  end
@@ -45,7 +45,7 @@ module ElasticAPM
45
45
  ElasticAPM.with_span name.to_s, type.to_s do
46
46
  super(*args, &block)
47
47
  end
48
- end
48
+ end)
49
49
  end)
50
50
  end
51
51
  end
@@ -79,7 +79,11 @@ module ElasticAPM
79
79
  end
80
80
 
81
81
  def install
82
- ::Elasticsearch::Transport::Client.prepend(Ext)
82
+ if defined?(::Elastic::Transport::Client)
83
+ ::Elastic::Transport::Client.prepend(Ext)
84
+ elsif defined?(::Elasticsearch::Transport::Client)
85
+ ::Elasticsearch::Transport::Client.prepend(Ext)
86
+ end
83
87
  end
84
88
  end
85
89
 
@@ -88,5 +92,11 @@ module ElasticAPM
88
92
  'elasticsearch-transport',
89
93
  ElasticsearchSpy.new
90
94
  )
95
+
96
+ register(
97
+ 'Elastic::Transport::Client',
98
+ 'elastic-transport',
99
+ ElasticsearchSpy.new
100
+ )
91
101
  end
92
102
  end
@@ -37,14 +37,8 @@ module ElasticAPM
37
37
 
38
38
  EVENT_KEY = :__elastic_instrumenter_mongo_events_key
39
39
 
40
- class Collection
41
- def events
42
- Thread.current[EVENT_KEY] ||= {}
43
- end
44
- end
45
-
46
- def initialize
47
- @collection = Collection.new
40
+ def events
41
+ Thread.current[EVENT_KEY] ||= []
48
42
  end
49
43
 
50
44
  def started(event)
@@ -78,7 +72,7 @@ module ElasticAPM
78
72
  # and the collection name is at the key `collection`
79
73
  collection =
80
74
  if event.command[event.command_name] == 1 ||
81
- event.command[event.command_name].is_a?(BSON::Int64)
75
+ event.command[event.command_name].is_a?(BSON::Int64)
82
76
  event.command[:collection]
83
77
  else
84
78
  event.command[event.command_name]
@@ -97,14 +91,13 @@ module ElasticAPM
97
91
  context: build_context(event)
98
92
  )
99
93
 
100
- @collection.events[event.operation_id] = span
94
+ events << span
101
95
  end
102
96
 
103
97
  def pop_event(event)
104
- span = @collection.events.delete(event.operation_id)
105
98
  return unless (curr = ElasticAPM.current_span)
106
99
 
107
- curr == span && ElasticAPM.end_span
100
+ curr == events[-1] && ElasticAPM.end_span(events.pop)
108
101
  end
109
102
 
110
103
  def build_context(event)
@@ -0,0 +1,77 @@
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
+ begin
19
+ require 'active_support/notifications'
20
+ require 'active_support/subscriber'
21
+
22
+ # frozen_string_literal: true
23
+ module ElasticAPM
24
+ # @api private
25
+ module Spies
26
+ # @api private
27
+ class RacecarSpy
28
+ TYPE = 'kafka'
29
+ SUBTYPE = 'racecar'
30
+
31
+ # @api private
32
+ class ConsumerSubscriber < ActiveSupport::Subscriber
33
+ def start_process_message(event)
34
+ start_process_transaction(event: event, kind: 'process_message')
35
+ end
36
+ def process_message(_event)
37
+ ElasticAPM.end_transaction
38
+ end
39
+
40
+ def start_process_batch(event)
41
+ start_process_transaction(event: event, kind: 'process_batch')
42
+ end
43
+ def process_batch(_event)
44
+ ElasticAPM.end_transaction
45
+ end
46
+
47
+ private # only public methods will be subscribed
48
+
49
+ def start_process_transaction(event:, kind:)
50
+ ElasticAPM.start_transaction(kind, TYPE)
51
+ ElasticAPM.current_transaction.context.set_service(framework_name: 'racecar', framework_version: Racecar::VERSION)
52
+ end
53
+ end
54
+
55
+ class ProducerSubscriber < ActiveSupport::Subscriber
56
+ def start_deliver_message(event)
57
+ ElasticAPM.start_transaction('deliver_message',TYPE)
58
+ ElasticAPM.current_transaction.context.set_service(framework_name: 'racecar', framework_version: Racecar::VERSION)
59
+ end
60
+
61
+ def deliver_message(_event)
62
+ ElasticAPM.end_transaction
63
+ end
64
+ end
65
+
66
+ def install
67
+ ConsumerSubscriber.attach_to(:racecar)
68
+ ProducerSubscriber.attach_to(:racecar)
69
+ end
70
+ end
71
+ register 'Racecar', 'racecar', RacecarSpy.new
72
+ end
73
+ end
74
+
75
+ rescue LoadError
76
+ # no active support available
77
+ end
@@ -25,7 +25,7 @@ module ElasticAPM
25
25
  # @api private
26
26
  module Ext
27
27
  def call(command, &block)
28
- name = command[0].upcase
28
+ name = command[0].to_s.upcase
29
29
 
30
30
  return super(command, &block) if command[0] == :auth
31
31
 
@@ -44,8 +44,17 @@ module ElasticAPM
44
44
  name =
45
45
  ElasticAPM::Spies::SequelSpy.summarizer.summarize sql
46
46
 
47
+ db_name = ''
48
+ # postgresql shows current database
49
+ db_name = connection&.db.to_s if connection.respond_to?(:db)
50
+ # sqlite may expose a filename
51
+ db_name = connection&.filename.to_s if db_name == '' && connection.respond_to?(:filename)
52
+ # fall back to adapter class name
53
+ db_name = connection.class.to_s if db_name == ''
54
+
47
55
  context = ElasticAPM::Span::Context.new(
48
56
  db: { statement: sql, type: 'sql', user: opts[:user] },
57
+ service: {target: {type: subtype, name: db_name }},
49
58
  destination: { service: { resource: subtype } }
50
59
  )
51
60
 
@@ -38,7 +38,7 @@ module ElasticAPM
38
38
  end
39
39
 
40
40
  def self.get_topic(params)
41
- return '<PHONE_NUMBER>' if params[:phone_number]
41
+ return '[PHONENUMBER]' if params[:phone_number]
42
42
 
43
43
  last_after_slash_or_colon(
44
44
  params[:topic_arn] || params[:target_arn]
@@ -56,6 +56,7 @@ module ElasticAPM
56
56
  service: { resource: "#{SUBTYPE}/#{queue_name}" },
57
57
  cloud: { region: region }
58
58
  }
59
+ # span links added here?
59
60
  )
60
61
  end
61
62
 
@@ -107,7 +107,7 @@ module ElasticAPM
107
107
  split_by_nl_and_comma(header)
108
108
  .each_with_object({}) do |entry, hsh|
109
109
  k, v = entry.split('=')
110
-
110
+ next unless k && v && !k.empty? && !v.empty?
111
111
  hsh[k] =
112
112
  case k
113
113
  when 'es' then EsEntry.new(v)
@@ -96,7 +96,7 @@ module ElasticAPM
96
96
  def apply_headers
97
97
  yield 'Traceparent', traceparent.to_header
98
98
 
99
- if tracestate
99
+ if tracestate && !tracestate.to_header.empty?
100
100
  yield 'Tracestate', tracestate.to_header
101
101
  end
102
102
 
@@ -35,7 +35,6 @@ module ElasticAPM
35
35
  include Logging
36
36
 
37
37
  WATCHER_EXECUTION_INTERVAL = 5
38
- WATCHER_TIMEOUT_INTERVAL = 4
39
38
  WORKER_JOIN_TIMEOUT = 5
40
39
 
41
40
  def initialize(config)
@@ -112,8 +111,7 @@ module ElasticAPM
112
111
 
113
112
  def create_watcher
114
113
  @watcher = Concurrent::TimerTask.execute(
115
- execution_interval: WATCHER_EXECUTION_INTERVAL,
116
- timeout_interval: WATCHER_TIMEOUT_INTERVAL
114
+ execution_interval: WATCHER_EXECUTION_INTERVAL
117
115
  ) { ensure_worker_count }
118
116
  end
119
117