elastic-apm 3.12.1 → 3.13.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/labeler-config.yml +3 -0
  3. data/.github/workflows/labeler.yml +16 -0
  4. data/.rubocop.yml +33 -4
  5. data/CHANGELOG.asciidoc +20 -0
  6. data/Gemfile +5 -3
  7. data/Rakefile +10 -10
  8. data/docs/configuration.asciidoc +3 -3
  9. data/lib/elastic_apm.rb +4 -4
  10. data/lib/elastic_apm/central_config.rb +7 -2
  11. data/lib/elastic_apm/config.rb +32 -18
  12. data/lib/elastic_apm/config/log_level_map.rb +47 -0
  13. data/lib/elastic_apm/context.rb +2 -8
  14. data/lib/elastic_apm/graphql.rb +2 -0
  15. data/lib/elastic_apm/grpc.rb +3 -3
  16. data/lib/elastic_apm/instrumenter.rb +1 -1
  17. data/lib/elastic_apm/metadata/cloud_info.rb +3 -1
  18. data/lib/elastic_apm/metadata/service_info.rb +2 -2
  19. data/lib/elastic_apm/metadata/system_info/container_info.rb +16 -5
  20. data/lib/elastic_apm/metrics.rb +1 -0
  21. data/lib/elastic_apm/metrics/cpu_mem_set.rb +1 -0
  22. data/lib/elastic_apm/opentracing.rb +2 -1
  23. data/lib/elastic_apm/span.rb +1 -2
  24. data/lib/elastic_apm/span/context/db.rb +1 -1
  25. data/lib/elastic_apm/spies/delayed_job.rb +3 -1
  26. data/lib/elastic_apm/spies/dynamo_db.rb +8 -1
  27. data/lib/elastic_apm/spies/elasticsearch.rb +4 -2
  28. data/lib/elastic_apm/spies/faraday.rb +4 -2
  29. data/lib/elastic_apm/spies/net_http.rb +2 -0
  30. data/lib/elastic_apm/spies/sequel.rb +2 -0
  31. data/lib/elastic_apm/sql/signature.rb +4 -2
  32. data/lib/elastic_apm/sql/tokenizer.rb +2 -2
  33. data/lib/elastic_apm/stacktrace/frame.rb +1 -0
  34. data/lib/elastic_apm/stacktrace_builder.rb +2 -4
  35. data/lib/elastic_apm/trace_context.rb +0 -2
  36. data/lib/elastic_apm/trace_context/traceparent.rb +0 -2
  37. data/lib/elastic_apm/trace_context/tracestate.rb +7 -5
  38. data/lib/elastic_apm/transaction.rb +5 -4
  39. data/lib/elastic_apm/transport/connection.rb +1 -1
  40. data/lib/elastic_apm/transport/filters/hash_sanitizer.rb +2 -1
  41. data/lib/elastic_apm/transport/filters/secrets_filter.rb +32 -12
  42. data/lib/elastic_apm/transport/serializers.rb +1 -0
  43. data/lib/elastic_apm/transport/serializers/metadata_serializer.rb +6 -6
  44. data/lib/elastic_apm/transport/serializers/span_serializer.rb +0 -2
  45. data/lib/elastic_apm/util/deep_dup.rb +1 -2
  46. data/lib/elastic_apm/util/precision_validator.rb +1 -1
  47. data/lib/elastic_apm/version.rb +1 -1
  48. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de9bb2ac6873a987cb7c7d0cdf51f8c11908d0d3ada729bd21bb4bc24d3aa3dc
4
- data.tar.gz: 571507faa100bb620c116dbe11bdcad1b958c718c89a7f8572732ef3939ad70f
3
+ metadata.gz: 49c0c5abfddc19b97d5a0a25f7adeff62bd8ed99a1bdcb97d94ca9b3ff09134f
4
+ data.tar.gz: 4e7a68808d904181b3649cc766c075e5b575633b55a370047cd85c4eff53c5ef
5
5
  SHA512:
6
- metadata.gz: 916cfb05143133cf1c0680d2495f2877997d607cac710063d3862acf62105d256434f0e3f9170599fa5d6c2a59c80ff39dace42584a0cce493b5f476ad6e8e5e
7
- data.tar.gz: af7f87595e02ec5996c7a1ecf5aac7e7deb376ae4a32d30c250ad6293be3ce086a8a64074e88b79f6dcb2ce52b1c9861e7d7031119da58026bfff9e2ca841eb4
6
+ metadata.gz: 94af89d9a12520b2344f941b85eefdd6d0bd447dc75ac75b220b491611e0b16a47722cce78badf8f065f78cd09496d7a63d5a0e392af3ee939ed86ecef43599b
7
+ data.tar.gz: '0790d669dede1e490e290960129488264dc9661224ccb011094c1a3a5a48419ad628f5b7e83ba11ad273c8af1698e9d935cb2d6f3a823197793931f2ec27e7de'
@@ -0,0 +1,3 @@
1
+ # add 'agent-ruby' label to all new issues
2
+ agent-ruby:
3
+ - '.*'
@@ -0,0 +1,16 @@
1
+ name: "Issue Labeler"
2
+ on:
3
+ issues:
4
+ types: [opened]
5
+ pull_request_target:
6
+ types: [opened]
7
+
8
+ jobs:
9
+ triage:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: AlexanderWert/issue-labeler@v2.3
13
+ with:
14
+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
15
+ configuration-path: .github/labeler-config.yml
16
+ enable-versioned-regex: 0
@@ -1,11 +1,13 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.3
2
+ TargetRubyVersion: 2.4
3
+ NewCops: enable
3
4
  Exclude:
4
5
  - 'elastic-apm.gemspec'
5
6
  - 'vendor/**/*'
6
7
  - 'bench/*'
7
8
  - 'spec/support/helloworld_pb.rb'
8
9
  - 'spec/support/helloworld_services_pb.rb'
10
+ - 'features/step_definitions/stepdefs.rb'
9
11
 
10
12
  require:
11
13
  - rubocop-performance
@@ -32,6 +34,15 @@ Lint/RescueException:
32
34
  Lint/SuppressedException:
33
35
  Enabled: false
34
36
 
37
+ Lint/ConstantDefinitionInBlock: # So we can define a class in an rspec block
38
+ Enabled: false
39
+
40
+ Lint/EmptyClass:
41
+ Enabled: false
42
+
43
+ Lint/NoReturnInBeginEndBlocks:
44
+ Enabled: false
45
+
35
46
  # Metrics /
36
47
 
