elastic-apm 3.2.0 → 3.3.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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.ci/.jenkins_exclude.yml +8 -1
  3. data/.ci/.jenkins_ruby.yml +1 -0
  4. data/.ci/Jenkinsfile +64 -31
  5. data/.github/workflows/main.yml +14 -0
  6. data/.pre-commit-config.yaml +1 -5
  7. data/.rubocop.yml +35 -29
  8. data/CHANGELOG.asciidoc +20 -4
  9. data/Gemfile +1 -0
  10. data/README.md +2 -2
  11. data/bin/dev +1 -1
  12. data/bin/run-tests +3 -0
  13. data/docs/api.asciidoc +0 -29
  14. data/docs/configuration.asciidoc +11 -0
  15. data/docs/context.asciidoc +4 -4
  16. data/lib/elastic_apm.rb +5 -9
  17. data/lib/elastic_apm/agent.rb +0 -9
  18. data/lib/elastic_apm/central_config.rb +10 -10
  19. data/lib/elastic_apm/central_config/cache_control.rb +1 -1
  20. data/lib/elastic_apm/config.rb +4 -11
  21. data/lib/elastic_apm/config/options.rb +2 -4
  22. data/lib/elastic_apm/config/wildcard_pattern_list.rb +35 -0
  23. data/lib/elastic_apm/context_builder.rb +0 -2
  24. data/lib/elastic_apm/error.rb +1 -1
  25. data/lib/elastic_apm/error/exception.rb +2 -2
  26. data/lib/elastic_apm/error_builder.rb +0 -2
  27. data/lib/elastic_apm/grape.rb +0 -3
  28. data/lib/elastic_apm/instrumenter.rb +3 -13
  29. data/lib/elastic_apm/metadata/service_info.rb +0 -5
  30. data/lib/elastic_apm/metadata/system_info/container_info.rb +4 -6
  31. data/lib/elastic_apm/metrics.rb +0 -3
  32. data/lib/elastic_apm/metrics/cpu_mem_set.rb +0 -10
  33. data/lib/elastic_apm/metrics/metric.rb +6 -2
  34. data/lib/elastic_apm/metrics/set.rb +4 -4
  35. data/lib/elastic_apm/metrics/span_scoped_set.rb +1 -1
  36. data/lib/elastic_apm/metrics/transaction_set.rb +0 -2
  37. data/lib/elastic_apm/metrics/vm_set.rb +0 -3
  38. data/lib/elastic_apm/middleware.rb +0 -2
  39. data/lib/elastic_apm/normalizers/grape/endpoint_run.rb +2 -1
  40. data/lib/elastic_apm/normalizers/rails/active_record.rb +1 -1
  41. data/lib/elastic_apm/opentracing.rb +6 -15
  42. data/lib/elastic_apm/rails.rb +2 -5
  43. data/lib/elastic_apm/sinatra.rb +1 -1
  44. data/lib/elastic_apm/span.rb +2 -2
  45. data/lib/elastic_apm/span/context.rb +17 -1
  46. data/lib/elastic_apm/spies/elasticsearch.rb +0 -3
  47. data/lib/elastic_apm/spies/faraday.rb +2 -4
  48. data/lib/elastic_apm/spies/http.rb +0 -3
  49. data/lib/elastic_apm/spies/mongo.rb +10 -5
  50. data/lib/elastic_apm/spies/net_http.rb +1 -4
  51. data/lib/elastic_apm/spies/rake.rb +0 -2
  52. data/lib/elastic_apm/spies/sequel.rb +0 -2
  53. data/lib/elastic_apm/spies/sidekiq.rb +2 -6
  54. data/lib/elastic_apm/spies/sinatra.rb +0 -2
  55. data/lib/elastic_apm/stacktrace/frame.rb +0 -3
  56. data/lib/elastic_apm/stacktrace_builder.rb +0 -2
  57. data/lib/elastic_apm/subscriber.rb +2 -3
  58. data/lib/elastic_apm/trace_context.rb +0 -3
  59. data/lib/elastic_apm/transaction.rb +2 -2
  60. data/lib/elastic_apm/transport/base.rb +0 -6
  61. data/lib/elastic_apm/transport/connection.rb +1 -4
  62. data/lib/elastic_apm/transport/connection/http.rb +0 -2
  63. data/lib/elastic_apm/transport/filters.rb +1 -1
  64. data/lib/elastic_apm/transport/filters/secrets_filter.rb +1 -3
  65. data/lib/elastic_apm/transport/serializers.rb +0 -3
  66. data/lib/elastic_apm/transport/serializers/context_serializer.rb +0 -2
  67. data/lib/elastic_apm/transport/serializers/error_serializer.rb +0 -2
  68. data/lib/elastic_apm/transport/serializers/metadata_serializer.rb +0 -2
  69. data/lib/elastic_apm/transport/serializers/metricset_serializer.rb +0 -2
  70. data/lib/elastic_apm/transport/serializers/span_serializer.rb +0 -3
  71. data/lib/elastic_apm/transport/serializers/transaction_serializer.rb +0 -2
  72. data/lib/elastic_apm/transport/worker.rb +10 -6
  73. data/lib/elastic_apm/util.rb +1 -1
  74. data/lib/elastic_apm/version.rb +1 -1
  75. metadata +5 -5
  76. data/.ci/bin/check_paths_for_matches.py +0 -80
  77. data/.hound.yml +0 -2
