elastic-apm 3.11.0 → 3.14.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.ci/.jenkins_codecov.yml +1 -1
  3. data/.ci/.jenkins_exclude.yml +46 -61
  4. data/.ci/.jenkins_framework.yml +3 -4
  5. data/.ci/.jenkins_master_framework.yml +1 -1
  6. data/.ci/.jenkins_ruby.yml +1 -3
  7. data/.ci/Jenkinsfile +22 -2
  8. data/.ci/docker/jruby/11-jdk/Dockerfile +2 -1
  9. data/.ci/docker/jruby/12-jdk/Dockerfile +2 -1
  10. data/.ci/docker/jruby/13-jdk/Dockerfile +2 -1
  11. data/.ci/docker/jruby/7-jdk/Dockerfile +2 -1
  12. data/.ci/docker/jruby/8-jdk/Dockerfile +2 -1
  13. data/.github/labeler-config.yml +3 -0
  14. data/.github/workflows/addToProject.yml +29 -0
  15. data/.github/workflows/labeler.yml +16 -0
  16. data/.rubocop.yml +33 -4
  17. data/CHANGELOG.asciidoc +58 -0
  18. data/Gemfile +23 -9
  19. data/Rakefile +10 -10
  20. data/docs/api.asciidoc +2 -1
  21. data/docs/configuration.asciidoc +20 -3
  22. data/docs/supported-technologies.asciidoc +2 -0
  23. data/lib/elastic_apm.rb +14 -2
  24. data/lib/elastic_apm/central_config.rb +7 -2
  25. data/lib/elastic_apm/config.rb +35 -18
  26. data/lib/elastic_apm/config/log_level_map.rb +47 -0
  27. data/lib/elastic_apm/context.rb +2 -8
  28. data/lib/elastic_apm/graphql.rb +2 -0
  29. data/lib/elastic_apm/grpc.rb +3 -3
  30. data/lib/elastic_apm/instrumenter.rb +1 -1
  31. data/lib/elastic_apm/metadata/cloud_info.rb +6 -4
  32. data/lib/elastic_apm/metadata/service_info.rb +2 -2
  33. data/lib/elastic_apm/metadata/system_info/container_info.rb +16 -5
  34. data/lib/elastic_apm/metrics.rb +1 -0
  35. data/lib/elastic_apm/metrics/cpu_mem_set.rb +1 -0
  36. data/lib/elastic_apm/middleware.rb +8 -3
  37. data/lib/elastic_apm/normalizers/rails/active_record.rb +16 -4
  38. data/lib/elastic_apm/opentracing.rb +2 -1
  39. data/lib/elastic_apm/span.rb +13 -2
  40. data/lib/elastic_apm/span/context/db.rb +1 -1
  41. data/lib/elastic_apm/span/context/http.rb +2 -0
  42. data/lib/elastic_apm/spies/delayed_job.rb +11 -3
  43. data/lib/elastic_apm/spies/dynamo_db.rb +8 -1
  44. data/lib/elastic_apm/spies/elasticsearch.rb +4 -2
  45. data/lib/elastic_apm/spies/faraday.rb +19 -11
  46. data/lib/elastic_apm/spies/http.rb +1 -0
  47. data/lib/elastic_apm/spies/mongo.rb +10 -2
  48. data/lib/elastic_apm/spies/net_http.rb +4 -1
  49. data/lib/elastic_apm/spies/rake.rb +4 -2
  50. data/lib/elastic_apm/spies/resque.rb +4 -2
  51. data/lib/elastic_apm/spies/sequel.rb +12 -1
  52. data/lib/elastic_apm/spies/shoryuken.rb +2 -0
  53. data/lib/elastic_apm/spies/sidekiq.rb +2 -0
  54. data/lib/elastic_apm/spies/sneakers.rb +2 -0
  55. data/lib/elastic_apm/spies/sucker_punch.rb +2 -0
  56. data/lib/elastic_apm/sql/signature.rb +4 -2
  57. data/lib/elastic_apm/sql/tokenizer.rb +2 -2
  58. data/lib/elastic_apm/stacktrace/frame.rb +1 -0
  59. data/lib/elastic_apm/stacktrace_builder.rb +2 -4
  60. data/lib/elastic_apm/trace_context.rb +0 -2
  61. data/lib/elastic_apm/trace_context/traceparent.rb +0 -2
  62. data/lib/elastic_apm/trace_context/tracestate.rb +7 -5
  63. data/lib/elastic_apm/transaction.rb +17 -4
  64. data/lib/elastic_apm/transport/connection.rb +1 -1
  65. data/lib/elastic_apm/transport/filters/hash_sanitizer.rb +8 -1
  66. data/lib/elastic_apm/transport/filters/secrets_filter.rb +32 -10
  67. data/lib/elastic_apm/transport/serializers.rb +1 -0
  68. data/lib/elastic_apm/transport/serializers/metadata_serializer.rb +23 -8
  69. data/lib/elastic_apm/transport/serializers/span_serializer.rb +2 -3
  70. data/lib/elastic_apm/transport/serializers/transaction_serializer.rb +1 -0
  71. data/lib/elastic_apm/util/deep_dup.rb +65 -0
  72. data/lib/elastic_apm/util/precision_validator.rb +1 -1
  73. data/lib/elastic_apm/version.rb +1 -1
  74. metadata +7 -2
