atatus 1.3.0 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/Gemfile +72 -22
  4. data/LICENSE +1 -1
  5. data/atatus.gemspec +2 -2
  6. data/lib/atatus/agent.rb +78 -29
  7. data/lib/atatus/central_config/cache_control.rb +18 -1
  8. data/lib/atatus/central_config.rb +72 -27
  9. data/lib/atatus/child_durations.rb +64 -0
  10. data/lib/atatus/collector/base.rb +102 -43
  11. data/lib/atatus/collector/builder.rb +134 -4
  12. data/lib/atatus/collector/hist.rb +54 -0
  13. data/lib/atatus/collector/layer.rb +1 -0
  14. data/lib/atatus/collector/transport.rb +41 -11
  15. data/lib/atatus/config/bytes.rb +17 -0
  16. data/lib/atatus/config/duration.rb +17 -0
  17. data/lib/atatus/config/options.rb +29 -9
  18. data/lib/atatus/config/regexp_list.rb +17 -0
  19. data/lib/atatus/config/wildcard_pattern_list.rb +64 -0
  20. data/lib/atatus/config.rb +129 -28
  21. data/lib/atatus/context/request/socket.rb +18 -1
  22. data/lib/atatus/context/request/url.rb +17 -0
  23. data/lib/atatus/context/request.rb +17 -0
  24. data/lib/atatus/context/response.rb +27 -2
  25. data/lib/atatus/context/user.rb +17 -0
  26. data/lib/atatus/context.rb +32 -1
  27. data/lib/atatus/context_builder.rb +19 -4
  28. data/lib/atatus/deprecations.rb +17 -0
  29. data/lib/atatus/error/exception.rb +24 -0
  30. data/lib/atatus/error/log.rb +17 -0
  31. data/lib/atatus/error.rb +27 -0
  32. data/lib/atatus/error_builder.rb +21 -2
  33. data/lib/atatus/grape.rb +62 -0
  34. data/lib/atatus/graphql.rb +91 -0
  35. data/lib/atatus/grpc.rb +99 -0
  36. data/lib/atatus/instrumenter.rb +135 -30
  37. data/lib/atatus/internal_error.rb +17 -0
  38. data/lib/atatus/logging.rb +17 -2
  39. data/lib/atatus/metadata/process_info.rb +17 -0
  40. data/lib/atatus/metadata/service_info.rb +21 -6
  41. data/lib/atatus/metadata/system_info/container_info.rb +49 -10
  42. data/lib/atatus/metadata/system_info/hw_info.rb +1 -1
  43. data/lib/atatus/metadata/system_info.rb +22 -3
  44. data/lib/atatus/metadata.rb +17 -0
  45. data/lib/atatus/metrics/breakdown_set.rb +31 -0
  46. data/lib/atatus/metrics/{cpu_mem.rb → cpu_mem_set.rb} +110 -63
  47. data/lib/atatus/metrics/metric.rb +140 -0
  48. data/lib/atatus/metrics/set.rb +123 -0
  49. data/lib/atatus/metrics/span_scoped_set.rb +56 -0
  50. data/lib/atatus/metrics/transaction_set.rb +26 -0
  51. data/lib/atatus/metrics/vm_set.rb +58 -0
  52. data/lib/atatus/metrics.rb +69 -27
  53. data/lib/atatus/metricset.rb +48 -4
  54. data/lib/atatus/middleware.rb +28 -8
  55. data/lib/atatus/naively_hashable.rb +17 -0
  56. data/lib/atatus/normalizers/grape/endpoint_run.rb +65 -0
  57. data/lib/atatus/normalizers/grape.rb +22 -0
  58. data/lib/atatus/normalizers/rails/action_controller.rb +44 -0
  59. data/lib/atatus/normalizers/rails/action_mailer.rb +43 -0
  60. data/lib/atatus/normalizers/{action_view.rb → rails/action_view.rb} +17 -0
  61. data/lib/atatus/normalizers/rails/active_record.rb +80 -0
  62. data/lib/atatus/normalizers/rails.rb +27 -0
  63. data/lib/atatus/normalizers.rb +23 -9
  64. data/lib/atatus/opentracing.rb +75 -42
  65. data/lib/atatus/rails.rb +29 -13
  66. data/lib/atatus/railtie.rb +19 -6
  67. data/lib/atatus/resque.rb +29 -0
  68. data/lib/atatus/sinatra.rb +53 -0
  69. data/lib/atatus/span/context/db.rb +43 -0
  70. data/lib/atatus/span/context/destination.rb +77 -0
  71. data/lib/atatus/span/context/http.rb +43 -0
  72. data/lib/atatus/span/context.rb +43 -28
  73. data/lib/atatus/span.rb +44 -15
  74. data/lib/atatus/span_helpers.rb +18 -1
  75. data/lib/atatus/spies/action_dispatch.rb +27 -6
  76. data/lib/atatus/spies/delayed_job.rb +26 -5
  77. data/lib/atatus/spies/dynamo_db.rb +62 -0
  78. data/lib/atatus/spies/elasticsearch.rb +53 -7
  79. data/lib/atatus/spies/faraday.rb +54 -20
  80. data/lib/atatus/spies/http.rb +36 -6
  81. data/lib/atatus/spies/json.rb +18 -0
  82. data/lib/atatus/spies/mongo.rb +41 -10
  83. data/lib/atatus/spies/net_http.rb +52 -11
  84. data/lib/atatus/spies/rake.rb +42 -23
  85. data/lib/atatus/spies/redis.rb +17 -0
  86. data/lib/atatus/spies/resque.rb +57 -0
  87. data/lib/atatus/spies/sequel.rb +54 -17
  88. data/lib/atatus/spies/shoryuken.rb +69 -0
  89. data/lib/atatus/spies/sidekiq.rb +46 -25
  90. data/lib/atatus/spies/sinatra.rb +20 -4
  91. data/lib/atatus/spies/sneakers.rb +74 -0
  92. data/lib/atatus/spies/sucker_punch.rb +58 -0
  93. data/lib/atatus/spies/tilt.rb +20 -1
  94. data/lib/atatus/spies.rb +33 -15
  95. data/lib/atatus/sql/signature.rb +169 -0
  96. data/lib/atatus/sql/tokenizer.rb +264 -0
  97. data/lib/atatus/sql/tokens.rb +63 -0
  98. data/lib/atatus/sql.rb +36 -0
  99. data/lib/atatus/sql_summarizer.rb +24 -6
  100. data/lib/atatus/stacktrace/frame.rb +17 -3
  101. data/lib/atatus/stacktrace.rb +17 -0
  102. data/lib/atatus/stacktrace_builder.rb +23 -3
  103. data/lib/atatus/subscriber.rb +23 -4
  104. data/lib/atatus/trace_context/traceparent.rb +111 -0
  105. data/lib/atatus/trace_context/tracestate.rb +148 -0
  106. data/lib/atatus/trace_context.rb +84 -51
  107. data/lib/atatus/transaction.rb +74 -18
  108. data/lib/atatus/transport/base.rb +44 -27
  109. data/lib/atatus/transport/connection/http.rb +58 -35
  110. data/lib/atatus/transport/connection/proxy_pipe.rb +24 -5
  111. data/lib/atatus/transport/connection.rb +28 -72
  112. data/lib/atatus/transport/filters/hash_sanitizer.rb +77 -0
  113. data/lib/atatus/transport/filters/secrets_filter.rb +30 -55
  114. data/lib/atatus/transport/filters.rb +18 -1
  115. data/lib/atatus/transport/headers.rb +83 -0
  116. data/lib/atatus/transport/serializers/context_serializer.rb +30 -3
  117. data/lib/atatus/transport/serializers/error_serializer.rb +17 -2
  118. data/lib/atatus/transport/serializers/metadata_serializer.rb +44 -22
  119. data/lib/atatus/transport/serializers/metricset_serializer.rb +34 -6
  120. data/lib/atatus/transport/serializers/span_serializer.rb +47 -12
  121. data/lib/atatus/transport/serializers/transaction_serializer.rb +18 -2
  122. data/lib/atatus/transport/serializers.rb +17 -5
  123. data/lib/atatus/transport/user_agent.rb +48 -0
  124. data/lib/atatus/transport/worker.rb +31 -7
  125. data/lib/atatus/util/inflector.rb +17 -0
  126. data/lib/atatus/util/lru_cache.rb +17 -0
  127. data/lib/atatus/util/throttle.rb +17 -0
  128. data/lib/atatus/util.rb +18 -1
  129. data/lib/atatus/version.rb +19 -1
  130. data/lib/atatus.rb +84 -16
  131. metadata +46 -26
  132. data/Rakefile +0 -19
  133. data/bench/.gitignore +0 -2
  134. data/bench/app.rb +0 -53
  135. data/bench/benchmark.rb +0 -36
  136. data/bench/report.rb +0 -55
  137. data/bench/rubyprof.rb +0 -39
  138. data/bench/stackprof.rb +0 -23
  139. data/bin/build_docs +0 -5
  140. data/bin/console +0 -15
  141. data/bin/setup +0 -8
  142. data/bin/with_framework +0 -7
  143. data/lib/atatus/metrics/vm.rb +0 -60
  144. data/lib/atatus/normalizers/action_controller.rb +0 -27
  145. data/lib/atatus/normalizers/action_mailer.rb +0 -26
  146. data/lib/atatus/normalizers/active_record.rb +0 -45
  147. data/lib/atatus/util/prefixed_logger.rb +0 -18
  148. data/vendor/.gitkeep +0 -0