@@ -318,6 +318,17 @@ NOTE: `global_labels` are supported as of APM server version 7.2. `default_tags`
318
318
  deprecated so please transition to using `global_labels` instead. In the meantime, any `default_tags`
319
319
  that are set will override `global_labels`.
320
320
 
321
+ [float]
322
+ [[config-disable_metrics]]
323
+ ==== `disable_metrics`
324
+ |============
325
+ | Environment | `Config` key | Default | Example
326
+ | `ELASTIC_APM_DISABLE_METRICS` | `disable_metrics` | [] | `"*.cpu.*,system.memory.total"`
327
+ |============
328
+
329
+ A comma-separated list of dotted metrics names that should not be sent to the APM Server.
330
+ You can use `*` to match multiple metrics.
331
+
321
332
  [float]
322
333
  [[config-disable-send]]
323
334
  ==== `disable_send`
@@ -19,14 +19,14 @@ end
19
19
  ----
20
20
 
21
21
  [float]
22
- ==== Adding tags
22
+ ==== Adding labels
23
23
 
24
- Tags are special in that they are indexed in your Elasticsearch database and
25
- therefore searchable.
24
+ Labels are special in that they are indexed in your Elasticsearch database and
25
+ therefore queryable.
26
26
 
27
27
  [source,ruby]
28
28
  ----
29
- ElasticAPM.set_tag(:company_name, 'Acme, Inc.')
29
+ ElasticAPM.set_label(:company_name, 'Acme, Inc.')
30
30
  ----
31
31
 
32
32
  Note that `.`, `*` and `"` in keys are converted to `_`.
@@ -28,7 +28,7 @@ require 'elastic_apm/sinatra' if defined?(::Sinatra)
28
28
  require 'elastic_apm/grape' if defined?(::Grape)
29
29
 
30
30
  # ElasticAPM
31
- module ElasticAPM # rubocop:disable Metrics/ModuleLength
31
+ module ElasticAPM
32
32
  class << self
33
33
  ### Life cycle
34
34
 
@@ -71,7 +71,6 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
71
71
  agent&.current_span
72
72
  end
73
73
 
74
- # rubocop:disable Metrics/AbcSize
75
74
  # Get a formatted string containing transaction, span, and trace ids.
76
75
  # If a block is provided, the ids are yielded.
77
76
  #
@@ -90,7 +89,6 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
90
89
  ids << "trace.id=#{trace_id}" if trace_id
91
90
  ids.join(' ')
92
91
  end
93
- # rubocop:enable Metrics/AbcSize
94
92
 
95
93
  # Start a new transaction
96
94
  #
@@ -122,7 +120,6 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
122
120
  agent&.end_transaction(result)
123
121
  end
124
122
 
125
- # rubocop:disable Metrics/MethodLength
126
123
  # Wrap a block in a Transaction, ending it after the block
127
124
  #
128
125
  # @param name [String] A description of the transaction, eg
@@ -158,9 +155,8 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
158
155
  end_transaction
159
156
  end
160
157
  end
161
- # rubocop:enable Metrics/MethodLength
162
158
 
163
- # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
159
+ # rubocop:disable Metrics/ParameterLists
164
160
  # Start a new span
165
161
  #
166
162
  # @param name [String] A description of the span, eq `SELECT FROM "users"`
@@ -193,7 +189,7 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
193
189
  span.original_backtrace ||= caller
194
190
  end
195
191
  end
196
- # rubocop:enable Metrics/MethodLength, Metrics/ParameterLists
192
+ # rubocop:enable Metrics/ParameterLists
197
193
 
