atatus 1.6.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +49 -13
  4. data/LICENSE +1 -1
  5. data/atatus.gemspec +3 -3
  6. data/lib/atatus/agent.rb +18 -7
  7. data/lib/atatus/central_config.rb +19 -8
  8. data/lib/atatus/collector/base.rb +113 -1
  9. data/lib/atatus/collector/builder.rb +8 -0
  10. data/lib/atatus/collector/layer.rb +1 -1
  11. data/lib/atatus/collector/transport.rb +23 -2
  12. data/lib/atatus/{sql_summarizer.rb → config/log_level_map.rb} +22 -28
  13. data/lib/atatus/config/options.rb +2 -1
  14. data/lib/atatus/config/regexp_list.rb +1 -1
  15. data/lib/atatus/config/round_float.rb +31 -0
  16. data/lib/atatus/config/server_info.rb +50 -0
  17. data/lib/atatus/config/wildcard_pattern_list.rb +3 -1
  18. data/lib/atatus/config.rb +94 -70
  19. data/lib/atatus/context/company.rb +38 -0
  20. data/lib/atatus/context/request/socket.rb +1 -2
  21. data/lib/atatus/context/response.rb +1 -3
  22. data/lib/atatus/context.rb +4 -8
  23. data/lib/atatus/context_builder.rb +3 -3
  24. data/lib/atatus/error.rb +2 -1
  25. data/lib/atatus/error_builder.rb +1 -1
  26. data/lib/atatus/fields.rb +98 -0
  27. data/lib/atatus/graphql.rb +2 -0
  28. data/lib/atatus/grpc.rb +5 -7
  29. data/lib/atatus/instrumenter.rb +38 -24
  30. data/lib/atatus/metadata/cloud_info.rb +156 -0
  31. data/lib/atatus/metadata/service_info.rb +3 -3
  32. data/lib/atatus/metadata/system_info/container_info.rb +20 -8
  33. data/lib/atatus/metadata/system_info.rb +20 -5
  34. data/lib/atatus/metadata.rb +3 -1
  35. data/lib/atatus/metrics/cpu_mem_set.rb +10 -38
  36. data/lib/atatus/metrics/jvm_set.rb +88 -0
  37. data/lib/atatus/metrics/metric.rb +2 -0
  38. data/lib/atatus/metrics.rb +32 -16
  39. data/lib/atatus/middleware.rb +8 -3
  40. data/lib/atatus/naively_hashable.rb +1 -0
  41. data/lib/atatus/normalizers/rails/active_record.rb +25 -7
  42. data/lib/atatus/normalizers.rb +2 -2
  43. data/lib/atatus/opentracing.rb +5 -3
  44. data/lib/atatus/rails.rb +1 -1
  45. data/lib/atatus/span/context/db.rb +1 -1
  46. data/lib/atatus/span/context/destination.rb +58 -32
  47. data/lib/atatus/span/context/http.rb +2 -0
  48. data/lib/atatus/span/context/links.rb +32 -0
  49. data/lib/atatus/{sql.rb → span/context/message.rb} +16 -12
  50. data/lib/atatus/span/context/service.rb +55 -0
  51. data/lib/atatus/span/context.rb +28 -3
  52. data/lib/atatus/span.rb +35 -5
  53. data/lib/atatus/span_helpers.rb +12 -23
  54. data/lib/atatus/spies/action_dispatch.rb +10 -13
  55. data/lib/atatus/spies/azure_storage_table.rb +148 -0
  56. data/lib/atatus/spies/delayed_job.rb +19 -13
  57. data/lib/atatus/spies/dynamo_db.rb +56 -15
  58. data/lib/atatus/spies/elasticsearch.rb +54 -39
  59. data/lib/atatus/spies/faraday.rb +92 -58
  60. data/lib/atatus/spies/http.rb +33 -37
  61. data/lib/atatus/spies/json.rb +5 -9
  62. data/lib/atatus/spies/mongo.rb +26 -19
  63. data/lib/atatus/spies/net_http.rb +53 -51
  64. data/lib/atatus/spies/racecar.rb +77 -0
  65. data/lib/atatus/spies/rake.rb +27 -27
  66. data/lib/atatus/spies/redis.rb +11 -12
  67. data/lib/atatus/spies/resque.rb +18 -23
  68. data/lib/atatus/spies/s3.rb +132 -0
  69. data/lib/atatus/spies/sequel.rb +50 -40
  70. data/lib/atatus/spies/shoryuken.rb +4 -6
  71. data/lib/atatus/spies/sidekiq.rb +23 -31
  72. data/lib/atatus/spies/sinatra.rb +20 -28
  73. data/lib/atatus/spies/sneakers.rb +2 -0
  74. data/lib/atatus/spies/sns.rb +126 -0
  75. data/lib/atatus/spies/sqs.rb +231 -0
  76. data/lib/atatus/spies/sucker_punch.rb +20 -22
  77. data/lib/atatus/spies/tilt.rb +10 -13
  78. data/lib/atatus/spies.rb +20 -0
  79. data/lib/atatus/sql/signature.rb +4 -2
  80. data/lib/atatus/sql/tokenizer.rb +23 -7
  81. data/lib/atatus/stacktrace/frame.rb +1 -0
  82. data/lib/atatus/stacktrace_builder.rb +12 -16
  83. data/lib/atatus/subscriber.rb +1 -0
  84. data/lib/atatus/trace_context/traceparent.rb +5 -8
  85. data/lib/atatus/trace_context/tracestate.rb +16 -14
  86. data/lib/atatus/trace_context.rb +6 -16
  87. data/lib/atatus/transaction.rb +25 -4
  88. data/lib/atatus/transport/base.rb +1 -3
  89. data/lib/atatus/transport/connection/http.rb +11 -3
  90. data/lib/atatus/transport/connection/proxy_pipe.rb +1 -2
  91. data/lib/atatus/transport/connection.rb +3 -2
  92. data/lib/atatus/transport/filters/hash_sanitizer.rb +16 -34
  93. data/lib/atatus/transport/filters/secrets_filter.rb +35 -12
  94. data/lib/atatus/transport/serializers/context_serializer.rb +1 -2
  95. data/lib/atatus/transport/serializers/metadata_serializer.rb +54 -8
  96. data/lib/atatus/transport/serializers/metricset_serializer.rb +2 -2
  97. data/lib/atatus/transport/serializers/span_serializer.rb +55 -9
  98. data/lib/atatus/transport/serializers/transaction_serializer.rb +1 -0
  99. data/lib/atatus/transport/serializers.rb +9 -6
  100. data/lib/atatus/transport/user_agent.rb +16 -9
  101. data/lib/atatus/transport/worker.rb +2 -1
  102. data/lib/atatus/util/deep_dup.rb +65 -0
  103. data/lib/atatus/util/precision_validator.rb +46 -0
  104. data/lib/atatus/util.rb +2 -0
  105. data/lib/atatus/version.rb +1 -1
  106. data/lib/atatus.rb +48 -5
  107. metadata +41 -11