@@ -8,6 +8,7 @@ module Atatus
8
8
  include Logging
9
9
 
10
10
  TXN_ENDPOINT = '/track/apm/txn'.freeze
11
+ TXN_HIST_ENDPOINT = '/track/apm/txn/histogram'.freeze
11
12
  TRACE_ENDPOINT = '/track/apm/trace'.freeze
12
13
  HOSTINFO_ENDPOINT = "/track/apm/hostinfo".freeze
13
14
  ERROR_ENDPOINT = "/track/apm/error".freeze
@@ -18,15 +19,17 @@ module Atatus
18
19
  @config = config
19
20
 
20
21
  @notify_host = @config.notify_host
21
- @uri = URI(@notify_host)
22
- if not @uri.kind_of?(URI::HTTPS) and not @uri.kind_of?(URI::HTTP)
22
+ uri = URI(@notify_host)
23
+ if not uri.kind_of?(URI::HTTPS) and not uri.kind_of?(URI::HTTP)
23
24
  @notify_host = "https://apm-rx.atatus.com"
24
- @uri = URI(@notify_host)
25
25
  end
26
26
 
27
27
  @builder = Atatus::Builder.new(config)
28
28
  @headers = {}
29
29
  @headers['Content-Type'] = "application/json"
30
+
31
+ @blocked = false
32
+ @capture_percentiles = false
30
33
  end