198
194
  # Ends the current span
199
195
  #
@@ -202,7 +198,7 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
202
198
  agent&.end_span
203
199
  end
204
200
 
205
- # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
201
+ # rubocop:disable Metrics/ParameterLists
206
202
  # Wrap a block in a Span, ending it after the block
207
203
  #
208
204
  # @param name [String] A description of the span, eq `SELECT FROM "users"`
@@ -243,7 +239,7 @@ module ElasticAPM # rubocop:disable Metrics/ModuleLength
243
239
  end_span
244
240
  end
245
241
  end
246
- # rubocop:enable Metrics/MethodLength, Metrics/ParameterLists
242
+ # rubocop:enable Metrics/ParameterLists
247
243
 
248
244
  # Build a [Context] from a Rack `env`. The context may include information
249
245
  # about the request, response, current user and more
@@ -13,7 +13,6 @@ require 'elastic_apm/metrics'
13
13
  require 'elastic_apm/spies'
14
14
 
15
15
  module ElasticAPM
16
- # rubocop:disable Metrics/ClassLength
17
16
  # @api private
18
17
  class Agent
19
18
  include Logging
@@ -27,7 +26,6 @@ module ElasticAPM
27
26
  @instance
28
27
  end
29
28
 
30
- # rubocop:disable Metrics/MethodLength
31
29
  def self.start(config)
32
30
  return @instance if @instance
33
31
 
@@ -47,7 +45,6 @@ module ElasticAPM
47
45
  @instance = new(config).start
48
46
  end
49
47
  end
50
- # rubocop:enable Metrics/MethodLength
51
48
 
52
49
  def self.stop
53
50
  LOCK.synchronize do
@@ -62,7 +59,6 @@ module ElasticAPM
62
59
  !!@instance
63
60
  end
64
61
 
65
- # rubocop:disable Metrics/MethodLength
66
62
  def initialize(config)
67
63
  @stacktrace_builder = StacktraceBuilder.new(config)
68
64
  @context_builder = ContextBuilder.new(config)
@@ -77,7 +73,6 @@ module ElasticAPM
77
73
  stacktrace_builder: stacktrace_builder
78
74
  ) { |event| enqueue event }
79
75
  end
80
- # rubocop:enable Metrics/MethodLength
81
76
 
82
77
  attr_reader(
83
78
  :central_config,
@@ -91,8 +86,6 @@ module ElasticAPM
91
86
  )
92
87
 
93
88
  def_delegator :@central_config, :config
94
-
95
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
96
89
  def start
97
90
  unless config.disable_start_message?