@@ -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
 
@@ -17,9 +17,12 @@
17
17
 
18
18
  # frozen_string_literal: true
19
19
 
20
+ require 'elastic_apm/util/deep_dup'
21
+
20
22
  module ElasticAPM
21
23
  module Transport
22
24
  module Filters
25
+ # @api private
23
26
  class HashSanitizer
24
27
  FILTERED = '[FILTERED]'
25
28
 
@@ -38,8 +41,12 @@ module ElasticAPM
38
41
 
39
42
  attr_accessor :key_patterns
40
43
 
44
+ def strip_from(obj)
45
+ strip_from!(Util::DeepDup.dup(obj))
46
+ end
47
+
41
48
  def strip_from!(obj)
42
- return unless obj&.is_a?(Hash)
49
+ return unless obj.is_a?(Hash)
43
50
 
44
51
  obj.each do |k, v|
45
52
  if filter_key?(k)
@@ -28,20 +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, :cookies)
42
- @sanitizer.strip_from! payload.dig(:error, :context, :request, :headers)
43
- @sanitizer.strip_from! payload.dig(:error, :context, :response, :headers)
44
-
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
+ )
45
67
  payload
46
68
  end
47
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
 
@@ -84,34 +84,49 @@ module ElasticAPM
84
84
  hostname: keyword_field(system.hostname),
85
85
  architecture: keyword_field(system.architecture),
86
86
  platform: keyword_field(system.platform),
87
- kubernetes: keyword_object(system.kubernetes)
87
+ kubernetes: keyword_object(system.kubernetes),
88
+ container: keyword_object(system.container)
88
89
  }
89
90
  end
90
91
 
91
92
  def build_cloud(cloud)
92
- {
93
+ strip_nulls!(
93
94
  provider: cloud.provider,
94
95
  account: {
95
96
  id: keyword_field(cloud.account_id),
96
- name: keyword_field(cloud.account_name),
97
+ name: keyword_field(cloud.account_name)
97
98
  },
98
99
  availability_zone: keyword_field(cloud.availability_zone),
99
100
  instance: {
100
101
  id: keyword_field(cloud.instance_id),
101
- name: keyword_field(cloud.instance_name),
102
+ name: keyword_field(cloud.instance_name)
102
103
  },
103
104
  machine: { type: keyword_field(cloud.machine_type) },
104
105
  project: {
105
106
  id: keyword_field(cloud.project_id),
106
- name: keyword_field(cloud.project_name),
107
+ name: keyword_field(cloud.project_name)
107
108
  },
108
109
  region: keyword_field(cloud.region)
109
- }
110
+ )
110
111
  end
111
112
 
112
113
  def build_labels(labels)
113
114
  keyword_object(labels)
114
115
  end