31
34
 
32
35
  def hostinfo(start_time)
@@ -39,6 +42,13 @@ module Atatus
39
42
  post(TXN_ENDPOINT, payload)
40
43
  end
41
44
 
45
+ def txn_hist(start_time, end_time, data)
46
+ if @capture_percentiles == true
47
+ payload = @builder.txn_hist(start_time, end_time, data)
48
+ post(TXN_HIST_ENDPOINT, payload)
49
+ end
50
+ end
51
+
42
52
  def traces(start_time, end_time, data)
43
53
  payload = @builder.traces(start_time, end_time, data)
44
54
  post(TRACE_ENDPOINT, payload)
@@ -68,14 +78,18 @@ module Atatus
68
78
  end
69
79
 
70
80
  begin
71
- request = Net::HTTP::Post.new(endpoint, @headers)
81
+ uri = URI(@notify_host + endpoint)
82
+ uri.query = URI.encode_www_form({"license_key": @config.license_key, "agent_name": AGENT_NAME, "agent_version": VERSION})
83
+
84
+ request = Net::HTTP::Post.new(uri.request_uri, @headers)
72
85
  request.body = ::JSON.dump(data)
73
- http = Net::HTTP.new(@uri.host, @uri.port)
86
+ http = Net::HTTP.new(uri.host, uri.port)
74
87
  http.use_ssl = true
