elastic-apm 3.11.0 → 3.14.0

Sign up to get free protection for your applications and to get access to all the features.
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