37
48
  Metrics/AbcSize:
@@ -104,9 +115,27 @@ Style/HashEachMethods:
104
115
  Style/HashTransformKeys:
105
116
  Enabled: true
106
117
 
107
- Style/HashTransformValues:
108
- Enabled: true
109
-
110
118
  Style/FrozenStringLiteralComment:
111
119
  Enabled: false
112
120
 
121
+ Style/StringLiterals:
122
+ Enabled: false
123
+
124
+ Style/RescueStandardError:
125
+ Enabled: false
126
+
127
+ Style/SoleNestedConditional:
128
+ Enabled: false
129
+
130
+ Style/StringConcatenation:
131
+ Enabled: false
132
+
133
+ Style/DocumentDynamicEvalDefinition:
134
+ Enabled: false
135
+
136
+ # Applies to > ruby 2.3, enable when 2.3 support is dropped
137
+ Performance/RegexpMatch:
138
+ Enabled: false
139
+
140
+ Style/HashTransformValues:
141
+ Enabled: false
@@ -35,6 +35,26 @@ endif::[]
35
35
  [[release-notes-3.x]]
36
36
  === Ruby Agent version 3.x
37
37
 
38
+ [[release-notes-3.13.0]]
39
+ ==== 3.13.0 (2020-12-22)
40
+
41
+ [float]
42
+ ===== Fixed
43
+
44
+ - Handle invalid utf-8 byte sequences in sql summarizer and DB statement {pull}896[#896]
45
+ - Expand Kubernetes metadata discovery {pull}916[#916]
46
+ - Fix fetching cloud info on Http.rb 3.x versions {pull}919[#919]
47
+
48
+ [float]
49
+ ===== Added
50
+
51
+ - Support both integer and string log levels, and extra central config values {pull}902[#902]
52
+
53
+ [float]
54
+ ===== Changed
55
+
56
+ - Rename server_ca_cert to server_ca_cert_file {pull}908[#908]
57
+
38
58
  [[release-notes-3.12.1]]
39
59
  ==== 3.12.1 (2020-11-16)
40
60
 
data/Gemfile CHANGED
@@ -37,8 +37,10 @@ gem 'elasticsearch', require: nil
37
37
  gem 'fakeredis', require: nil
38
38
  gem 'faraday', require: nil
39
39
  gem 'graphql', require: nil
40
- gem 'google-protobuf', '< 3.12' if !defined?(JRUBY_VERSION) && RUBY_VERSION < '2.5'
41
- gem 'grpc' if !defined?(JRUBY_VERSION)
40
+ if !defined?(JRUBY_VERSION) && RUBY_VERSION < '2.5'
41
+ gem 'google-protobuf', '< 3.12'
42
+ end
43
+ gem 'grpc' unless defined?(JRUBY_VERSION)
42
44
  gem 'json'
43
45
  gem 'json-schema', require: nil
44
46
  gem 'mongo', require: nil
@@ -93,7 +95,7 @@ if RUBY_PLATFORM == 'java'
93
95
  elsif frameworks_versions['rails'] =~ /^(4|5)/
94
96
  gem 'sqlite3', '~> 1.3.6'
95
97
  else
96
- gem 'sqlite3' # rubocop:disable Bundler/DuplicatedGem
98
+ gem 'sqlite3'
97
99
  end
98
100
 
99
101
  group :bench do
data/Rakefile CHANGED
@@ -19,9 +19,9 @@
19
19
 
20
20
  require 'bundler/gem_tasks'
21
21
 
22
- desc """Post release action:
23
- Update `3.x` branch to be at released commit and push it to GitHub.
24
- """
22
+ desc 'Post release action:'\
23
+ 'Update `3.x` branch to be at released commit and push it to GitHub.'
24
+
25
25
  namespace :release do
26
26
  task :update_branch do
27
27
  `git checkout 3.x &&
@@ -41,11 +41,11 @@ task docs: :yard
41
41
  task default: :spec
42
42
 
43
43
  namespace :coverage do
44
- desc "Collates all result sets generated by the different test runners"
45
- task :report do
46
- require 'simplecov'
47
- require 'simplecov-cobertura'
48
- SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
49
- SimpleCov.collate Dir["coverage/matrix_results/**/.resultset.json"]
50
- end
44
+ desc "Collates all result sets generated by the different test runners"
45
+ task :report do
46
+ require 'simplecov'
47
+ require 'simplecov-cobertura'
48
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
49
+ SimpleCov.collate Dir["coverage/matrix_results/**/.resultset.json"]
51
50
  end
51
+ end
@@ -798,12 +798,12 @@ It has to be provided in *<<config-format-duration, duration format>>*.
798
798
 
799
799
  [float]
800
800
  [[config-ssl-ca-cert]]
801
- ==== `server_ca_cert`
801
+ ==== `server_ca_cert_file`
802
802
 
803
803
  [options="header"]
804
804
  |============
805
- | Environment | `Config` key | Default | Example
806
- | `ELASTIC_APM_SERVER_CA_CERT` | `server_ca_cert` | `nil` | `'/path/to/ca.pem'`
805
+ | Environment | `Config` key | Default | Example
806
+ | `ELASTIC_APM_SERVER_CA_CERT_FILE` | `server_ca_cert_file` | `nil` | `'/path/to/ca.pem'`
807
807
  |============
808
808
 
809
809
  The path to a custom CA certificate for connecting to APM Server.
@@ -106,6 +106,7 @@ module ElasticAPM
106
106
  # @yield [String|nil, String|nil, String|nil] The transaction, span,
107
107
  # and trace ids.
108
108
  # @return [String] Unless block given
109
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
109
110
  def log_ids
110
111
  trace_id = (current_transaction || current_span)&.trace_id
111
112
  if block_given?
@@ -118,6 +119,7 @@ module ElasticAPM
118
119
  ids << "trace.id=#{trace_id}" if trace_id
119
120
  ids.join(' ')
120
121
  end
122
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
121
123
 
122
124
  # Start a new transaction
123
125
  #
@@ -293,12 +295,10 @@ module ElasticAPM
293
295
  sync: sync
294
296
  )
295
297
  result = yield span
296
- span&.outcome =
297
- Span::Outcome::SUCCESS unless span&.outcome
298
+ span&.outcome ||= Span::Outcome::SUCCESS
298
299
  result
299
300
  rescue
300
- span&.outcome =
301
- Span::Outcome::FAILURE unless span&.outcome
301
+ span&.outcome ||= Span::Outcome::FAILURE
302
302
  raise
303
303
  ensure
304
304
  end_span
@@ -19,6 +19,7 @@
19
19
 
20
20
  require 'elastic_apm/central_config/cache_control'
21
21
 
22
+ # rubocop:disable Style/AccessorGrouping
22
23
  module ElasticAPM
23
24
  # @api private
24
25
  class CentralConfig
@@ -27,6 +28,7 @@ module ElasticAPM
27
28
  # @api private
28
29
  class ResponseError < InternalError
29
30
  def initialize(response)
31
+ super
30
32
  @response = response
31
33
  end
32
34
 
@@ -72,6 +74,7 @@ module ElasticAPM
72
74
  def fetch_config
73
75
  resp = perform_request
74
76
 
77
+ # rubocop:disable Lint/DuplicateBranch
75
78
  case resp.status
76
79
  when 200..299
77
80
  resp
@@ -82,6 +85,7 @@ module ElasticAPM
82
85
  when 500..599
83
86
  raise ServerError, resp
84
87
  end
88
+ # rubocop:enable Lint/DuplicateBranch
85
89
  end
86
90
 
87
91
  def assign(update)
@@ -122,7 +126,7 @@ module ElasticAPM
122
126
  assign(update)
123
127
  end
124
128
 
125
- if update && update.any?
129
+ if update&.any?
126
130
  info 'Updated config from Kibana'
127
131
  debug 'Modified: %s', update.inspect
128
132
  debug 'Modified original options: %s', @modified_options.inspect
@@ -160,7 +164,7 @@ module ElasticAPM
160
164
  @server_url ||=
161
165
  config.server_url +
162
166
  '/config/v1/agents' \
163
- "?service.name=#{config.service_name}"
167
+ "?service.name=#{CGI.escape(config.service_name)}"
164
168
  end
165
169
 
166
170
  def headers
@@ -182,3 +186,4 @@ module ElasticAPM
182
186
  end
183
187
  end
184
188
  end
189
+ # rubocop:enable Style/AccessorGrouping
@@ -19,6 +19,7 @@
19
19
 
20
20
  require 'elastic_apm/config/bytes'
21
21
  require 'elastic_apm/config/duration'
22
+ require 'elastic_apm/config/log_level_map'
22
23
  require 'elastic_apm/config/options'
23
24
  require 'elastic_apm/config/round_float'
24
25
  require 'elastic_apm/config/regexp_list'
@@ -32,11 +33,13 @@ module ElasticAPM
32
33
  DEPRECATED_OPTIONS = %i[].freeze
33
34
 
34
35
  # DEPRECATED: To align with other agents, change on next major bump to:
35
- # "password, passwd, pwd, secret, *key, *token*, *session*, *credit*, *card*, authorization, set-cookie"
36
+ # "password, passwd, pwd, secret, *key, *token*, *session*, *credit*,
37
+ # *card*, authorization, set-cookie"
36
38
  SANITIZE_FIELD_NAMES_DEFAULT =
37
- %w[*password* *passwd* *pwd* *secret* *key* *token* *session* *credit* *card* *authorization* *set-cookie*]
39
+ %w[*password* *passwd* *pwd* *secret* *key* *token* *session*
40
+ *credit* *card* *authorization* *set-cookie*].freeze
38
41
 
39
- # rubocop:disable Metrics/LineLength, Layout/ExtraSpacing
42
+ # rubocop:disable Layout/LineLength, Layout/ExtraSpacing
40
43
  option :config_file, type: :string, default: 'config/elastic_apm.yml'
41
44
  option :server_url, type: :url, default: 'http://localhost:8200'
42
45
  option :secret_token, type: :string
@@ -73,7 +76,7 @@ module ElasticAPM
73
76
  option :ignore_url_patterns, type: :list, default: [], converter: RegexpList.new
74
77
  option :instrument, type: :bool, default: true
75
78
  option :instrumented_rake_tasks, type: :list, default: []
76
- option :log_level, type: :int, default: Logger::INFO
79
+ option :log_level, type: :int, default: Logger::INFO, converter: LogLevelMap.new
77
80
  option :log_path, type: :string
78
81
  option :metrics_interval, type: :int, default: '30s', converter: Duration.new
79
82
  option :pool_size, type: :int, default: 1
@@ -83,9 +86,8 @@ module ElasticAPM
83
86
  option :proxy_port, type: :int
84
87
  option :proxy_username, type: :string
85
88
  option :recording, type: :bool, default: true
86
- option :sanitize_field_names, type: :list,
87
- default: SANITIZE_FIELD_NAMES_DEFAULT, converter: WildcardPatternList.new
88
- option :server_ca_cert, type: :string
89
+ option :sanitize_field_names, type: :list, default: SANITIZE_FIELD_NAMES_DEFAULT, converter: WildcardPatternList.new
90
+ option :server_ca_cert_file, type: :string
89
91
  option :service_name, type: :string
90
92
  option :service_node_name, type: :string
91
93
  option :service_version, type: :string
@@ -102,7 +104,7 @@ module ElasticAPM
102
104
  option :use_legacy_sql_parser, type: :bool, default: false
103
105
  option :verify_server_cert, type: :bool, default: true
104
106
 
105
- # rubocop:enable Metrics/LineLength, Layout/ExtraSpacing
107
+ # rubocop:enable Layout/LineLength, Layout/ExtraSpacing
106
108
  def initialize(options = {})
107
109
  @options = load_schema
108
110
 
@@ -126,8 +128,7 @@ module ElasticAPM
126
128
  @__root_path ||= Dir.pwd
127
129
  end
128
130
 
129
- attr_accessor :__view_paths, :__root_path
130
- attr_accessor :logger
131
+ attr_accessor :__view_paths, :__root_path, :logger
131
132
 
132
133
  attr_reader :options
133
134
 
@@ -201,8 +202,9 @@ module ElasticAPM
201
202
  def sanitize_field_names=(value)
202
203
  list = WildcardPatternList.new.call(value)
203
204
  defaults = WildcardPatternList.new.call(SANITIZE_FIELD_NAMES_DEFAULT)
205
+ # use regex pattern for comparisons
204
206
  get(:sanitize_field_names).value =
205
- defaults.concat(list).uniq(&:pattern) # use regex pattern for comparisons
207
+ defaults.concat(list).uniq(&:pattern)
206
208
  end
207
209
 
208
210
  def span_frames_min_duration?
@@ -223,8 +225,8 @@ module ElasticAPM
223
225
 
224
226
  @ssl_context ||=
225
227
  OpenSSL::SSL::SSLContext.new.tap do |context|
226
- if server_ca_cert
227
- context.ca_file = server_ca_cert
228
+ if server_ca_cert_file
229
+ context.ca_file = server_ca_cert_file
228
230
  else
229
231
  context.cert_store =
230
232
  OpenSSL::X509::Store.new.tap(&:set_default_paths)
@@ -278,15 +280,20 @@ module ElasticAPM
278
280
  end
279
281
  alias active? active
280
282
 
283
+ def server_ca_cert
284
+ server_ca_cert_file
285
+ end
286
+
281
287
  def disabled_instrumentations=(value)
282
288
  warn '[DEPRECATED] The option disabled_instrumentations has been ' \
283
289
  'renamed to disable_instrumentations to align with other agents.'
284
290
  self.disable_instrumentations = value
285
291
  end
286
292
 
287
- def use_experimental_sql_parser=(value)
288
- warn '[DEPRECATED] The new SQL parser is now the default. To use the old one, '
289
- 'use use_legacy_sql_parser and please report why you wish to do so.'
293
+ def use_experimental_sql_parser=(_value)
294
+ warn '[DEPRECATED] The new SQL parser is now the default. To use the ' \
295
+ 'old one, use use_legacy_sql_parser and please report why you ' \
296
+ 'wish to do so.'
290
297
  end
291
298
 
292
299
  def active=(value)
@@ -295,6 +302,12 @@ module ElasticAPM
295
302
  self.enabled = value
296
303
  end
297
304
 
305
+ def server_ca_cert=(value)
306
+ warn '[DEPRECATED] The option server_ca_cert has been ' \
307
+ 'renamed to server_ca_cert_file to align with other agents.'
308
+ self.server_ca_cert_file = value
309
+ end
310
+
298
311
  private
299
312
 
300
313
  def load_config_file
@@ -313,7 +326,7 @@ module ElasticAPM
313
326
  end
314
327
 
315
328
  def build_logger
316
- Logger.new(log_path == '-' ? STDOUT : log_path).tap do |logger|
329
+ Logger.new(log_path == '-' ? $stdout : log_path).tap do |logger|
317
330
  logger.level = log_level
318
331
  end
319
332
  end
@@ -344,7 +357,8 @@ module ElasticAPM
344
357
  self.logger ||= ::Rails.logger
345
358
 
346
359
  self.__root_path = ::Rails.root.to_s
347
- self.__view_paths = app.config.paths['app/views'].existent + [::Rails.root.to_s]
360
+ self.__view_paths = app.config.paths['app/views'].existent +
361
+ [::Rails.root.to_s]
348
362
  end
349
363
 
350
364
  def rails_app_name(app)
@@ -0,0 +1,47 @@
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 LogLevelMap
24
+ LEVELS = {
25
+ debug: Logger::DEBUG,
26
+ info: Logger::INFO,
27
+ warn: Logger::WARN,
28
+ error: Logger::ERROR,
29
+ fatal: Logger::FATAL,
30
+ trace: Logger::DEBUG,
31
+ warning: Logger::WARN,
32
+ critical: Logger::FATAL,
33
+ off: Logger::FATAL
34
+ }.freeze
35
+
36
+ DEFAULT = Logger::INFO
37
+
38
+ def call(value)
39
+ if value.is_a?(Integer)
40
+ LEVELS.value?(value) ? value : DEFAULT
41
+ else
42
+ LEVELS.fetch(value.to_sym, DEFAULT)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -36,14 +36,9 @@ module ElasticAPM
36
36
  Service = Struct.new(:framework)
37
37
  Framework = Struct.new(:name, :version)
38
38
 
39
- attr_accessor :request
40
- attr_accessor :response
41
- attr_accessor :user
42
- attr_reader :custom
43
- attr_reader :labels
44
- attr_reader :service
39
+ attr_accessor :request, :response, :user
40
+ attr_reader :custom, :labels, :service
45
41
 
46
- # rubocop:disable Metrics/CyclomaticComplexity
47
42
  def empty?
48
43
  return false if labels.any?
49
44
  return false if custom.any?
@@ -53,7 +48,6 @@ module ElasticAPM
53
48
 
54
49
  true
55
50
  end
56
- # rubocop:enable Metrics/CyclomaticComplexity
57
51
 
58
52
  def set_service(framework_name: nil, framework_version: nil)
59
53
  @service = Service.new(
@@ -48,6 +48,7 @@ module ElasticAPM
48
48
  # "authorized" => "graphql.authorized",
49
49
  }.freeze
50
50
 
51
+ # rubocop:disable Style/ExplicitBlockArgument
51
52
  def self.trace(key, data)
52
53
  return yield unless KEYS_TO_NAME.key?(key)
53
54
  return yield unless (transaction = ElasticAPM.current_transaction)
@@ -69,6 +70,7 @@ module ElasticAPM
69
70
 
70
71
  results
71
72
  end
73
+ # rubocop:enable Style/ExplicitBlockArgument
72
74
 
73
75
  class << self
74
76
  private
@@ -25,7 +25,7 @@ module ElasticAPM
25
25
  TYPE = 'external'
26
26
  SUBTYPE = 'grpc'
27
27
 
28
- # rubocop:disable Lint/UnusedMethodArgument
28
+ # rubocop:disable Lint/UnusedMethodArgument, Style/ExplicitBlockArgument
29
29
  def request_response(request:, call:, method:, metadata:)
30
30
  return yield unless (transaction = ElasticAPM.current_transaction)
31
31
  if (trace_context = transaction.trace_context)
@@ -40,7 +40,7 @@ module ElasticAPM
40
40
  yield
41
41
  end
42
42
  end
43
- # rubocop:enable Lint/UnusedMethodArgument
43
+ # rubocop:enable Lint/UnusedMethodArgument, Style/ExplicitBlockArgument
44
44
 
45
45
  private
46
46
 
@@ -71,7 +71,7 @@ module ElasticAPM
71
71
  transaction.done 'success'
72
72
  rescue ::Exception => e
73
73
  ElasticAPM.report(e, handled: false)
74
- transaction.done 'error' if transaction
74
+ transaction&.done 'error'
75
75
  raise
76
76
  ensure
77
77
  ElasticAPM.end_transaction
@@ -239,7 +239,7 @@ module ElasticAPM
239
239
  def set_label(key, value)
240
240
  return unless current_transaction
241
241
 
242
- key = key.to_s.gsub(/[\."\*]/, '_').to_sym
242
+ key = key.to_s.gsub(/[."*]/, '_').to_sym
243
243
  current_transaction.context.labels[key] = value
244
244
  end
245
245
 
@@ -31,7 +31,7 @@ module ElasticAPM
31
31
 
32
32
  def initialize(config)
33
33
  @config = config
34
- @client = HTTP.timeout(0.1)
34
+ @client = HTTP.timeout(connect: 0.1, read: 0.1)
35
35
  end
36
36
 
37
37
  attr_reader :config
@@ -49,6 +49,7 @@ module ElasticAPM
49
49
  :region
50
50
  )
51
51
 
52
+ # rubocop:disable Metrics/CyclomaticComplexity
52
53
  def fetch!
53
54
  case config.cloud_provider
54
55
  when "aws"
@@ -67,6 +68,7 @@ module ElasticAPM
67
68
 
68
69
  self
69
70
  end
71
+ # rubocop:enable Metrics/CyclomaticComplexity
70
72
 
71
73
  private
72
74
 
@@ -52,8 +52,8 @@ module ElasticAPM
52
52
  @version = @config.service_version || Util.git_sha
53
53
  end
54
54
 
55
- attr_reader :name, :node_name, :environment, :agent, :framework, :language,
56
- :runtime, :version
55
+ attr_reader :name, :node_name, :environment, :agent, :framework,
56
+ :language, :runtime, :version
57
57
 
58
58
  private
59
59
 
@@ -81,15 +81,23 @@ module ElasticAPM
81
81
  ENV.fetch('KUBERNETES_POD_UID', kubernetes_pod_uid)
82
82
  end
83
83
 
84
+ # rubocop:disable Style/RegexpLiteral
84
85
  CONTAINER_ID_REGEXES = [
85
86
  %r{^[[:xdigit:]]{64}$},
86
- %r{^[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4,}$}
87
- ]
87
+ %r{
88
+ ^[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]
89
+ {4}-[[:xdigit:]]{4}-[[:xdigit:]]{4,}$
90
+ }x
91
+ ].freeze
88
92
  KUBEPODS_REGEXES = [
89
93
  %r{(?:^/kubepods[^\s]*/pod([^/]+)$)},
90
- %r{(?:^/kubepods\.slice/kubepods-[^/]+\.slice/kubepods-[^/]+-pod([^/]+)\.slice$)}
91
- ]
94
+ %r{
95
+ (?:^/kubepods\.slice/(kubepods-[^/]+\.slice/)?
96
+ kubepods[^/]*-pod([^/]+)\.slice$)
97
+ }x
98
+ ].freeze
92
99
  SYSTEMD_SCOPE_SUFFIX = '.scope'
100
+ # rubocop:enable Style/RegexpLiteral
93
101
 
94
102
  # rubocop:disable Metrics/PerceivedComplexity
95
103
  # rubocop:disable Metrics/CyclomaticComplexity
@@ -125,7 +133,10 @@ module ElasticAPM
125
133
  end
126
134
 
127
135
  if (kubepods_match = match_kubepods(directory))
128
- pod_id = kubepods_match[1] || kubepods_match[2]
136
+ unless (pod_id = kubepods_match[1])
137
+ pod_id = kubepods_match[2]
138
+ pod_id&.tr!('_', '-')
139
+ end
129
140
 
130
141
  self.container_id = container_id
131
142
  self.kubernetes_pod_uid = pod_id
@@ -40,6 +40,7 @@ module ElasticAPM
40
40
  end
41
41
 
42
42
  attr_reader :config, :sets, :callback
43
+
43
44
  def start
44
45
  unless config.collect_metrics?
45
46
  debug 'Skipping metrics'
@@ -214,6 +214,7 @@ module ElasticAPM
214
214
  # @api private
215
215
  class Meminfo
216
216
  attr_reader :total, :available, :page_size
217
+
217
218
  # rubocop:disable Metrics/PerceivedComplexity
218
219
  # rubocop:disable Metrics/CyclomaticComplexity
219
220
  def read!
@@ -123,6 +123,7 @@ module ElasticAPM
123
123
  end
124
124
 
125
125
  attr_accessor :trace_context
126
+
126
127
  def_delegators :trace_context, :trace_id, :id, :parent_id
127
128
 
128
129
  def self.from_header(header)
@@ -345,7 +346,7 @@ module ElasticAPM
345
346
  context = context_from_child_of(child_of) ||
346
347
  context_from_references(references) ||
347
348
  context_from_active_scope(ignore_active_scope)
348
- return context.child if context&.respond_to?(:child)
349
+ return context.child if context.respond_to?(:child)
349
350
 
350
351
  context
351
352
  end
@@ -49,8 +49,7 @@ module ElasticAPM
49
49
  action: nil,
50
50
  context: nil,
51
51
  stacktrace_builder: nil,
52
- sync: nil,
53
- sample_rate: nil
52
+ sync: nil
54
53
  )
55
54
  @name = name
56
55
 
@@ -30,7 +30,7 @@ module ElasticAPM
30
30
  rows_affected: nil
31
31
  )
32
32
  @instance = instance
33
- @statement = statement
33
+ @statement = statement&.encode('utf-8', invalid: :replace, undef: :replace)
34
34
  @type = type
35
35
  @user = user
36
36
  @rows_affected = rows_affected
@@ -55,7 +55,9 @@ module ElasticAPM
55
55
  def self.name_from_payload(payload_object)
56
56
  if payload_object.is_a?(::Delayed::PerformableMethod)
57
57
  performable_method_name(payload_object)
58
- elsif payload_object.class.name == 'ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper'
58
+ elsif payload_object.instance_of?(
59
+ ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper
60
+ )
59
61
  payload_object.job_data['job_class']
60
62
  else
61
63
  payload_object.class.name
@@ -25,9 +25,11 @@ module ElasticAPM
25
25
  def self.without_net_http
26
26
  return yield unless defined?(NetHTTPSpy)
27
27
 
28
+ # rubocop:disable Style/ExplicitBlockArgument
28
29
  ElasticAPM::Spies::NetHTTPSpy.disable_in do
29
30
  yield
30
31
  end
32
+ # rubocop:enable Style/ExplicitBlockArgument
31
33
  end
32
34
 
33
35
  def install
@@ -37,7 +39,12 @@ module ElasticAPM
37
39
  alias :"#{operation_name}_without_apm" :"#{operation_name}"
38
40
 
39
41
  define_method(operation_name) do |params = {}, options = {}|
40
- ElasticAPM.with_span(operation_name, 'db', subtype: 'dynamodb', action: operation_name) do
42
+ ElasticAPM.with_span(
43
+ operation_name,
44
+ 'db',
45
+ subtype: 'dynamodb',
46
+ action: operation_name
47
+ ) do
41
48
  ElasticAPM::Spies::DynamoDBSpy.without_net_http do
42
49
  original_method = method("#{operation_name}_without_apm")
43
50
  original_method.call(params, options)
@@ -31,7 +31,8 @@ module ElasticAPM
31
31
  begin
32
32
  config = ElasticAPM.agent.config
33
33
  ElasticAPM::Transport::Filters::HashSanitizer.new(
34
- key_patterns: config.custom_key_filters + config.sanitize_field_names
34
+ key_patterns: config.custom_key_filters +
35
+ config.sanitize_field_names
35
36
  )
36
37
  end
37
38
  end
@@ -53,7 +54,8 @@ module ElasticAPM
53
54
  if ElasticAPM.agent.config.capture_elasticsearch_queries
54
55
  unless args[1].nil? || args[1].empty?
55
56
  statement << {
56
- body: ElasticAPM::Spies::ElasticsearchSpy.sanitizer.strip_from(args[1])
57
+ body: ElasticAPM::Spies::ElasticsearchSpy
58
+ .sanitizer.strip_from(args[1])
57
59
  }
58
60
  end
59
61
  end
@@ -28,12 +28,14 @@ module ElasticAPM
28
28
  def self.without_net_http
29
29
  return yield unless defined?(NetHTTPSpy)
30
30
 
31
+ # rubocop:disable Style/ExplicitBlockArgument
31
32
  ElasticAPM::Spies::NetHTTPSpy.disable_in do
32
33
  yield
33
34
  end
35
+ # rubocop:enable Style/ExplicitBlockArgument
34
36
  end
35
37
 
36
- # rubocop:disable Metrics/CyclomaticComplexity
38
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
37
39
  def install
38
40
  ::Faraday::Connection.class_eval do
39
41
  alias run_request_without_apm run_request
@@ -96,7 +98,7 @@ module ElasticAPM
96
98
  end
97
99
  end
98
100
  end
99
- # rubocop:enable Metrics/CyclomaticComplexity
101
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
100
102
  end
101
103
 
102
104
  register 'Faraday', 'faraday', FaradaySpy.new
@@ -47,6 +47,7 @@ module ElasticAPM
47
47
  end
48
48
 
49
49
  # rubocop:disable Metrics/CyclomaticComplexity
50
+ # rubocop:disable Metrics/PerceivedComplexity
50
51
  def install
51
52
  Net::HTTP.class_eval do
52
53
  alias request_without_apm request
@@ -103,6 +104,7 @@ module ElasticAPM
103
104
  end
104
105
  end
105
106
  # rubocop:enable Metrics/CyclomaticComplexity
107
+ # rubocop:enable Metrics/PerceivedComplexity
106
108
  end
107
109
 
108
110
  register 'Net::HTTP', 'net/http', NetHTTPSpy.new
@@ -31,6 +31,7 @@ module ElasticAPM
31
31
  @summarizer ||= Sql.summarizer
32
32
  end
33
33
 
34
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
34
35
  def install
35
36
  require 'sequel/database/logging'
36
37
 
@@ -84,6 +85,7 @@ module ElasticAPM
84
85
  end
85
86
  end
86
87
  end
88
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
87
89
  end
88
90
 
89
91
  register 'Sequel', 'sequel', SequelSpy.new
@@ -36,8 +36,8 @@ module ElasticAPM
36
36
  end
37
37
 
38
38
  def initialize(sql)
39
- @sql = sql
40
- @tokenizer = Tokenizer.new(sql)
39
+ @sql = sql.encode('utf-8', invalid: :replace, undef: :replace)
40
+ @tokenizer = Tokenizer.new(@sql)
41
41
  end
42
42
 
43
43
  def parse
@@ -158,9 +158,11 @@ module ElasticAPM
158
158
  def scan_dotted_identifier
159
159
  table = @tokenizer.text
160
160
 
161
+ # rubocop:disable Style/WhileUntilModifier
161
162
  while scan_token(PERIOD) && scan_token(IDENT)
162
163
  table += ".#{@tokenizer.text}"
163
164
  end
165
+ # rubocop:enable Style/WhileUntilModifier
164
166
 
165
167
  table
166
168
  end
@@ -130,7 +130,7 @@ module ElasticAPM
130
130
  end
131
131
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
132
132
 
133
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
133
+ # rubocop:disable Metrics/CyclomaticComplexity
134
134
  def scan_dollar_sign
135
135
  while (peek = peek_char)
136
136
  case peek
@@ -165,7 +165,7 @@ module ElasticAPM
165
165
 
166
166
  OTHER
167
167
  end
168
- # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
168
+ # rubocop:enable Metrics/CyclomaticComplexity
169
169
 
170
170
  def scan_quoted_indentifier(delimiter)
171
171
  while (char = next_char)
@@ -38,6 +38,7 @@ module ElasticAPM
38
38
  :module,
39
39
  :colno
40
40
  )
41
+
41
42
  def build_context(context_line_count)
42
43
  return unless abs_path && context_line_count > 0
43
44
 
@@ -23,7 +23,7 @@ require 'elastic_apm/util/lru_cache'
23
23
  module ElasticAPM
24
24
  # @api private
25
25
  class StacktraceBuilder
26
- JAVA_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/.freeze
26
+ JAVA_FORMAT = /^(.+)\.([^.]+)\(([^:]+):(\d+)\)$/.freeze
27
27
  RUBY_FORMAT = /^(.+?):(\d+)(?::in `(.+?)')?$/.freeze
28
28
 
29
29
  RUBY_VERS_REGEX = %r{ruby(/gems)?[-/](\d+\.)+\d}.freeze
@@ -86,14 +86,13 @@ module ElasticAPM
86
86
  [file, number, method, module_name]
87
87
  end
88
88
 
89
- # rubocop:disable Metrics/CyclomaticComplexity
90
89
  def library_frame?(config, abs_path)
91
90
  return false unless abs_path
92
91
 
93
92
  return true if abs_path.start_with?(GEMS_PATH)
94
93
 
95
94
  if abs_path.start_with?(config.__root_path)
96
- return true if abs_path.start_with?(config.__root_path + '/vendor')
95
+ return true if abs_path.start_with?("#{config.__root_path}/vendor")
97
96
  return false
98
97
  end
99
98
 
@@ -102,7 +101,6 @@ module ElasticAPM
102
101
 
103
102
  false
104
103
  end
105
- # rubocop:enable Metrics/CyclomaticComplexity
106
104
 
107
105
  def strip_load_path(path)
108
106
  return nil if path.nil?
@@ -42,7 +42,6 @@ module ElasticAPM
42
42
  :version, :trace_id, :id, :parent_id, :ensure_parent_id, :recorded?
43
43
 
44
44
  class << self
45
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
46
45
  def parse(legacy_header = nil, env: nil, metadata: nil)
47
46
  unless legacy_header || env || metadata
48
47
  raise ArgumentError, 'TraceContext expects env:, metadata: ' \
@@ -57,7 +56,6 @@ module ElasticAPM
57
56
  trace_context_from_metadata(metadata)
58
57
  end
59
58
  end
60
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
61
59
 
62
60
  private
63
61
 
@@ -27,7 +27,6 @@ module ElasticAPM
27
27
  TRACE_ID_LENGTH = 16
28
28
  ID_LENGTH = 8
29
29
 
30
- # rubocop:disable Metrics/ParameterLists
31
30
  def initialize(
32
31
  version: VERSION,
33
32
  trace_id: nil,
@@ -42,7 +41,6 @@ module ElasticAPM
42
41
  @id = id || hex(ID_LENGTH)
43
42
  @recorded = recorded
44
43
  end
45
- # rubocop:enable Metrics/ParameterLists
46
44
 
47
45
  attr_accessor :version, :id, :trace_id, :parent_id, :recorded
48
46
 
@@ -37,12 +37,13 @@ module ElasticAPM
37
37
  end
38
38
  end
39
39
 
40
+ # @api private
40
41
  class EsEntry
41
42
  ASSIGN = ':'
42
43
  SPLIT = ';'
43
44
 
44
- SHORT_TO_LONG = { 's' => 'sample_rate' }
45
- LONG_TO_SHORT = { 'sample_rate' => 's' }
45
+ SHORT_TO_LONG = { 's' => 'sample_rate' }.freeze
46
+ LONG_TO_SHORT = { 'sample_rate' => 's' }.freeze
46
47
 
47
48
  def initialize(values = nil)
48
49
  parse(values)
@@ -83,7 +84,7 @@ module ElasticAPM
83
84
 
84
85
  values.split(SPLIT).map do |kv|
85
86
  k, v = kv.split(ASSIGN)
86
- next unless SHORT_TO_LONG.keys.include?(k)
87
+ next unless SHORT_TO_LONG.key?(k)
87
88
  send("#{SHORT_TO_LONG[k]}=", v)
88
89
  end
89
90
  end
@@ -136,8 +137,9 @@ module ElasticAPM
136
137
  def split_by_nl_and_comma(str)
137
138
  # HTTP allows multiple headers with the same name, eg. multiple
138
139
  # Set-Cookie headers per response.
139
- # Rack handles this by joining the headers under the same key, separated
140
- # by newlines, see https://www.rubydoc.info/github/rack/rack/file/SPEC
140
+ # Rack handles this by joining the headers under the same key,
141
+ # separated by newlines.
142
+ # See https://www.rubydoc.info/github/rack/rack/file/SPEC
141
143
  String(str).split("\n").map { |s| s.split(',') }.flatten
142
144
  end
143
145
  end
@@ -20,7 +20,6 @@
20
20
  module ElasticAPM
21
21
  # @api private
22
22
  class Transaction
23
-
24
23
  # @api private
25
24
  class Outcome
26
25
  FAILURE = "failure"
@@ -45,10 +44,10 @@ module ElasticAPM
45
44
  def initialize(
46
45
  name = nil,
47
46
  type = nil,
47
+ config:,
48
48
  sampled: true,
49
49
  sample_rate: 1,
50
50
  context: nil,
51
- config:,
52
51
  trace_context: nil
53
52
  )
54
53
  @name = name
@@ -75,7 +74,9 @@ module ElasticAPM
75
74
  unless (@trace_context = trace_context)
76
75
  @trace_context = TraceContext.new(
77
76
  traceparent: TraceContext::Traceparent.new(recorded: sampled),
78
- tracestate: TraceContext::Tracestate.new(sample_rate: sampled ? sample_rate : 0)
77
+ tracestate: TraceContext::Tracestate.new(
78
+ sample_rate: sampled ? sample_rate : 0
79
+ )
79
80
  )
80
81
  end
81
82
 
@@ -102,7 +103,7 @@ module ElasticAPM
102
103
  :started_spans,
103
104
  :timestamp,
104
105
  :trace_context,
105
- :transaction_max_spans
106
+ :transaction_max_spans
106
107
  )
107
108
 
108
109
  alias :collect_metrics? :collect_metrics
@@ -42,7 +42,7 @@ module ElasticAPM
42
42
  Metadata.new(config)
43
43
  )
44
44
  )
45
- @url = config.server_url + '/intake/v2/events'
45
+ @url = "#{config.server_url}/intake/v2/events"
46
46
  @mutex = Mutex.new
47
47
  end
48
48
 
@@ -22,6 +22,7 @@ require 'elastic_apm/util/deep_dup'
22
22
  module ElasticAPM
23
23
  module Transport
24
24
  module Filters
25
+ # @api private
25
26
  class HashSanitizer
26
27
  FILTERED = '[FILTERED]'
27
28
 
@@ -45,7 +46,7 @@ module ElasticAPM
45
46
  end
46
47
 
47
48
  def strip_from!(obj)
48
- return unless obj&.is_a?(Hash)
49
+ return unless obj.is_a?(Hash)
49
50
 
50
51
  obj.each do |k, v|
51
52
  if filter_key?(k)
@@ -28,22 +28,42 @@ module ElasticAPM
28
28
  @config = config
29
29
  @sanitizer =
30
30
  HashSanitizer.new(
31
- key_patterns: config.custom_key_filters + config.sanitize_field_names
31
+ key_patterns: config.custom_key_filters +
32
+ config.sanitize_field_names
32
33
  )
33
34
  end
34
35
 
35
36
  def call(payload)
36
- @sanitizer.strip_from! payload.dig(:transaction, :context, :request, :body)
37
- @sanitizer.strip_from! payload.dig(:transaction, :context, :request, :cookies)
38
- @sanitizer.strip_from! payload.dig(:transaction, :context, :request, :env)
39
- @sanitizer.strip_from! payload.dig(:transaction, :context, :request, :headers)
40
- @sanitizer.strip_from! payload.dig(:transaction, :context, :response, :headers)
41
- @sanitizer.strip_from! payload.dig(:error, :context, :request, :body)
42
- @sanitizer.strip_from! payload.dig(:error, :context, :request, :cookies)
43
- @sanitizer.strip_from! payload.dig(:error, :context, :request, :env)
44
- @sanitizer.strip_from! payload.dig(:error, :context, :request, :headers)
45
- @sanitizer.strip_from! payload.dig(:error, :context, :response, :headers)
46
-
37
+ @sanitizer.strip_from!(
38
+ payload.dig(:transaction, :context, :request, :body)
39
+ )
40
+ @sanitizer.strip_from!(
41
+ payload.dig(:transaction, :context, :request, :cookies)
42
+ )
43
+ @sanitizer.strip_from!(
44
+ payload.dig(:transaction, :context, :request, :env)
45
+ )
46
+ @sanitizer.strip_from!(
47
+ payload.dig(:transaction, :context, :request, :headers)
48
+ )
49
+ @sanitizer.strip_from!(
50
+ payload.dig(:transaction, :context, :response, :headers)
51
+ )
52
+ @sanitizer.strip_from!(
53
+ payload.dig(:error, :context, :request, :body)
54
+ )
55
+ @sanitizer.strip_from!(
56
+ payload.dig(:error, :context, :request, :cookies)
57
+ )
58
+ @sanitizer.strip_from!(
59
+ payload.dig(:error, :context, :request, :env)
60
+ )
61
+ @sanitizer.strip_from!(
62
+ payload.dig(:error, :context, :request, :headers)
63
+ )
64
+ @sanitizer.strip_from!(
65
+ payload.dig(:error, :context, :response, :headers)
66
+ )
47
67
  payload
48
68
  end
49
69
  end
@@ -74,6 +74,7 @@ module ElasticAPM
74
74
  end
75
75
 
76
76
  attr_reader :transaction, :span, :error, :metadata, :metricset
77
+
77
78
  def serialize(resource)
78
79
  case resource
79
80
  when Transaction
@@ -31,7 +31,7 @@ module ElasticAPM
31
31
  labels: build_labels(metadata.labels)
32
32
  }
33
33
 
34
- if (metadata.cloud.provider)
34
+ if metadata.cloud.provider
35
35
  base[:cloud] = build_cloud(metadata.cloud)
36
36
  end
37
37
 
@@ -64,7 +64,7 @@ module ElasticAPM
64
64
  }
65
65
  }