75
88
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
76
89
  response = http.start { |http| http.request(request) }
77
90
  rescue SystemCallError, Timeout::Error, EOFError, SocketError => e
78
- puts "Atatus transport [#{@notify_host}#{endpoint}] failed with exception: #{e}"
91
+ error format('Atatus transport [%s%s] failed with exception: %s', @notify_host, endpoint, e.message)
92
+ return
79
93
  end
80
94
 
81
95
  if @blocked == true
@@ -84,10 +98,25 @@ module Atatus
84
98
 
85
99
  case response
86
100
  when Net::HTTPSuccess
87
- true
101
+ if endpoint == HOSTINFO_ENDPOINT
102
+ @capture_percentiles = false
103
+
104
+ if not response.body
105
+ return
106
+ end
107
+
108
+ resp = JSON.parse response.body
109
+ if resp
110
+ if resp.key?("capturePercentiles")
111
+ @capture_percentiles = resp["capturePercentiles"]
112
+ end
113
+ end
114
+ else
115
+ true
116
+ end
88
117
  when Net::HTTPBadRequest
89
118
  if not response.body
90
- error format('Atatus transport status 400, failed without content')
119
+ error format('Transport status 400, failed without content')
91
120
  return
92
121
  end
93
122
 
@@ -97,7 +126,7 @@ module Atatus
97
126
  @blocked = resp[:blocked]
98
127
  if @blocked == true
99
128
  if resp.key?(:errorMessage)
100
- error format('Atatus blocked from sending data as: %s', resp[:errorMessage])
129
+ error format('Blocked from sending data as: %s', resp[:errorMessage])
101
130
  return
102
131
  end
103
132
  end
@@ -105,11 +134,12 @@ module Atatus
105
134
  end
106
135
 
107
136
  if !resp
108
- error format('Atatus transport status 400, failed with parsed content: %s', resp)
137
+ error format('Transport status 400, failed with parsed content: %s', resp)
109
138
  else
110
- error format('Atatus transport status 400, failed with content: %s', response.body)
139
+ error format('Transport status 400, failed with content: %s', response.body)
111
140
  end
112
141
  else
142
+ error format('Transport unexpected failure: [%s] [%s]', response.code, endpoint)
113
143
  end
114
144
  end
115
145
  end
@@ -1,3 +1,20 @@
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
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  module Atatus
@@ -1,3 +1,20 @@
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
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  module Atatus
@@ -1,3 +1,20 @@
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
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  module Atatus
@@ -33,9 +50,9 @@ module Atatus
33
50
 
34
51
  private
35
52
 
36
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
53
+ # rubocop:disable Metrics/CyclomaticComplexity
37
54
  def normalize(val)
38
- return unless val
55
+ return if val.nil?
39
56
 
40
57
  if @converter
41
58
  return @converter.call(val)
@@ -48,12 +65,13 @@ module Atatus
48
65
  when :bool then normalize_bool(val)
49
66
  when :list then normalize_list(val)
50
67
  when :dict then normalize_dict(val)
68
+ when :url then normalize_url(val)
51
69
  else
52
70
  # raise "Unknown options type '#{type.inspect}'"
53
71
  val
54
72
  end
55
73
  end
56
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
74
+ # rubocop:enable Metrics/CyclomaticComplexity
57
75
 
58
76
  def normalize_bool(val)
59
77
  return val unless val.is_a?(String)
@@ -69,6 +87,11 @@ module Atatus
69
87
  return val unless val.is_a?(String)
70
88
  Hash[val.split(/[&,]/).map { |kv| kv.split('=') }]
71
89
  end
90
+
91
+ def normalize_url(val)
92
+ val = val.to_s
93
+ val.end_with?('/') ? val.chomp('/') : val
94
+ end
72
95
  end
73
96
 
74
97
  # @api private
@@ -77,9 +100,8 @@ module Atatus
77
100
  @schema ||= {}
78
101
  end
79
102
 
80
- def option(*args)
81
- key = args.shift
82
- schema[key] = *args
103
+ def option(key, **args)
104
+ schema[key] = args
83
105
  end
84
106
  end
85
107
 
