atatus 1.7.0 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +49 -13
- data/LICENSE +1 -1
- data/atatus.gemspec +3 -3
- data/lib/atatus/agent.rb +10 -7
- data/lib/atatus/central_config.rb +19 -8
- data/lib/atatus/collector/layer.rb +1 -1
- data/lib/atatus/{sql_summarizer.rb → config/log_level_map.rb} +22 -28
- data/lib/atatus/config/options.rb +2 -1
- data/lib/atatus/config/regexp_list.rb +1 -1
- data/lib/atatus/config/round_float.rb +31 -0
- data/lib/atatus/config/server_info.rb +50 -0
- data/lib/atatus/config/wildcard_pattern_list.rb +3 -1
- data/lib/atatus/config.rb +91 -70
- data/lib/atatus/context/request/socket.rb +1 -2
- data/lib/atatus/context/response.rb +1 -3
- data/lib/atatus/context.rb +3 -10
- data/lib/atatus/context_builder.rb +3 -3
- data/lib/atatus/error.rb +2 -1
- data/lib/atatus/error_builder.rb +1 -1
- data/lib/atatus/fields.rb +98 -0
- data/lib/atatus/graphql.rb +2 -0
- data/lib/atatus/grpc.rb +5 -7
- data/lib/atatus/instrumenter.rb +29 -25
- data/lib/atatus/metadata/cloud_info.rb +156 -0
- data/lib/atatus/metadata/service_info.rb +3 -3
- data/lib/atatus/metadata/system_info/container_info.rb +20 -8
- data/lib/atatus/metadata/system_info.rb +20 -5
- data/lib/atatus/metadata.rb +3 -1
- data/lib/atatus/metrics/cpu_mem_set.rb +10 -38
- data/lib/atatus/metrics/jvm_set.rb +88 -0
- data/lib/atatus/metrics/metric.rb +2 -0
- data/lib/atatus/metrics.rb +33 -16
- data/lib/atatus/middleware.rb +8 -3
- data/lib/atatus/naively_hashable.rb +1 -0
- data/lib/atatus/normalizers/rails/active_record.rb +25 -7
- data/lib/atatus/normalizers.rb +2 -2
- data/lib/atatus/opentracing.rb +5 -3
- data/lib/atatus/rails.rb +1 -1
- data/lib/atatus/span/context/db.rb +1 -1
- data/lib/atatus/span/context/destination.rb +58 -32
- data/lib/atatus/span/context/http.rb +2 -0
- data/lib/atatus/span/context/links.rb +32 -0
- data/lib/atatus/{sql.rb → span/context/message.rb} +16 -12
- data/lib/atatus/span/context/service.rb +55 -0
- data/lib/atatus/span/context.rb +28 -3
- data/lib/atatus/span.rb +35 -5
- data/lib/atatus/span_helpers.rb +12 -23
- data/lib/atatus/spies/action_dispatch.rb +10 -13
- data/lib/atatus/spies/azure_storage_table.rb +148 -0
- data/lib/atatus/spies/delayed_job.rb +19 -13
- data/lib/atatus/spies/dynamo_db.rb +56 -15
- data/lib/atatus/spies/elasticsearch.rb +54 -39
- data/lib/atatus/spies/faraday.rb +92 -58
- data/lib/atatus/spies/http.rb +33 -37
- data/lib/atatus/spies/json.rb +5 -9
- data/lib/atatus/spies/mongo.rb +26 -19
- data/lib/atatus/spies/net_http.rb +53 -51
- data/lib/atatus/spies/racecar.rb +77 -0
- data/lib/atatus/spies/rake.rb +27 -27
- data/lib/atatus/spies/redis.rb +11 -12
- data/lib/atatus/spies/resque.rb +18 -23
- data/lib/atatus/spies/s3.rb +132 -0
- data/lib/atatus/spies/sequel.rb +11 -2
- data/lib/atatus/spies/shoryuken.rb +4 -6
- data/lib/atatus/spies/sidekiq.rb +23 -31
- data/lib/atatus/spies/sinatra.rb +20 -28
- data/lib/atatus/spies/sneakers.rb +2 -0
- data/lib/atatus/spies/sns.rb +126 -0
- data/lib/atatus/spies/sqs.rb +231 -0
- data/lib/atatus/spies/sucker_punch.rb +20 -22
- data/lib/atatus/spies/tilt.rb +10 -13
- data/lib/atatus/spies.rb +20 -0
- data/lib/atatus/sql/signature.rb +4 -2
- data/lib/atatus/sql/tokenizer.rb +23 -7
- data/lib/atatus/stacktrace/frame.rb +1 -0
- data/lib/atatus/stacktrace_builder.rb +12 -16
- data/lib/atatus/subscriber.rb +1 -0
- data/lib/atatus/trace_context/traceparent.rb +5 -8
- data/lib/atatus/trace_context/tracestate.rb +16 -14
- data/lib/atatus/trace_context.rb +6 -16
- data/lib/atatus/transaction.rb +17 -4
- data/lib/atatus/transport/base.rb +1 -3
- data/lib/atatus/transport/connection/http.rb +11 -3
- data/lib/atatus/transport/connection/proxy_pipe.rb +1 -2
- data/lib/atatus/transport/connection.rb +3 -2
- data/lib/atatus/transport/filters/hash_sanitizer.rb +16 -34
- data/lib/atatus/transport/filters/secrets_filter.rb +35 -12
- data/lib/atatus/transport/serializers/context_serializer.rb +1 -2
- data/lib/atatus/transport/serializers/metadata_serializer.rb +54 -8
- data/lib/atatus/transport/serializers/metricset_serializer.rb +2 -2
- data/lib/atatus/transport/serializers/span_serializer.rb +55 -9
- data/lib/atatus/transport/serializers/transaction_serializer.rb +1 -0
- data/lib/atatus/transport/serializers.rb +9 -6
- data/lib/atatus/transport/user_agent.rb +16 -9
- data/lib/atatus/transport/worker.rb +2 -1
- data/lib/atatus/util/deep_dup.rb +65 -0
- data/lib/atatus/util/precision_validator.rb +46 -0
- data/lib/atatus/util.rb +2 -0
- data/lib/atatus/version.rb +1 -1
- data/lib/atatus.rb +32 -5
- metadata +40 -11
data/lib/atatus/sql/tokenizer.rb
CHANGED
|
@@ -69,7 +69,7 @@ module Atatus
|
|
|
69
69
|
when '[' then scan_quoted_indentifier(']')
|
|
70
70
|
when '(' then LPAREN
|
|
71
71
|
when ')' then RPAREN
|
|
72
|
-
when '/' then
|
|
72
|
+
when '/' then scan_bracketed_or_cql_comment
|
|
73
73
|
when '-' then scan_simple_comment
|
|
74
74
|
when "'" then scan_string_literal
|
|
75
75
|
when ALPHA then scan_keyword_or_identifier(possible_keyword: true)
|
|
@@ -110,7 +110,7 @@ module Atatus
|
|
|
110
110
|
next next_char
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
next next_char if peek
|
|
113
|
+
next next_char if ALPHA.match?(peek)
|
|
114
114
|
|
|
115
115
|
break
|
|
116
116
|
end
|
|
@@ -130,7 +130,7 @@ module Atatus
|
|
|
130
130
|
end
|
|
131
131
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
132
132
|
|
|
133
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
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 Atatus
|
|
|
165
165
|
|
|
166
166
|
OTHER
|
|
167
167
|
end
|
|
168
|
-
# rubocop:enable Metrics/
|
|
168
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
169
169
|
|
|
170
170
|
def scan_quoted_indentifier(delimiter)
|
|
171
171
|
while (char = next_char)
|
|
@@ -185,10 +185,16 @@ module Atatus
|
|
|
185
185
|
IDENT
|
|
186
186
|
end
|
|
187
187
|
|
|
188
|
+
def scan_bracketed_or_cql_comment
|
|
189
|
+
case peek_char
|
|
190
|
+
when '*' then scan_bracketed_comment
|
|
191
|
+
when '/' then scan_cql_comment
|
|
192
|
+
else OTHER
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
188
196
|
# rubocop:disable Metrics/CyclomaticComplexity
|
|
189
197
|
def scan_bracketed_comment
|
|
190
|
-
return OTHER unless peek_char == '*'
|
|
191
|
-
|
|
192
198
|
nesting = 1
|
|
193
199
|
|
|
194
200
|
while (char = next_char)
|
|
@@ -207,6 +213,16 @@ module Atatus
|
|
|
207
213
|
end
|
|
208
214
|
# rubocop:enable Metrics/CyclomaticComplexity
|
|
209
215
|
|
|
216
|
+
def scan_cql_comment
|
|
217
|
+
return OTHER unless peek_char == '/'
|
|
218
|
+
|
|
219
|
+
while (char = next_char)
|
|
220
|
+
break if char == "\n"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
COMMENT
|
|
224
|
+
end
|
|
225
|
+
|
|
210
226
|
def scan_simple_comment
|
|
211
227
|
return OTHER unless peek_char == '-'
|
|
212
228
|
|
|
@@ -251,7 +267,7 @@ module Atatus
|
|
|
251
267
|
when 'e', 'E'
|
|
252
268
|
return NUMBER if exponent
|
|
253
269
|
next_char
|
|
254
|
-
next_char if
|
|
270
|
+
next_char if /[+-]/.match?(peek_char)
|
|
255
271
|
else break
|
|
256
272
|
end
|
|
257
273
|
end
|
|
@@ -23,7 +23,7 @@ require 'atatus/util/lru_cache'
|
|
|
23
23
|
module Atatus
|
|
24
24
|
# @api private
|
|
25
25
|
class StacktraceBuilder
|
|
26
|
-
JAVA_FORMAT = /^(.+)\.([
|
|
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
|
|
@@ -38,7 +38,9 @@ module Atatus
|
|
|
38
38
|
|
|
39
39
|
def initialize(config)
|
|
40
40
|
@config = config
|
|
41
|
-
@cache = Util::LruCache.new(2048,
|
|
41
|
+
@cache = Util::LruCache.new(2048) do |cache, frame|
|
|
42
|
+
build_frame(cache, frame)
|
|
43
|
+
end
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
attr_reader :config
|
|
@@ -59,7 +61,7 @@ module Atatus
|
|
|
59
61
|
|
|
60
62
|
frame = Stacktrace::Frame.new
|
|
61
63
|
frame.abs_path = abs_path
|
|
62
|
-
frame.filename = strip_load_path(
|
|
64
|
+
frame.filename = strip_load_path(abs_path)
|
|
63
65
|
frame.function = function
|
|
64
66
|
frame.lineno = lineno.to_i
|
|
65
67
|
frame.library_frame = library_frame?(config, abs_path)
|
|
@@ -86,14 +88,13 @@ module Atatus
|
|
|
86
88
|
[file, number, method, module_name]
|
|
87
89
|
end
|
|
88
90
|
|
|
89
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
90
91
|
def library_frame?(config, abs_path)
|
|
91
92
|
return false unless abs_path
|
|
92
93
|
|
|
93
94
|
return true if abs_path.start_with?(GEMS_PATH)
|
|
94
95
|
|
|
95
96
|
if abs_path.start_with?(config.__root_path)
|
|
96
|
-
return true if abs_path.start_with?(config.__root_path
|
|
97
|
+
return true if abs_path.start_with?("#{config.__root_path}/vendor")
|
|
97
98
|
return false
|
|
98
99
|
end
|
|
99
100
|
|
|
@@ -102,20 +103,15 @@ module Atatus
|
|
|
102
103
|
|
|
103
104
|
false
|
|
104
105
|
end
|
|
105
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
106
106
|
|
|
107
|
-
def strip_load_path(
|
|
107
|
+
def strip_load_path(path)
|
|
108
108
|
return nil if path.nil?
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
.map(&:to_s)
|
|
116
|
-
.select { |s| path.start_with?(s) }
|
|
117
|
-
.max_by(&:length)
|
|
118
|
-
end
|
|
110
|
+
prefix =
|
|
111
|
+
$LOAD_PATH
|
|
112
|
+
.map(&:to_s)
|
|
113
|
+
.select { |s| path.start_with?(s) }
|
|
114
|
+
.max_by(&:length)
|
|
119
115
|
|
|
120
116
|
prefix ? path[prefix.chomp(File::SEPARATOR).length + 1..-1] : path
|
|
121
117
|
end
|
data/lib/atatus/subscriber.rb
CHANGED
|
@@ -22,27 +22,24 @@ module Atatus
|
|
|
22
22
|
# @api private
|
|
23
23
|
class Traceparent
|
|
24
24
|
VERSION = '00'
|
|
25
|
-
|
|
25
|
+
NON_HEX_REGEX = /[^[:xdigit:]]/.freeze
|
|
26
26
|
|
|
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,
|
|
34
|
-
|
|
33
|
+
parent_id: nil,
|
|
35
34
|
id: nil,
|
|
36
35
|
recorded: true
|
|
37
36
|
)
|
|
38
37
|
@version = version
|
|
39
38
|
@trace_id = trace_id || hex(TRACE_ID_LENGTH)
|
|
40
|
-
|
|
41
|
-
@parent_id = span_id
|
|
39
|
+
@parent_id = parent_id
|
|
42
40
|
@id = id || hex(ID_LENGTH)
|
|
43
41
|
@recorded = recorded
|
|
44
42
|
end
|
|
45
|
-
# rubocop:enable Metrics/ParameterLists
|
|
46
43
|
|
|
47
44
|
attr_accessor :version, :id, :trace_id, :parent_id, :recorded
|
|
48
45
|
|
|
@@ -58,8 +55,8 @@ module Atatus
|
|
|
58
55
|
values[-1] = Util.hex_to_bits(values[-1])
|
|
59
56
|
end
|
|
60
57
|
|
|
61
|
-
raise_invalid(header) if
|
|
62
|
-
raise_invalid(header) if
|
|
58
|
+
raise_invalid(header) if NON_HEX_REGEX.match?(t.trace_id)
|
|
59
|
+
raise_invalid(header) if NON_HEX_REGEX.match?(t.parent_id)
|
|
63
60
|
end
|
|
64
61
|
end
|
|
65
62
|
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
# frozen_string_literal: true
|
|
19
19
|
|
|
20
|
+
require 'atatus/util/precision_validator'
|
|
21
|
+
|
|
20
22
|
module Atatus
|
|
21
23
|
class TraceContext
|
|
22
24
|
# @api private
|
|
@@ -35,12 +37,13 @@ module Atatus
|
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
40
|
+
# @api private
|
|
38
41
|
class EsEntry
|
|
39
42
|
ASSIGN = ':'
|
|
40
43
|
SPLIT = ';'
|
|
41
44
|
|
|
42
|
-
SHORT_TO_LONG = { 's' => 'sample_rate' }
|
|
43
|
-
LONG_TO_SHORT = { 'sample_rate' => 's' }
|
|
45
|
+
SHORT_TO_LONG = { 's' => 'sample_rate' }.freeze
|
|
46
|
+
LONG_TO_SHORT = { 'sample_rate' => 's' }.freeze
|
|
44
47
|
|
|
45
48
|
def initialize(values = nil)
|
|
46
49
|
parse(values)
|
|
@@ -63,13 +66,9 @@ module Atatus
|
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
def sample_rate=(val)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@sample_rate = float
|
|
71
|
-
rescue ArgumentError => e
|
|
72
|
-
nil
|
|
69
|
+
@sample_rate = Util::PrecisionValidator.validate(
|
|
70
|
+
val, precision: 4, minimum: 0.0001
|
|
71
|
+
)
|
|
73
72
|
end
|
|
74
73
|
|
|
75
74
|
def to_s
|
|
@@ -85,7 +84,7 @@ module Atatus
|
|
|
85
84
|
|
|
86
85
|
values.split(SPLIT).map do |kv|
|
|
87
86
|
k, v = kv.split(ASSIGN)
|
|
88
|
-
next unless SHORT_TO_LONG.
|
|
87
|
+
next unless SHORT_TO_LONG.key?(k)
|
|
89
88
|
send("#{SHORT_TO_LONG[k]}=", v)
|
|
90
89
|
end
|
|
91
90
|
end
|
|
@@ -93,6 +92,8 @@ module Atatus
|
|
|
93
92
|
|
|
94
93
|
extend Forwardable
|
|
95
94
|
|
|
95
|
+
ENTRY_SPLIT_REGEX = /\s*[\n,]+\s*/
|
|
96
|
+
|
|
96
97
|
def initialize(entries: {}, sample_rate: nil)
|
|
97
98
|
@entries = entries
|
|
98
99
|
|
|
@@ -108,7 +109,7 @@ module Atatus
|
|
|
108
109
|
split_by_nl_and_comma(header)
|
|
109
110
|
.each_with_object({}) do |entry, hsh|
|
|
110
111
|
k, v = entry.split('=')
|
|
111
|
-
|
|
112
|
+
next unless k && v && !k.empty? && !v.empty?
|
|
112
113
|
hsh[k] =
|
|
113
114
|
case k
|
|
114
115
|
when 'es' then EsEntry.new(v)
|
|
@@ -138,9 +139,10 @@ module Atatus
|
|
|
138
139
|
def split_by_nl_and_comma(str)
|
|
139
140
|
# HTTP allows multiple headers with the same name, eg. multiple
|
|
140
141
|
# Set-Cookie headers per response.
|
|
141
|
-
# Rack handles this by joining the headers under the same key,
|
|
142
|
-
# by newlines
|
|
143
|
-
|
|
142
|
+
# Rack handles this by joining the headers under the same key,
|
|
143
|
+
# separated by newlines.
|
|
144
|
+
# See https://www.rubydoc.info/github/rack/rack/file/SPEC
|
|
145
|
+
String(str).split(ENTRY_SPLIT_REGEX).flatten
|
|
144
146
|
end
|
|
145
147
|
end
|
|
146
148
|
end
|
data/lib/atatus/trace_context.rb
CHANGED
|
@@ -29,10 +29,9 @@ module Atatus
|
|
|
29
29
|
|
|
30
30
|
def initialize(
|
|
31
31
|
traceparent: nil,
|
|
32
|
-
tracestate: nil
|
|
33
|
-
**legacy_traceparent_attrs
|
|
32
|
+
tracestate: nil
|
|
34
33
|
)
|
|
35
|
-
@traceparent = traceparent || Traceparent.new
|
|
34
|
+
@traceparent = traceparent || Traceparent.new
|
|
36
35
|
@tracestate = tracestate || Tracestate.new
|
|
37
36
|
end
|
|
38
37
|
|
|
@@ -42,22 +41,18 @@ module Atatus
|
|
|
42
41
|
:version, :trace_id, :id, :parent_id, :ensure_parent_id, :recorded?
|
|
43
42
|
|
|
44
43
|
class << self
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
unless legacy_header || env || metadata
|
|
44
|
+
def parse(env: nil, metadata: nil)
|
|
45
|
+
unless env || metadata
|
|
48
46
|
raise ArgumentError, 'TraceContext expects env:, metadata: ' \
|
|
49
47
|
'or single argument header string'
|
|
50
48
|
end
|
|
51
49
|
|
|
52
|
-
if
|
|
53
|
-
legacy_parse_from_header(legacy_header)
|
|
54
|
-
elsif env
|
|
50
|
+
if env
|
|
55
51
|
trace_context_from_env(env)
|
|
56
52
|
elsif metadata
|
|
57
53
|
trace_context_from_metadata(metadata)
|
|
58
54
|
end
|
|
59
55
|
end
|
|
60
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
61
56
|
|
|
62
57
|
private
|
|
63
58
|
|
|
@@ -90,11 +85,6 @@ module Atatus
|
|
|
90
85
|
|
|
91
86
|
new(traceparent: parent, tracestate: state)
|
|
92
87
|
end
|
|
93
|
-
|
|
94
|
-
def legacy_parse_from_header(header)
|
|
95
|
-
parent = Traceparent.parse(header)
|
|
96
|
-
new(traceparent: parent)
|
|
97
|
-
end
|
|
98
88
|
end
|
|
99
89
|
|
|
100
90
|
def child
|
|
@@ -106,7 +96,7 @@ module Atatus
|
|
|
106
96
|
def apply_headers
|
|
107
97
|
yield 'Traceparent', traceparent.to_header
|
|
108
98
|
|
|
109
|
-
if tracestate
|
|
99
|
+
if tracestate && !tracestate.to_header.empty?
|
|
110
100
|
yield 'Tracestate', tracestate.to_header
|
|
111
101
|
end
|
|
112
102
|
|
data/lib/atatus/transaction.rb
CHANGED
|
@@ -20,6 +20,17 @@
|
|
|
20
20
|
module Atatus
|
|
21
21
|
# @api private
|
|
22
22
|
class Transaction
|
|
23
|
+
# @api private
|
|
24
|
+
class Outcome
|
|
25
|
+
FAILURE = "failure"
|
|
26
|
+
SUCCESS = "success"
|
|
27
|
+
UNKNOWN = "unknown"
|
|
28
|
+
|
|
29
|
+
def self.from_http_status(code)
|
|
30
|
+
code.to_i >= 500 ? FAILURE : SUCCESS
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
23
34
|
extend Forwardable
|
|
24
35
|
include ChildDurations::Methods
|
|
25
36
|
|
|
@@ -33,10 +44,10 @@ module Atatus
|
|
|
33
44
|
def initialize(
|
|
34
45
|
name = nil,
|
|
35
46
|
type = nil,
|
|
47
|
+
config:,
|
|
36
48
|
sampled: true,
|
|
37
49
|
sample_rate: 1,
|
|
38
50
|
context: nil,
|
|
39
|
-
config:,
|
|
40
51
|
trace_context: nil
|
|
41
52
|
)
|
|
42
53
|
@name = name
|
|
@@ -63,7 +74,9 @@ module Atatus
|
|
|
63
74
|
unless (@trace_context = trace_context)
|
|
64
75
|
@trace_context = TraceContext.new(
|
|
65
76
|
traceparent: TraceContext::Traceparent.new(recorded: sampled),
|
|
66
|
-
tracestate: TraceContext::Tracestate.new(
|
|
77
|
+
tracestate: TraceContext::Tracestate.new(
|
|
78
|
+
sample_rate: sampled ? sample_rate : 0
|
|
79
|
+
)
|
|
67
80
|
)
|
|
68
81
|
end
|
|
69
82
|
|
|
@@ -74,7 +87,7 @@ module Atatus
|
|
|
74
87
|
end
|
|
75
88
|
# rubocop:enable Metrics/ParameterLists
|
|
76
89
|
|
|
77
|
-
attr_accessor :name, :type, :result, :spans, :ruby_time
|
|
90
|
+
attr_accessor :name, :type, :result, :outcome, :spans, :ruby_time
|
|
78
91
|
|
|
79
92
|
attr_reader(
|
|
80
93
|
:breakdown_metrics,
|
|
@@ -90,7 +103,7 @@ module Atatus
|
|
|
90
103
|
:started_spans,
|
|
91
104
|
:timestamp,
|
|
92
105
|
:trace_context,
|
|
93
|
-
:transaction_max_spans
|
|
106
|
+
:transaction_max_spans
|
|
94
107
|
)
|
|
95
108
|
|
|
96
109
|
alias :collect_metrics? :collect_metrics
|
|
@@ -35,7 +35,6 @@ module Atatus
|
|
|
35
35
|
include Logging
|
|
36
36
|
|
|
37
37
|
WATCHER_EXECUTION_INTERVAL = 5
|
|
38
|
-
WATCHER_TIMEOUT_INTERVAL = 4
|
|
39
38
|
WORKER_JOIN_TIMEOUT = 5
|
|
40
39
|
|
|
41
40
|
def initialize(config)
|
|
@@ -112,8 +111,7 @@ module Atatus
|
|
|
112
111
|
|
|
113
112
|
def create_watcher
|
|
114
113
|
@watcher = Concurrent::TimerTask.execute(
|
|
115
|
-
execution_interval: WATCHER_EXECUTION_INTERVAL
|
|
116
|
-
timeout_interval: WATCHER_TIMEOUT_INTERVAL
|
|
114
|
+
execution_interval: WATCHER_EXECUTION_INTERVAL
|
|
117
115
|
) { ensure_worker_count }
|
|
118
116
|
end
|
|
119
117
|
|
|
@@ -74,8 +74,16 @@ module Atatus
|
|
|
74
74
|
debug '%s: Closing request with reason %s', thread_str, reason
|
|
75
75
|
@closed.make_true
|
|
76
76
|
|
|
77
|
-
@wr&.close
|
|
78
|
-
|
|
77
|
+
@wr&.close
|
|
78
|
+
|
|
79
|
+
if @request&.join(5)
|
|
80
|
+
@rd&.close
|
|
81
|
+
return
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
@rd&.close
|
|
85
|
+
|
|
86
|
+
return if @request.nil?
|
|
79
87
|
|
|
80
88
|
error(
|
|
81
89
|
'%s: APM Server not responding in time, terminating request',
|
|
@@ -85,7 +93,7 @@ module Atatus
|
|
|
85
93
|
end
|
|
86
94
|
|
|
87
95
|
def closed?
|
|
88
|
-
@closed.true?
|
|
96
|
+
@rd.closed? && @closed.true?
|
|
89
97
|
end
|
|
90
98
|
|
|
91
99
|
def inspect
|
|
@@ -42,11 +42,12 @@ module Atatus
|
|
|
42
42
|
Metadata.new(config)
|
|
43
43
|
)
|
|
44
44
|
)
|
|
45
|
-
@url = config.server_url
|
|
45
|
+
@url = "#{config.server_url}/intake/v2/events"
|
|
46
46
|
@mutex = Mutex.new
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
attr_reader :http
|
|
50
|
+
|
|
50
51
|
def write(str)
|
|
51
52
|
return false if @config.disable_send
|
|
52
53
|
|
|
@@ -104,7 +105,7 @@ module Atatus
|
|
|
104
105
|
@close_task&.cancel
|
|
105
106
|
@close_task =
|
|
106
107
|
Concurrent::ScheduledTask.execute(@config.api_request_time) do
|
|
107
|
-
flush(:
|
|
108
|
+
flush(:scheduled_flush)
|
|
108
109
|
end
|
|
109
110
|
end
|
|
110
111
|
end
|
|
@@ -17,59 +17,41 @@
|
|
|
17
17
|
|
|
18
18
|
# frozen_string_literal: true
|
|
19
19
|
|
|
20
|
+
require 'atatus/util/deep_dup'
|
|
21
|
+
|
|
20
22
|
module Atatus
|
|
21
23
|
module Transport
|
|
22
24
|
module Filters
|
|
25
|
+
# @api private
|
|
23
26
|
class HashSanitizer
|
|
24
27
|
FILTERED = '[FILTERED]'
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/^pw$/,
|
|
30
|
-
/secret/i,
|
|
31
|
-
/token/i,
|
|
32
|
-
/api[-._]?key/i,
|
|
33
|
-
/session[-._]?id/i,
|
|
34
|
-
/(set[-_])?cookie/i
|
|
35
|
-
].freeze
|
|
36
|
-
|
|
37
|
-
VALUE_FILTERS = [
|
|
38
|
-
# (probably) credit card number
|
|
39
|
-
/^\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}$/
|
|
40
|
-
].freeze
|
|
29
|
+
def initialize(key_patterns:)
|
|
30
|
+
@key_patterns = key_patterns
|
|
31
|
+
end
|
|
41
32
|
|
|
42
|
-
attr_accessor :
|
|
33
|
+
attr_accessor :key_patterns
|
|
43
34
|
|
|
44
|
-
def
|
|
45
|
-
|
|
35
|
+
def strip_from(obj)
|
|
36
|
+
strip_from!(Util::DeepDup.dup(obj))
|
|
46
37
|
end
|
|
47
38
|
|
|
48
|
-
def strip_from!(obj
|
|
49
|
-
return unless obj
|
|
50
|
-
|
|
51
|
-
obj.each do |k, v|
|
|
52
|
-
if filter_key?(k)
|
|
53
|
-
next obj[k] = FILTERED
|
|
54
|
-
end
|
|
39
|
+
def strip_from!(obj)
|
|
40
|
+
return unless obj.is_a?(Hash)
|
|
55
41
|
|
|
42
|
+
obj.each_pair do |k, v|
|
|
56
43
|
case v
|
|
57
44
|
when Hash
|
|
58
45
|
strip_from!(v)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
end
|
|
46
|
+
else
|
|
47
|
+
next unless filter_key?(k)
|
|
48
|
+
obj[k] = FILTERED
|
|
63
49
|
end
|
|
64
50
|
end
|
|
65
51
|
end
|
|
66
52
|
|
|
67
53
|
def filter_key?(key)
|
|
68
|
-
@
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def filter_value?(value)
|
|
72
|
-
VALUE_FILTERS.any? { |regex| regex.match(value) }
|
|
54
|
+
@key_patterns.any? { |regex| regex.match(key) }
|
|
73
55
|
end
|
|
74
56
|
end
|
|
75
57
|
end
|
|
@@ -26,21 +26,44 @@ module Atatus
|
|
|
26
26
|
class SecretsFilter
|
|
27
27
|
def initialize(config)
|
|
28
28
|
@config = config
|
|
29
|
-
@sanitizer =
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
@sanitizer =
|
|
30
|
+
HashSanitizer.new(
|
|
31
|
+
key_patterns: config.custom_key_filters +
|
|
32
|
+
config.sanitize_field_names
|
|
33
|
+
)
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def call(payload)
|
|
35
|
-
@sanitizer.strip_from!
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@sanitizer.strip_from!
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@sanitizer.strip_from!
|
|
42
|
-
|
|
43
|
-
|
|
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
|
+
)
|
|
44
67
|
payload
|
|
45
68
|
end
|
|
46
69
|
end
|