66
66
 
67
- if node_name = service.node_name
67
+ if (node_name = service.node_name)
68
68
  base[:node] = { name: keyword_field(node_name) }
69
69
  end
70
70
 
@@ -93,17 +93,17 @@ module ElasticAPM
93
93
  provider: cloud.provider,
94
94
  account: {
95
95
  id: keyword_field(cloud.account_id),
96
- name: keyword_field(cloud.account_name),
96
+ name: keyword_field(cloud.account_name)
97
97
  },
98
98
  availability_zone: keyword_field(cloud.availability_zone),
99
99
  instance: {
100
100
  id: keyword_field(cloud.instance_id),
101
- name: keyword_field(cloud.instance_name),
101
+ name: keyword_field(cloud.instance_name)
102
102
  },
103
103
  machine: { type: keyword_field(cloud.machine_type) },
104
104
  project: {
105
105
  id: keyword_field(cloud.project_id),
106
- name: keyword_field(cloud.project_name),
106
+ name: keyword_field(cloud.project_name)
107
107
  },
108
108
  region: keyword_field(cloud.region)
109
109
  )
@@ -115,7 +115,7 @@ module ElasticAPM
115
115
 
116
116
  # A bug in APM Server 7.9 disallows null values in `cloud`
117
117
  def strip_nulls!(hash)