98
91
  config.logger.info format(
@@ -113,7 +106,6 @@ module ElasticAPM
113
106
 
114
107
  self
115
108
  end
116
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
117
109
 
118
110
  def stop
119
111
  debug 'Stopping agent'
@@ -244,5 +236,4 @@ module ElasticAPM
244
236
  super.split.first + '>'
245
237
  end
246
238
  end
247
- # rubocop:enable Metrics/ClassLength
248
239
  end
@@ -4,7 +4,7 @@ require 'elastic_apm/central_config/cache_control'
4
4
 
5
5
  module ElasticAPM
6
6
  # @api private
7
- class CentralConfig # rubocop:disable Metrics/ClassLength
7
+ class CentralConfig
8
8
  include Logging
9
9
 
10
10
  # @api private
@@ -52,7 +52,6 @@ module ElasticAPM
52
52
  .rescue(&method(:handle_error))
53
53
  end
54
54
 
55
- # rubocop:disable Metrics/MethodLength
56
55
  def fetch_config
57
56
  resp = perform_request
58
57
 
@@ -67,7 +66,6 @@ module ElasticAPM
67
66
  raise ServerError, resp
68
67
  end
69
68
  end
70
- # rubocop:enable Metrics/MethodLength
71
69
 
72
70
  def assign(update)
73
71
  # For each updated option, store the original value,
@@ -92,7 +90,6 @@ module ElasticAPM
92
90
  @config = config.dup.tap { |new_config| new_config.assign(new_options) }
93
91
  end
94
92
 
95
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
96
93
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
97
94
  def handle_success(resp)
98
95
  if (etag = resp.headers['Etag'])
@@ -121,17 +118,19 @@ module ElasticAPM
121
118
  debug { e.backtrace.join('\n') }
122
119
  end
123
120
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
124
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
125
121
 
126
122
  def handle_error(error)
123
+ # For tests, WebMock failures don't have real responses
124
+ response = error.response if error.respond_to?(:response)
125
+
127
126
  debug(
128
127
  'Failed fetching config: %s, trying again in %d seconds',
129
- error.response.body, DEFAULT_MAX_AGE
128
+ response&.body, DEFAULT_MAX_AGE
130
129
  )
131
130
 
132
131
  assign({})
133
132
 
134
- schedule_next_fetch(error.response)
133
+ schedule_next_fetch(response)
135
134
  end
136
135
 
137
136
  def perform_request
@@ -149,10 +148,11 @@ module ElasticAPM
149
148
  { 'Etag': @etag }
150
149
  end
151
150
 
152
- def schedule_next_fetch(resp)
151
+ def schedule_next_fetch(resp = nil)
152
+ headers = resp&.headers
153
153
  seconds =
154
- if (cache_header = resp.headers['Cache-Control'])
155
- CacheControl.new(cache_header).max_age
154
+ if headers['Cache-Control']
155
+ CacheControl.new(headers['Cache-Control']).max_age
156
156
  else
157
157
  DEFAULT_MAX_AGE
158
158
  end
@@ -26,7 +26,7 @@ module ElasticAPM
26
26
  def parse!(value)
27
27
  value.split(',').each do |token|
28
28
  k, v = token.split('=').map(&:strip)
29
- instance_variable_set(:"@#{k.gsub('-', '_')}", v ? v.to_i : true)
29
+ instance_variable_set(:"@#{k.tr('-', '_')}", v ? v.to_i : true)
30
30
  end
31
31
  end
32
32
  end
@@ -4,9 +4,9 @@ require 'elastic_apm/config/options'
4
4
  require 'elastic_apm/config/duration'
5
5
  require 'elastic_apm/config/bytes'
6
6
  require 'elastic_apm/config/regexp_list'
7
+ require 'elastic_apm/config/wildcard_pattern_list'
7
8
 
8
9
  module ElasticAPM
9
- # rubocop:disable Metrics/ClassLength
10
10
  # @api private
11
11
  class Config
12
12
  extend Options
@@ -33,6 +33,7 @@ module ElasticAPM
33
33
  option :custom_key_filters, type: :list, default: [], converter: RegexpList.new
34
34
  option :default_tags, type: :dict, default: {}
35
35
  option :default_labels, type: :dict, default: {}
36
+ option :disable_metrics, type: :list, default: [], converter: WildcardPatternList.new
36
37
  option :disable_send, type: :bool, default: false
37
38
  option :disable_start_message, type: :bool, default: false
38
39
  option :disabled_instrumentations, type: :list, default: %w[json]
@@ -69,8 +70,6 @@ module ElasticAPM
69
70
  option :transaction_sample_rate, type: :float, default: 1.0
70
71
  option :verify_server_cert, type: :bool, default: true
71
72
  # rubocop:enable Metrics/LineLength, Layout/ExtraSpacing
72
-
73
- # rubocop:disable Metrics/MethodLength
74
73
  def initialize(options = {})
75
74
  @options = load_schema
76
75
 
@@ -93,7 +92,6 @@ module ElasticAPM
93
92
  @__view_paths ||= []
94
93
  @__root_path ||= Dir.pwd
95
94
  end
96
- # rubocop:enable Metrics/MethodLength
97
95
 
98
96
  attr_accessor :__view_paths, :__root_path
99
97
  attr_accessor :logger
@@ -105,7 +103,6 @@ module ElasticAPM
105
103
  update.each { |key, value| send(:"#{key}=", value) }
106
104
  end
107
105
 
108
- # rubocop:disable Metrics/MethodLength
109
106
  def available_instrumentations
110
107
  %w[
111
108
  delayed_job
@@ -123,7 +120,6 @@ module ElasticAPM
123
120
  rake
124
121
  ]
125
122
  end
126
- # rubocop:enable Metrics/MethodLength
127
123
 
128
124
  def enabled_instrumentations
129
125
  available_instrumentations - disabled_instrumentations
@@ -166,7 +162,6 @@ module ElasticAPM
166
162
  @span_frames_min_duration_us ||= span_frames_min_duration * 1_000_000
167
163
  end
168
164
 
169
- # rubocop:disable Metrics/MethodLength
170
165
  def ssl_context
171
166
  return unless use_ssl?
172
167
 
@@ -187,7 +182,6 @@ module ElasticAPM
187
182
  end
188
183
  end
189
184
  end
190
- # rubocop:enable Metrics/MethodLength
191
185
 
192
186
  def inspect
193
187
  super.split.first + '>'
@@ -235,7 +229,7 @@ module ElasticAPM
235
229
  self.__root_path = Dir.pwd
236
230
  end
237
231
 
238
- def set_rails(app) # rubocop:disable Metrics/AbcSize
232
+ def set_rails(app)
239
233
  self.service_name ||= format_name(service_name || rails_app_name(app))
240
234
  self.framework_name ||= 'Ruby on Rails'
241
235
  self.framework_version ||= ::Rails::VERSION::STRING
@@ -254,8 +248,7 @@ module ElasticAPM
254
248
  end
255
249
 
256
250
  def format_name(str)
257
- str && str.gsub('::', '_')
251
+ str&.gsub('::', '_')
258
252
  end
259
253
  end
260
- # rubocop:enable Metrics/ClassLength
261
254
  end
@@ -33,7 +33,7 @@ module ElasticAPM
33
33
 
34
34
  private
35
35
 
36
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
36
+ # rubocop:disable Metrics/CyclomaticComplexity
37
37
  def normalize(val)
38
38
  return unless val
39
39
 
@@ -54,7 +54,7 @@ module ElasticAPM
54
54
  val
55
55
  end
56
56
  end
57
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
57
+ # rubocop:enable Metrics/CyclomaticComplexity
58
58
 
59
59
  def normalize_bool(val)
60
60
  return val unless val.is_a?(String)
@@ -97,7 +97,6 @@ module ElasticAPM
97
97
  end]