@@ -87,11 +109,10 @@ module Atatus
87
109
  module InstanceMethods
88
110
  def load_schema
89
111
  Hash[self.class.schema.map do |key, args|
90
- [key, Option.new(key, *args)]
112
+ [key, Option.new(key, **args)]
91
113
  end]
92
114
  end
93
115
 
94
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
95
116
  def method_missing(name, *value)
96
117
  name_str = name.to_s
97
118
 
@@ -110,7 +131,6 @@ module Atatus
110
131
  super
111
132
  end
112
133
  end
113
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
114
134
 
115
135
  def [](key)
116
136
  options[key]
@@ -1,3 +1,20 @@
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
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  module Atatus
@@ -0,0 +1,64 @@
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 WildcardPatternList
24
+ # @api private
25
+ class WildcardPattern
26
+ def initialize(str)
27
+ @pattern = convert(str)
28
+ end
29
+
30
+ def match?(other)
31
+ !!@pattern.match(other)
32
+ end
33
+
34
+ alias :match :match?
35
+
36
+ private
37
+
38
+ def convert(str)
39
+ case_sensitive = false
40
+
41
+ if str.start_with?('(?-i)')
42
+ str = str.gsub(/^\(\?-\i\)/, '')
43
+ case_sensitive = true
44
+ end
45
+
46
+ parts =
47
+ str.chars.each_with_object([]) do |char, arr|
48
+ arr << (char == '*' ? '.*' : Regexp.escape(char))
49
+ end
50
+
51
+ Regexp.new(
52
+ '\A' + parts.join + '\Z',
53
+ case_sensitive ? nil : Regexp::IGNORECASE
54
+ )
55
+ end
56
+ end
57
+
58
+ def call(value)
59
+ value = value.is_a?(String) ? value.split(',') : Array(value)
60
+ value.map(&WildcardPattern.method(:new))
61
+ end
62
+ end
63
+ end
64
+ end
data/lib/atatus/config.rb CHANGED
@@ -1,18 +1,29 @@
1
- # frozen_string_literal: true
2
-
3
- require 'logger'
4
- require 'yaml'
5
- require 'erb'
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.
6
17
 
7
- require 'atatus/util/prefixed_logger'
18
+ # frozen_string_literal: true
8
19
 
9
20
  require 'atatus/config/options'
10
21
  require 'atatus/config/duration'
11
22
  require 'atatus/config/bytes'
12
23
  require 'atatus/config/regexp_list'
24
+ require 'atatus/config/wildcard_pattern_list'
13
25
 
14
26
  module Atatus
15
- # rubocop:disable Metrics/ClassLength
16
27
  # @api private
17
28
  class Config
18
29
  extend Options
@@ -25,27 +36,30 @@ module Atatus
25
36
  option :notify_host, type: :string, default: 'https://apm-rx.atatus.com'
26
37
  option :trace_threshold, type: :int, default: 2000
27
38
  option :config_file, type: :string, default: 'config/atatus.yml'
28
- option :server_url, type: :string, default: ''
39
+ option :server_url, type: :url, default: ''
29
40
  option :secret_token, type: :string
41
+ option :api_key, type: :string
30
42
 
31
- option :active, type: :bool, default: true
32
43
  option :api_buffer_size, type: :int, default: 256
33
44
  option :api_request_size, type: :bytes, default: '750kb', converter: Bytes.new
34
45
  option :api_request_time, type: :float, default: '10s', converter: Duration.new
46
+ option :breakdown_metrics, type: :bool, default: true
35
47
  option :capture_body, type: :string, default: 'off'
36
48
  option :capture_headers, type: :bool, default: true
49
+ option :capture_elasticsearch_queries, type: :bool, default: false
37
50
  option :capture_env, type: :bool, default: true
38
51
  option :central_config, type: :bool, default: true
39
52
  option :current_user_email_method, type: :string, default: 'email'
40
53
  option :current_user_id_method, type: :string, default: 'id'
41
54
  option :current_user_username_method, type: :string, default: 'username'
42
55
  option :custom_key_filters, type: :list, default: [], converter: RegexpList.new