@@ -0,0 +1,31 @@
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
+ require 'atatus/util/precision_validator'
21
+
22
+ module Atatus
23
+ class Config
24
+ # @api private
25
+ class RoundFloat
26
+ def call(value)
27
+ Util::PrecisionValidator.validate(value, precision: 4, minimum: 0.0001)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -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 Atatus
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
+
@@ -27,6 +27,8 @@ module Atatus
27
27
  @pattern = convert(str)
28
28
  end
29
29
 
30
+ attr_reader :pattern
31
+
30
32
  def match?(other)
31
33
  !!@pattern.match(other)
32
34
  end
@@ -57,7 +59,7 @@ module Atatus
57
59
 
58
60
  def call(value)
59
61
  value = value.is_a?(String) ? value.split(',') : Array(value)
60
- value.map(&WildcardPattern.method(:new))
62
+ value.map { |p| WildcardPattern.new(p) }
61
63
  end
62
64
  end
63
65
  end
data/lib/atatus/config.rb CHANGED
@@ -17,24 +17,32 @@
17
17
 
18
18
  # frozen_string_literal: true
19
19
 
20
- require 'atatus/config/options'
21
- require 'atatus/config/duration'
22
20
  require 'atatus/config/bytes'
21
+ require 'atatus/config/duration'
22
+ require 'atatus/config/log_level_map'
23
+ require 'atatus/config/options'
24
+ require 'atatus/config/round_float'
23
25
  require 'atatus/config/regexp_list'