98
98
  end
99
99
 
100
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
101
100
  def method_missing(name, *value)
102
101
  name_str = name.to_s
103
102
 
@@ -116,7 +115,6 @@ module ElasticAPM
116
115
  super
117
116
  end
118
117
  end
119
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
120
118
 
121
119
  def [](key)
122
120
  options[key]
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElasticAPM
4
+ class Config
5
+ # @api private
6
+ class WildcardPatternList
7
+ # @api private
8
+ class WildcardPattern
9
+ def initialize(str)
10
+ @pattern = convert(str)
11
+ end
12
+
13
+ def match?(other)
14
+ !!@pattern.match(other)
15
+ end
16
+
17
+ private
18
+
19
+ def convert(str)
20
+ parts =
21
+ str.chars.each_with_object([]) do |char, arr|
22
+ arr << (char == '*' ? '.*' : Regexp.escape(char))
23
+ end
24
+
25
+ Regexp.new('\A' + parts.join + '\Z')
26
+ end
27
+ end
28
+
29
+ def call(value)
30
+ value = value.is_a?(String) ? value.split(',') : Array(value)
31
+ value.map(&WildcardPattern.method(:new))
32
+ end
33
+ end
34
+ end
35
+ end
@@ -20,7 +20,6 @@ module ElasticAPM
20
20
 
21
21
  private
22
22
 
23
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
24
23
  def apply_to_request(context, rack_env:, for_type:)
25
24
  req = rails_req?(rack_env) ? rack_env : Rack::Request.new(rack_env)
26
25
 
@@ -42,7 +41,6 @@ module ElasticAPM
42
41
 
43
42
  context
44
43
  end
45
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
46
44
 
47
45
  def should_capture_body?(for_type)
48
46
  option = config.capture_body
@@ -26,7 +26,7 @@ module ElasticAPM
26
26
  " transaction_id:#{transaction_id}" \
27
27
  " trace_id:#{trace_id}" \
28
28
  " exception:#{exception.inspect}" \
29
- ">"
29
+ '>'
30
30
  end
31
31
  end
32
32
  end
@@ -35,10 +35,10 @@ module ElasticAPM
35
35
  )
36
36
 
37
37
  def inspect
38
- "<ElasticAPM::Error::Exception" \
38
+ '<ElasticAPM::Error::Exception' \
39
39
  " type:#{type}" \
40
40
  " message:#{message}" \
41
- ">"
41
+ '>'
42
42
  end
43
43
 
44
44
  class << self
@@ -53,7 +53,6 @@ module ElasticAPM
53
53
  error.culprit = stacktrace.frames.first&.function
54
54
  end
55
55
 
56
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
57
56
  def add_current_transaction_fields(error, transaction)
58
57
  return unless transaction
59
58
 
@@ -70,6 +69,5 @@ module ElasticAPM
70
69
  Util.reverse_merge!(error.context.labels, transaction.context.labels)
71
70
  Util.reverse_merge!(error.context.custom, transaction.context.custom)
72
71
  end
73
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
74
72
  end
75
73
  end