43
- option :default_tags, type: :dict, default: {}
44
56
  option :default_labels, type: :dict, default: {}
57
+ option :disable_metrics, type: :list, default: [], converter: WildcardPatternList.new
45
58
  option :disable_send, type: :bool, default: false
46
59
  option :disable_start_message, type: :bool, default: false
47
- option :disabled_instrumentations, type: :list, default: %w[json]
60
+ option :disable_instrumentations, type: :list, default: %w[json]
48
61
  option :disabled_spies, type: :list, default: []
62
+ option :enabled, type: :bool, default: true
49
63
  option :environment, type: :string, default: ENV['RAILS_ENV'] || ENV['RACK_ENV']
50
64
  option :framework_name, type: :string
51
65
  option :framework_version, type: :string
@@ -65,8 +79,11 @@ module Atatus
65
79
  option :proxy_password, type: :string
66
80
  option :proxy_port, type: :int
67
81
  option :proxy_username, type: :string
82
+ option :recording, type: :bool, default: true
83
+ option :sanitize_field_names, type: :list, default: [], converter: WildcardPatternList.new
68
84
  option :server_ca_cert, type: :string
69
85
  option :service_name, type: :string
86
+ option :service_node_name, type: :string
70
87
  option :service_version, type: :string
71
88
  option :source_lines_error_app_frames, type: :int, default: 5
72
89
  option :source_lines_error_library_frames, type: :int, default: 0
@@ -74,17 +91,17 @@ module Atatus
74
91
  option :source_lines_span_library_frames, type: :int, default: 0
75
92
  option :span_frames_min_duration, type: :float, default: '5ms', converter: Duration.new(default_unit: 'ms')
76
93
  option :stack_trace_limit, type: :int, default: 999_999
94
+ option :transaction_ignore_urls, type: :list, default: [], converter: WildcardPatternList.new
77
95
  option :transaction_max_spans, type: :int, default: 500
78
96
  option :transaction_sample_rate, type: :float, default: 1.0
97
+ option :use_atatus_traceparent_header, type: :bool, default: true
98
+ option :use_legacy_sql_parser, type: :bool, default: false
79
99
  option :verify_server_cert, type: :bool, default: true
80
- # rubocop:enable Metrics/LineLength, Layout/ExtraSpacing
81
100
 
82
- # rubocop:disable Metrics/MethodLength
101
+ # rubocop:enable Metrics/LineLength, Layout/ExtraSpacing
83
102
  def initialize(options = {})
84
103
  @options = load_schema
85
104
 
86
- custom_logger = options.delete(:logger)
87
-
88
105
  assign(options)
89
106
 
90
107
  # Pick out config_file specifically as we need it now to load it,
@@ -99,12 +116,11 @@ module Atatus
99
116
 
100
117
  yield self if block_given?
101
118
 
102
- @logger = custom_logger || build_logger
119
+ self.logger ||= build_logger
103
120
 
104
- @__view_paths = []
105
- @__root_path = Dir.pwd
121
+ @__view_paths ||= []
122
+ @__root_path ||= Dir.pwd
106
123
  end
107
- # rubocop:enable Metrics/MethodLength
108
124
 
109
125
  attr_accessor :__view_paths, :__root_path
110
126
  attr_accessor :logger
@@ -116,28 +132,32 @@ module Atatus
116
132
  update.each { |key, value| send(:"#{key}=", value) }
117
133
  end
118
134
 
119
- # rubocop:disable Metrics/MethodLength
120
135
  def available_instrumentations
121
136
  %w[
137
+ action_dispatch
122
138
  delayed_job
139
+ dynamo_db
123
140
  elasticsearch
124
141
  faraday
125
142
  http
126
143
  json
127
144
  mongo
128
145
  net_http
146
+ rake
129
147
  redis
148
+ resque
130
149
  sequel
150
+ shoryuken
131
151
  sidekiq
132
152
  sinatra
153
+ sneakers
154
+ sucker_punch
133
155
  tilt
134
- rake
135
156
  ]
136
157
  end
137
- # rubocop:enable Metrics/MethodLength
138
158
 
139
159
  def enabled_instrumentations