118
- hash.keys.each do |key|
118
+ hash.each_key do |key|
119
119
  case value = hash[key]
120
120
  when Hash
121
121
  strip_nulls!(value)
@@ -51,7 +51,6 @@ module ElasticAPM
51
51
 
52
52
  # @api private
53
53
  class ContextSerializer < Serializer
54
- # rubocop:disable Metrics/CyclomaticComplexity
55
54
  def build(context)
56
55
  return unless context
57
56
 
@@ -68,7 +67,6 @@ module ElasticAPM
68
67
 
69
68
  base
70
69
  end
71
- # rubocop:enable Metrics/CyclomaticComplexity
72
70
 
73
71
  private
74
72
 
@@ -23,7 +23,7 @@ module ElasticAPM
23
23
  #
24
24
  # Makes a deep copy of an Array or Hash
25
25
  # NB: Not guaranteed to work well with complex objects, only simple Hash,
26
- # Array, String, Number, etc
26
+ # Array, String, Number, etc.
27
27
  class DeepDup
28
28
  def initialize(obj)
29
29
  @obj = obj
@@ -63,4 +63,3 @@ module ElasticAPM
63
63
  end
64
64
  end
65
65
  end
66
-
@@ -24,7 +24,7 @@ module ElasticAPM
24
24
  # If `minimum` is provided, and the value rounds to 0 (but was not zero to