24
26
  require 'atatus/config/wildcard_pattern_list'
27
+ require 'atatus/deprecations'
28
+ require 'atatus/config/server_info'
25
29
 
26
30
  module Atatus
27
31
  # @api private
28
32
  class Config
29
33
  extend Options
34
+ extend Deprecations
30
35
 
31
- DEPRECATED_OPTIONS = %i[].freeze
36
+ SANITIZE_FIELD_NAMES_DEFAULT =
37
+ %w[password passwd pwd secret *key *token* *session* *credit* *card* *auth* set-cookie].freeze
32
38
 
33
- # rubocop:disable Metrics/LineLength, Layout/ExtraSpacing
39
+ # rubocop:disable Layout/LineLength, Layout/ExtraSpacing
34
40
  option :app_name, type: :string
35
41
  option :license_key, type: :string
36
42
  option :notify_host, type: :string, default: 'https://apm-rx.atatus.com'
43
+ option :analytics_notify_host, type: :string, default: 'https://an-rx.atatus.com'
37
44
  option :trace_threshold, type: :int, default: 2000
45
+ option :analytics, type: :bool, default: false
38
46
  option :config_file, type: :string, default: 'config/atatus.yml'
39
47
  option :server_url, type: :url, default: ''
40
48
  option :secret_token, type: :string
@@ -49,9 +57,11 @@ module Atatus
49
57
  option :capture_elasticsearch_queries, type: :bool, default: false
50
58
  option :capture_env, type: :bool, default: true
51
59
  option :central_config, type: :bool, default: true
60
+ option :cloud_provider, type: :string, default: 'auto'
52
61
  option :current_user_email_method, type: :string, default: 'email'
53
62
  option :current_user_id_method, type: :string, default: 'id'
54
63
  option :current_user_username_method, type: :string, default: 'username'
64
+ option :current_company_id_method, type: :string, default: 'id'
55
65
  option :custom_key_filters, type: :list, default: [], converter: RegexpList.new
56
66
  option :default_labels, type: :dict, default: {}
57
67
  option :disable_metrics, type: :list, default: [], converter: WildcardPatternList.new
@@ -70,7 +80,8 @@ module Atatus
70
80
  option :ignore_url_patterns, type: :list, default: [], converter: RegexpList.new
71
81
  option :instrument, type: :bool, default: true
72
82
  option :instrumented_rake_tasks, type: :list, default: []
73
- option :log_level, type: :int, default: Logger::INFO
83
+ option :log_ecs_reformatting, type: :string, default: 'off'
84
+ option :log_level, type: :int, default: Logger::INFO, converter: LogLevelMap.new
74
85
  option :log_path, type: :string, default: '-'
75
86
  option :metrics_interval, type: :int, default: '30s', converter: Duration.new
76
87
  option :pool_size, type: :int, default: 1
@@ -80,8 +91,8 @@ module Atatus
80
91
  option :proxy_port, type: :int
81
92
  option :proxy_username, type: :string
82
93
  option :recording, type: :bool, default: true