140
- available_instrumentations - disabled_instrumentations
160
+ available_instrumentations - disable_instrumentations
141
161
  end
142
162
 
143
163
  def method_missing(name, *args)
@@ -145,6 +165,15 @@ module Atatus
145
165
  warn "The option `#{name}' has been removed."
146
166
  end
147
167
 
168
+ def replace_options(new_options)
169
+ return if new_options.nil? || new_options.empty?
170
+ options_copy = @options.dup
171
+ new_options.each do |key, value|
172
+ options_copy.fetch(key.to_sym).set(value)
173
+ end
174
+ @options = options_copy
175
+ end
176
+
148
177
  def app=(app)
149
178
  case app_type?(app)
150
179
  when :sinatra
@@ -177,10 +206,83 @@ module Atatus
177
206
  @span_frames_min_duration_us ||= span_frames_min_duration * 1_000_000
178
207
  end
179
208
 
209
+ def ssl_context
210
+ return unless use_ssl?
211
+
212
+ @ssl_context ||=
213
+ OpenSSL::SSL::SSLContext.new.tap do |context|
214
+ if server_ca_cert
215
+ context.ca_file = server_ca_cert
216
+ else
217
+ context.cert_store =
218
+ OpenSSL::X509::Store.new.tap(&:set_default_paths)
219
+ end
220
+
221
+ context.verify_mode =
222
+ if verify_server_cert
223
+ OpenSSL::SSL::VERIFY_PEER
224
+ else
225
+ OpenSSL::SSL::VERIFY_NONE
226
+ end
227
+ end
228
+ end
229
+
180
230
  def inspect
181
231
  super.split.first + '>'
182
232
  end
183
233
 
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
240
+ end
241
+
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
247
+
248
+ set(:ignore_url_patterns, value)
249
+ end
250
+
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.'
255
+ end
256
+
257
+ set(:custom_key_filters, value)
258
+ end
259
+
260
+ def disabled_instrumentations
261
+ disable_instrumentations
262
+ end
263
+
264
+ def active
265
+ enabled
266
+ end
267
+ alias active? active
268
+
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
274
+
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
279
+
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
285
+
184
286
  private
185
287
 
186
288
  def load_config_file
@@ -219,18 +321,18 @@ module Atatus
219
321
  def set_sinatra(app)
220
322
  self.service_name = format_name(service_name || app.to_s)
221
323
  self.framework_name = framework_name || 'Sinatra'
222
- self.framework_version = framework_version || Sinatra::VERSION
324
+ self.framework_version = framework_version || ::Sinatra::VERSION
223
325
  self.__root_path = Dir.pwd
224
326
  end
225
327
 
226
- def set_rails(app) # rubocop:disable Metrics/AbcSize
328
+ def set_rails(app)
227
329
  self.service_name ||= format_name(service_name || rails_app_name(app))
228
330
  self.framework_name ||= 'Rails'
229
331
  self.framework_version ||= ::Rails::VERSION::STRING
230
332
  self.logger ||= ::Rails.logger
231
333
 
232
334
  self.__root_path = ::Rails.root.to_s
233
- self.__view_paths = app.config.paths['app/views'].existent
335
+ self.__view_paths = app.config.paths['app/views'].existent + [::Rails.root.to_s]
234
336
  end
235
337
 
236
338
  def rails_app_name(app)
@@ -242,8 +344,7 @@ module Atatus
242
344
  end
243
345
 
244
346
  def format_name(str)
245
- str && str.gsub('::', '_')
347
+ str&.gsub('::', '_')
246
348
  end
247
349
  end
248
- # rubocop:enable Metrics/ClassLength
249
350
  end
@@ -1,3 +1,20 @@
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
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  module Atatus
@@ -8,7 +25,7 @@ module Atatus
8
25
  # @api private
9
26
  class Socket
10
27
  def initialize(req)
11
- @remote_addr = req.ip
28
+ @remote_addr = req.env['REMOTE_ADDR']
12
29
  @encrypted = req.scheme == 'https'
13
30
  end
14
31
 
@@ -1,3 +1,20 @@
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
+
1
18
  # frozen_string_literal: true
2
19
 
3
20
  module Atatus