25
25
  # begin with), use the minimum instead.
26
26
  module PrecisionValidator
27
- extend self
27
+ module_function
28
28
 
29
29
  def validate(value, precision: 0, minimum: nil)
30
30
  float = Float(value)
@@ -18,5 +18,5 @@
18
18
  # frozen_string_literal: true
19
19
 
20
20
  module ElasticAPM
21
- VERSION = '3.12.1'
21
+ VERSION = '3.13.0'
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic-apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.12.1
4
+ version: 3.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikkel Malmberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-16 00:00:00.000000000 Z
11
+ date: 2020-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -69,6 +69,8 @@ files:
69
69
  - ".github/ISSUE_TEMPLATE/Bug_report.md"
70
70
  - ".github/ISSUE_TEMPLATE/Feature_request.md"
71
71
  - ".github/PULL_REQUEST_TEMPLATE.md"
72
+ - ".github/labeler-config.yml"
73
+ - ".github/workflows/labeler.yml"
72
74
  - ".gitignore"
73
75
  - ".pre-commit-config.yaml"
74
76
  - ".rspec"
@@ -126,6 +128,7 @@ files:
126
128
  - lib/elastic_apm/config.rb
127
129
  - lib/elastic_apm/config/bytes.rb
128
130
  - lib/elastic_apm/config/duration.rb
131
+ - lib/elastic_apm/config/log_level_map.rb
129
132
  - lib/elastic_apm/config/options.rb
130
133
  - lib/elastic_apm/config/regexp_list.rb
131
134
  - lib/elastic_apm/config/round_float.rb