83
- option :sanitize_field_names, type: :list, default: [], converter: WildcardPatternList.new
84
- option :server_ca_cert, type: :string
94
+ option :sanitize_field_names, type: :list, default: SANITIZE_FIELD_NAMES_DEFAULT, converter: WildcardPatternList.new
95
+ option :server_ca_cert_file, type: :string
85
96
  option :service_name, type: :string
86
97
  option :service_node_name, type: :string
87
98
  option :service_version, type: :string
@@ -93,12 +104,21 @@ module Atatus
93
104
  option :stack_trace_limit, type: :int, default: 999_999
94
105
  option :transaction_ignore_urls, type: :list, default: [], converter: WildcardPatternList.new
95
106
  option :transaction_max_spans, type: :int, default: 500
96
- option :transaction_sample_rate, type: :float, default: 1.0
107
+ option :transaction_sample_rate, type: :float, default: 1.0, converter: RoundFloat.new
97
108
  option :use_atatus_traceparent_header, type: :bool, default: true
98
- option :use_legacy_sql_parser, type: :bool, default: false
99
109
  option :verify_server_cert, type: :bool, default: true
100
110
 
101
- # rubocop:enable Metrics/LineLength, Layout/ExtraSpacing
111
+ def log_ecs_formatting
112
+ log_ecs_reformatting
113
+ end
114
+
115
+ def log_ecs_formatting=(value)
116
+ @options[:log_ecs_reformatting].set(value)
117
+ end
118
+
119
+ deprecate :log_ecs_formatting, :log_ecs_reformatting
120
+
121
+ # rubocop:enable Layout/LineLength, Layout/ExtraSpacing
102
122
  def initialize(options = {})
103
123
  @options = load_schema
104
124
 
@@ -111,19 +131,20 @@ module Atatus
111
131
  self.config_file = env_config_file
112
132
  end
113
133
 
114
- assign(load_config_file)
134
+ assign(load_config_file(self.environment))
115
135
  assign(env)
116
136
 
117
137
  yield self if block_given?
118
138
 
119
- self.logger ||= build_logger
139
+ if self.logger.nil? || self.log_path
140
+ self.logger = build_logger
141
+ end
120
142
 
121
143
  @__view_paths ||= []
122
144
  @__root_path ||= Dir.pwd
123
145
  end
124
146
 
125
- attr_accessor :__view_paths, :__root_path
126
- attr_accessor :logger
147
+ attr_accessor :__view_paths, :__root_path, :logger
127
148
 
128
149
  attr_reader :options
129
150
 
@@ -135,6 +156,7 @@ module Atatus
135
156
  def available_instrumentations
136
157
  %w[
137
158
  action_dispatch
159
+ azure_storage_table
138
160
  delayed_job
139
161
  dynamo_db
140
162
  elasticsearch
@@ -144,13 +166,17 @@ module Atatus
144
166
  mongo
145
167
  net_http
146
168
  rake
169
+ racecar
147
170
  redis
148
171
  resque
172
+ s3
149
173
  sequel
150
174
  shoryuken
151
175
  sidekiq
152
176
  sinatra
153
177
  sneakers
178
+ sns
179
+ sqs
154
180
  sucker_punch
155
181
  tilt
156
182
  ]
@@ -160,11 +186,6 @@ module Atatus
160
186
  available_instrumentations - disable_instrumentations
161
187
  end
162
188
 
163
- def method_missing(name, *args)
164
- return super unless DEPRECATED_OPTIONS.include?(name)
165
- warn "The option `#{name}' has been removed."
166
- end
167
-
168
189
  def replace_options(new_options)
169
190
  return if new_options.nil? || new_options.empty?
170
191
  options_copy = @options.dup
@@ -211,8 +232,8 @@ module Atatus
211
232
 
212
233
  @ssl_context ||=
213
234
  OpenSSL::SSL::SSLContext.new.tap do |context|
214
- if server_ca_cert
215
- context.ca_file = server_ca_cert
235
+ if server_ca_cert_file
236
+ context.ca_file = server_ca_cert_file
216
237
  else