116
+
117
+ # A bug in APM Server 7.9 disallows null values in `cloud`
118
+ def strip_nulls!(hash)
119
+ hash.each_key do |key|
120
+ case value = hash[key]
121
+ when Hash
122
+ strip_nulls!(value)
123
+ hash.delete(key) if value.empty?
124
+ when nil then hash.delete(key)
125
+ end
126
+ end
127
+
128
+ hash
129
+ end
115
130
  end
116
131
  end
117
132
  end
@@ -43,14 +43,14 @@ module ElasticAPM
43
43
  stacktrace: span.stacktrace.to_a,
44
44
  timestamp: span.timestamp,
45
45
  trace_id: span.trace_id,
46
- sample_rate: span.sample_rate
46
+ sample_rate: span.sample_rate,
47
+ outcome: keyword_field(span.outcome)
47
48
  }
48
49
  }
49
50
  end
50
51
 
51
52
  # @api private
52
53
  class ContextSerializer < Serializer
53
- # rubocop:disable Metrics/CyclomaticComplexity
54
54
  def build(context)
55
55
  return unless context
56
56
 
@@ -67,7 +67,6 @@ module ElasticAPM
67
67
 
68
68
  base
69
69
  end
70
- # rubocop:enable Metrics/CyclomaticComplexity
71
70
 
72
71
  private
73
72
 
@@ -35,6 +35,7 @@ module ElasticAPM
35
35
  name: keyword_field(transaction.name),
36
36
  type: keyword_field(transaction.type),
37
37
  result: keyword_field(transaction.result.to_s),
38
+ outcome: keyword_field(transaction.outcome),
38
39
  duration: ms(transaction.duration),
39
40
  timestamp: transaction.timestamp,
40
41
  sampled: transaction.sampled?,
@@ -0,0 +1,65 @@
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
+ module Util
22
+ # @api private
23
+ #
24
+ # Makes a deep copy of an Array or Hash
25
+ # NB: Not guaranteed to work well with complex objects, only simple Hash,
26
+ # Array, String, Number, etc.
27
+ class DeepDup
28
+ def initialize(obj)
29
+ @obj = obj
30
+ end
31
+
32
+ def dup
33
+ deep_dup(@obj)
34
+ end
35
+
36
+ def self.dup(obj)
37
+ new(obj).dup
38
+ end
39
+
40
+ private
41
+
42
+ def deep_dup(obj)
43
+ case obj
44
+ when Hash then hash(obj)
45
+ when Array then array(obj)
46
+ else obj.dup
47
+ end
48
+ end
49
+
50
+ def array(arr)
51
+ arr.map(&method(:deep_dup))
52
+ end
53
+
54
+ def hash(hsh)
55
+ result = hsh.dup
56
+
57
+ hsh.each_pair do |key, value|
58
+ result[key] = deep_dup(value)
59
+ end
60
+
61
+ result
62
+ end
63
+ end
64
+ end
65
+ end
@@ -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.11.0'
21
+ VERSION = '3.14.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.11.0
4
+ version: 3.14.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-10-27 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -69,6 +69,9 @@ 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/addToProject.yml"
74
+ - ".github/workflows/labeler.yml"
72
75
  - ".gitignore"
73
76
  - ".pre-commit-config.yaml"
74
77
  - ".rspec"
@@ -126,6 +129,7 @@ files:
126
129
  - lib/elastic_apm/config.rb
127
130
  - lib/elastic_apm/config/bytes.rb
128
131
  - lib/elastic_apm/config/duration.rb
132
+ - lib/elastic_apm/config/log_level_map.rb
129
133
  - lib/elastic_apm/config/options.rb
130
134
  - lib/elastic_apm/config/regexp_list.rb
131
135
  - lib/elastic_apm/config/round_float.rb
@@ -235,6 +239,7 @@ files:
235
239
  - lib/elastic_apm/transport/user_agent.rb
236
240
  - lib/elastic_apm/transport/worker.rb
237
241
  - lib/elastic_apm/util.rb
242
+ - lib/elastic_apm/util/deep_dup.rb
238
243
  - lib/elastic_apm/util/inflector.rb
239
244
  - lib/elastic_apm/util/lru_cache.rb
240
245
  - lib/elastic_apm/util/precision_validator.rb