217
238
  context.cert_store =
218
239
  OpenSSL::X509::Store.new.tap(&:set_default_paths)
@@ -231,66 +252,49 @@ module Atatus
231
252
  super.split.first + '>'
232
253
  end
233
254
 
234
- # Deprecations
235
-
236
- def default_tags=(value)
237
- warn '[DEPRECATED] The option default_tags has been renamed to ' \
238
- 'default_labels.'
239
- self.default_labels = value
255
+ def version
256
+ @version ||= ServerInfo.new(self).version
240
257
  end
241
258
 
242
- def ignore_url_patterns=(value)
243
- unless value == self.class.schema[:ignore_url_patterns][:default]
244
- warn '[DEPRECATED] The option ignore_url_patterns is being removed. ' \
245
- 'Consider using transaction_ignore_urls instead.'
246
- end
259
+ private
247
260
 
248
- set(:ignore_url_patterns, value)
249
- end
250
261
 
251
- def custom_key_filters=(value)
252
- unless value == self.class.schema[:custom_key_filters][:default]
253
- warn '[DEPRECATED] The option custom_key_filters is being removed. ' \
254
- 'See sanitize_field_names for an alternative.'
262
+ def parse_erb(file)
263
+ begin
264
+ file.gsub!(/^\s*#.*$/, '#')
265
+ ERB.new(file).result(binding)
266
+ rescue ScriptError, StandardError => e
267
+ warn "[Atatus] FATAL : Failed ERB processing of atatus.yml file. Please check contents of the file. #{e}"
268
+ nil
255
269
  end
256
-
257
- set(:custom_key_filters, value)
258
- end
259
-
260
- def disabled_instrumentations
261
- disable_instrumentations
262
270
  end
263
271
 
264
- def active
265
- enabled
266
- end
267
- alias active? active
272
+ def load_config_file(env)
273
+ return unless File.exist?(config_file)
268
274
 
269
- def disabled_instrumentations=(value)
270
- warn '[DEPRECATED] The option disabled_instrumentations has been ' \
271
- 'renamed to disable_instrumentations to align with other agents.'
272
- self.disable_instrumentations = value
273
- end
275
+ config = {}
274
276
 
275
- def use_experimental_sql_parser=(value)
276
- warn '[DEPRECATED] The new SQL parser is now the default. To use the old one, '
277
- 'use use_legacy_sql_parser and please report why you wish to do so.'
278
- end
277
+ begin
278
+ read = File.read(config_file)
279
+ evaled = parse_erb(read)
280
+
281
+ # YAML.safe_load(evaled)
279
282
 
280
- def active=(value)
281
- warn '[DEPRECATED] The option active has been renamed to enabled ' \
282
- 'to align with other agents and with the remote config.'
283
- self.enabled = value
284
- end
283
+ loaded_config = YAML.load(evaled)
285
284
 
286
- private
285
+ if loaded_config.key?("default")
286
+ unless loaded_config.key?(env)
287
+ warn "[Atatus] ERROR : atatus.yml does not include '#{env}' section!"
288
+ loaded_config = loaded_config["default"]
289
+ end
290
+ end
287
291
 
288
- def load_config_file
289
- return unless File.exist?(config_file)
292
+ config = loaded_config[env] || loaded_config
293
+ rescue ScriptError, StandardError => e
294
+ warn "[Atatus] FATAL : Error parsing atatus.yml configuration '#{e}'"
295
+ end
290
296
 
291
- read = File.read(config_file)
292
- evaled = ERB.new(read).result
293
- YAML.safe_load(evaled)
297
+ config
294
298
  end
295
299
 
296
300
  def load_env
@@ -301,7 +305,25 @@ module Atatus
301
305
  end
302
306
 
303
307
  def build_logger
304
- Logger.new(log_path == '-' ? STDOUT : log_path).tap do |logger|
308
+ if self.log_ecs_reformatting == 'override'
309
+ begin
310
+ return build_ecs_logger
311
+ rescue LoadError
312
+ logger.info "Attempted to use EcsLogging::Logger but the gem couldn't be " \
313
+ "loaded so a ::Logger was created instead. Check if you have the `ecs-logging` " \
314
+ "gem installed and attempt to start the agent again."
315
+ end
316
+ end
317
+
318
+ Logger.new(log_path == '-' ? $stdout : log_path).tap do |logger|
319
+ logger.level = log_level
320
+ end
321
+ end
322
+
323
+ def build_ecs_logger
324
+ require 'ecs_logging/logger'
325
+
326
+ ::EcsLogging::Logger.new(log_path == '-' ? $stdout : log_path).tap do |logger|
305
327
  logger.level = log_level
306
328
  end
307
329
  end
@@ -330,9 +352,11 @@ module Atatus
330
352
  self.framework_name ||= 'Rails'
331
353
  self.framework_version ||= ::Rails::VERSION::STRING
332
354
  self.logger ||= ::Rails.logger
355
+ self.log_level ||= ::Rails.logger.log_level
333
356
 
334
357
  self.__root_path = ::Rails.root.to_s
335
- self.__view_paths = app.config.paths['app/views'].existent + [::Rails.root.to_s]
358
+ self.__view_paths = app.config.paths['app/views'].existent +
359
+ [::Rails.root.to_s]
336
360
  end
337
361
 
338
362
  def rails_app_name(app)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Atatus
4
+ class Context
5
+ # @api private
6
+ class Company
7
+ def initialize(id: nil)
8
+ @id = id
9
+ end
10
+
11
+ def self.infer(config, record)
12
+ return unless record
13
+
14
+ new(
15
+ id: safe_get(record, config.current_company_id_method)&.to_s
16
+ )
17
+ end
18
+
19
+ attr_accessor :id
20
+
21
+ def empty?
22
+ !id
23
+ end
24
+
25
+ def any?
26
+ !empty?
27
+ end
28
+
29
+ class << self
30
+ private
31
+
32
+ def safe_get(record, method_name)
33
+ record.respond_to?(method_name) ? record.send(method_name) : nil
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -26,10 +26,9 @@ module Atatus
26
26
  class Socket
27
27
  def initialize(req)
28
28
  @remote_addr = req.env['REMOTE_ADDR']
29
- @encrypted = req.scheme == 'https'
30
29
  end
31
30
 
32
- attr_reader :remote_addr, :encrypted
31
+ attr_reader :remote_addr
33
32
  end
34
33
  end
35
34
  end
@@ -38,9 +38,7 @@ module Atatus
38
38
  attr_reader :headers
39
39
 
40
40
  def headers=(headers)
41
- @headers = headers&.each_with_object({}) do |(k, v), hsh|
42
- hsh[k] = v.to_s
43
- end
41
+ @headers = headers&.transform_values { |v| v.to_s }
44
42
  end
45
43
  end
46
44
  end
@@ -22,6 +22,7 @@ require 'atatus/context/request/socket'
22
22
  require 'atatus/context/request/url'
23
23
  require 'atatus/context/response'
24
24
  require 'atatus/context/user'
25
+ require 'atatus/context/company'
25
26
 
26
27
  module Atatus
27
28
  # @api private
@@ -36,14 +37,10 @@ module Atatus
36
37
  Service = Struct.new(:framework)
37
38
  Framework = Struct.new(:name, :version)
38
39
 
39
- attr_accessor :request
40
- attr_accessor :response
41
- attr_accessor :user
42
- attr_reader :custom
43
- attr_reader :labels
44
- attr_reader :service
40
+ attr_accessor :request, :response, :user
41
+ attr_reader :custom, :labels, :service
42
+ attr_accessor :company, :response_body
45
43
 
46
- # rubocop:disable Metrics/CyclomaticComplexity
47
44
  def empty?
48
45
  return false if labels.any?
49
46
  return false if custom.any?
@@ -53,7 +50,6 @@ module Atatus
53
50
 
54
51
  true
55
52
  end
56
- # rubocop:enable Metrics/CyclomaticComplexity
57
53
 
58
54
  def set_service(framework_name: nil, framework_version: nil)
59
55
  @service = Service.new(
@@ -44,7 +44,7 @@ module Atatus
44
44
  request = context.request
45
45
 
46
46
  request.socket = Context::Request::Socket.new(req)
47
- request.http_version = build_http_version rack_env
47
+ request.http_version = build_http_version req
48
48
  request.method = req.request_method
49
49
  request.url = Context::Request::Url.new(req)
50
50
 
@@ -104,8 +104,8 @@ module Atatus
104
104
  key.gsub(/^HTTP_/, '').split('_').map(&:capitalize).join('-')
105
105
  end
106
106
 
107
- def build_http_version(rack_env)
108
- return unless (http_version = rack_env['HTTP_VERSION'])
107
+ def build_http_version(req)
108
+ return unless (http_version = req.env['HTTP_VERSION'])
109
109
  http_version.gsub(%r{HTTP/}, '')
110
110
  end
111
111
  end
data/lib/atatus/error.rb CHANGED
@@ -33,7 +33,7 @@ module Atatus
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 Atatus
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,11 +74,11 @@ module Atatus
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
80
81
  }
81
- error.transaction[:name] = transaction.name unless transaction.name.nil?
82
82
  error.trace_id = transaction.trace_id
83
83
  error.parent_id = Atatus.current_span&.id || transaction.id
84
84
 
@@ -0,0 +1,98 @@
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 Atatus
21
+ # An interface for creating simple, value holding objects that correspond to
22
+ # object fields in the API.
23
+ #
24
+ # Example:
25
+ # class MyThing
26
+ # include Fields
27
+ # field :name
28
+ # field :address, default: 'There'
29
+ # end
30
+ #
31
+ # MyThing.new(name: 'AJ').to_h
32
+ # # => { name: 'AJ' }
33
+ # MyThing.new().empty?
34
+ # # => true
35
+ module Fields
36
+ class Field
37
+ def initialize(key, default: nil)
38
+ @key = key
39
+ @default = default
40
+ end
41
+
42
+ attr_reader :key, :default
43
+ end
44
+
45
+ module InstanceMethods
46
+ def initialize(**attrs)
47
+ schema.each do |key, field|
48
+ send(:"#{key}=", field.default)
49
+ end
50
+
51
+ attrs.each do |key, value|
52
+ send(:"#{key}=", value)
53
+ end
54
+
55
+ super()
56
+ end
57
+
58
+ def empty?
59
+ self.class.schema.each do |key, field|
60
+ next if send(key).nil?
61
+ return false
62
+ end
63
+
64
+ true
65
+ end
66
+
67
+ def to_h
68
+ schema.each_with_object({}) do |(key, field), hsh|
69
+ hsh[key] = send(key)
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def schema
76
+ self.class.schema
77
+ end
78
+ end
79
+
80
+ module ClassMethods
81
+ def field(key, default: nil)
82
+ field = Field.new(key, default: default)
83
+ schema[key] = field
84
+
85
+ attr_accessor(key)
86
+ end
87
+
88
+ attr_reader :schema
89
+ end
90
+
91
+ def self.included(cls)
92
+ cls.extend(ClassMethods)
93
+ cls.include(InstanceMethods)
94
+
95
+ cls.instance_variable_set(:@schema, {})
96
+ end
97
+ end
98
+ end
@@ -48,6 +48,7 @@ module Atatus
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 = Atatus.current_transaction)
@@ -69,6 +70,7 @@ module Atatus
69
70
 
70
71
  results
71
72
  end
73
+ # rubocop:enable Style/ExplicitBlockArgument
72
74
 
73
75
  class << self
74
76
  private