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/spies/json.rb
CHANGED
|
@@ -25,15 +25,11 @@ module Atatus
|
|
|
25
25
|
# @api private
|
|
26
26
|
class JSONSpy
|
|
27
27
|
def install
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
span_class_method :parse!, 'JSON#parse!', 'json.parse'
|
|
34
|
-
span_class_method :generate, 'JSON#generate', 'json.generate'
|
|
35
|
-
end
|
|
36
|
-
|
|
28
|
+
::JSON.class_eval do
|
|
29
|
+
include SpanHelpers
|
|
30
|
+
span_class_method :parse, 'JSON#parse', 'json.parse'
|
|
31
|
+
span_class_method :parse!, 'JSON#parse!', 'json.parse'
|
|
32
|
+
span_class_method :generate, 'JSON#generate', 'json.generate'
|
|
37
33
|
end
|
|
38
34
|
end
|
|
39
35
|
end
|
data/lib/atatus/spies/mongo.rb
CHANGED
|
@@ -23,14 +23,10 @@ module Atatus
|
|
|
23
23
|
# @api private
|
|
24
24
|
class MongoSpy
|
|
25
25
|
def install
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Subscriber.new
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
end
|
|
26
|
+
::Mongo::Monitoring::Global.subscribe(
|
|
27
|
+
::Mongo::Monitoring::COMMAND,
|
|
28
|
+
Subscriber.new
|
|
29
|
+
)
|
|
34
30
|
end
|
|
35
31
|
|
|
36
32
|
# @api private
|
|
@@ -39,8 +35,10 @@ module Atatus
|
|
|
39
35
|
SUBTYPE = 'mongodb'
|
|
40
36
|
ACTION = 'query'
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
EVENT_KEY = :__atatus_instrumenter_mongo_events_key
|
|
39
|
+
|
|
40
|
+
def events
|
|
41
|
+
Thread.current[EVENT_KEY] ||= []
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
def started(event)
|
|
@@ -48,11 +46,19 @@ module Atatus
|
|
|
48
46
|
end
|
|
49
47
|
|
|
50
48
|
def failed(event)
|
|
51
|
-
pop_event(event)
|
|
49
|
+
if (span = pop_event(event))
|
|
50
|
+
span.outcome = Span::Outcome::FAILURE
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
span
|
|
52
54
|
end
|
|
53
55
|
|
|
54
56
|
def succeeded(event)
|
|
55
|
-
pop_event(event)
|
|
57
|
+
if span = pop_event(event)
|
|
58
|
+
span.outcome = Span::Outcome::SUCCESS
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
span
|
|
56
62
|
end
|
|
57
63
|
|
|
58
64
|
private
|
|
@@ -66,7 +72,7 @@ module Atatus
|
|
|
66
72
|
# and the collection name is at the key `collection`
|
|
67
73
|
collection =
|
|
68
74
|
if event.command[event.command_name] == 1 ||
|
|
69
|
-
|
|
75
|
+
event.command[event.command_name].is_a?(BSON::Int64)
|
|
70
76
|
event.command[:collection]
|
|
71
77
|
else
|
|
72
78
|
event.command[event.command_name]
|
|
@@ -85,14 +91,13 @@ module Atatus
|
|
|
85
91
|
context: build_context(event)
|
|
86
92
|
)
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
events << span
|
|
89
95
|
end
|
|
90
96
|
|
|
91
97
|
def pop_event(event)
|
|
92
|
-
span = @events.delete(event.operation_id)
|
|
93
98
|
return unless (curr = Atatus.current_span)
|
|
94
99
|
|
|
95
|
-
curr ==
|
|
100
|
+
curr == events[-1] && Atatus.end_span(events.pop)
|
|
96
101
|
end
|
|
97
102
|
|
|
98
103
|
def build_context(event)
|
|
@@ -104,9 +109,11 @@ module Atatus
|
|
|
104
109
|
user: nil
|
|
105
110
|
},
|
|
106
111
|
destination: {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
service: {
|
|
113
|
+
name: SUBTYPE,
|
|
114
|
+
resource: SUBTYPE,
|
|
115
|
+
type: TYPE
|
|
116
|
+
}
|
|
110
117
|
}
|
|
111
118
|
)
|
|
112
119
|
end
|
|
@@ -22,17 +22,17 @@ module Atatus
|
|
|
22
22
|
module Spies
|
|
23
23
|
# @api private
|
|
24
24
|
class NetHTTPSpy
|
|
25
|
-
|
|
26
|
-
TYPE = '
|
|
27
|
-
SUBTYPE = '
|
|
25
|
+
DISABLE_KEY = :__atatus_net_http_disabled
|
|
26
|
+
TYPE = 'external'
|
|
27
|
+
SUBTYPE = 'http'
|
|
28
28
|
|
|
29
29
|
class << self
|
|
30
30
|
def disabled=(disabled)
|
|
31
|
-
Thread.current[
|
|
31
|
+
Thread.current[DISABLE_KEY] = disabled
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def disabled?
|
|
35
|
-
Thread.current[
|
|
35
|
+
Thread.current[DISABLE_KEY] ||= false
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def disable_in
|
|
@@ -46,66 +46,68 @@ module Atatus
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
# @api private
|
|
50
|
+
module Ext
|
|
51
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
52
|
+
def request(req, body = nil, &block)
|
|
53
|
+
unless (transaction = Atatus.current_transaction)
|
|
54
|
+
return super(req, body, &block)
|
|
55
|
+
end
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
if Atatus::Spies::NetHTTPSpy.disabled?
|
|
58
|
+
return super(req, body, &block)
|
|
59
|
+
end
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return request_without_apm(req, body, &block)
|
|
59
|
-
end
|
|
61
|
+
host = req['host']&.split(':')&.first || address || 'localhost'
|
|
62
|
+
method = req.method.to_s.upcase
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
return request_without_apm(req, body, &block)
|
|
63
|
-
end
|
|
64
|
+
uri_or_path = URI(req.path)
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
# Support the case where a whole url is passed as a path to a nil host
|
|
67
|
+
uri =
|
|
68
|
+
if uri_or_path.host
|
|
69
|
+
uri_or_path
|
|
70
|
+
else
|
|
67
71
|
path, query = req.path.split('?')
|
|
68
|
-
|
|
69
72
|
url = use_ssl? ? +'https://' : +'http://'
|
|
70
73
|
url << host
|
|
71
74
|
url << ":#{port}" if port
|
|
72
75
|
url << path
|
|
73
76
|
url << "?#{query}" if query
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
destination =
|
|
77
|
-
Atatus::Span::Context::Destination.from_uri(uri)
|
|
78
|
-
|
|
79
|
-
context =
|
|
80
|
-
Atatus::Span::Context.new(
|
|
81
|
-
http: { url: uri, method: method },
|
|
82
|
-
destination: destination
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
Atatus.with_span(
|
|
86
|
-
"#{method} #{host}",
|
|
87
|
-
TYPE,
|
|
88
|
-
subtype: SUBTYPE,
|
|
89
|
-
action: method,
|
|
90
|
-
context: context
|
|
91
|
-
) do |span|
|
|
92
|
-
trace_context = span&.trace_context || transaction.trace_context
|
|
93
|
-
trace_context.apply_headers { |key, value| req[key] = value }
|
|
94
|
-
|
|
95
|
-
result = request_without_apm(req, body, &block)
|
|
96
|
-
|
|
97
|
-
if (http = span&.context&.http)
|
|
98
|
-
http.status_code = result.code
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
result
|
|
102
|
-
end
|
|
77
|
+
URI(url)
|
|
103
78
|
end
|
|
104
|
-
end
|
|
105
79
|
|
|
80
|
+
context =
|
|
81
|
+
Atatus::Span::Context.new(
|
|
82
|
+
http: { url: uri, method: method },
|
|
83
|
+
destination: Atatus::Span::Context::Destination.from_uri(uri, type: SUBTYPE)
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
Atatus.with_span(
|
|
87
|
+
"#{method} #{host}",
|
|
88
|
+
TYPE,
|
|
89
|
+
subtype: SUBTYPE,
|
|
90
|
+
context: context
|
|
91
|
+
) do |span|
|
|
92
|
+
trace_context = span&.trace_context || transaction.trace_context
|
|
93
|
+
trace_context.apply_headers { |key, value| req[key] = value }
|
|
94
|
+
|
|
95
|
+
result = super(req, body, &block)
|
|
96
|
+
|
|
97
|
+
if (http = span&.context&.http)
|
|
98
|
+
http.status_code = result.code
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
span&.outcome = Span::Outcome.from_http_status(result.code)
|
|
102
|
+
result
|
|
103
|
+
end
|
|
106
104
|
end
|
|
105
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def install
|
|
109
|
+
Net::HTTP.prepend(Ext)
|
|
107
110
|
end
|
|
108
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
109
111
|
end
|
|
110
112
|
|
|
111
113
|
register 'Net::HTTP', 'net/http', NetHTTPSpy.new
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
begin
|
|
19
|
+
require 'active_support/notifications'
|
|
20
|
+
require 'active_support/subscriber'
|
|
21
|
+
|
|
22
|
+
# frozen_string_literal: true
|
|
23
|
+
module Atatus
|
|
24
|
+
# @api private
|
|
25
|
+
module Spies
|
|
26
|
+
# @api private
|
|
27
|
+
class RacecarSpy
|
|
28
|
+
TYPE = 'kafka'
|
|
29
|
+
SUBTYPE = 'racecar'
|
|
30
|
+
|
|
31
|
+
# @api private
|
|
32
|
+
class ConsumerSubscriber < ActiveSupport::Subscriber
|
|
33
|
+
def start_process_message(event)
|
|
34
|
+
start_process_transaction(event: event, kind: 'process_message')
|
|
35
|
+
end
|
|
36
|
+
def process_message(_event)
|
|
37
|
+
Atatus.end_transaction
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def start_process_batch(event)
|
|
41
|
+
start_process_transaction(event: event, kind: 'process_batch')
|
|
42
|
+
end
|
|
43
|
+
def process_batch(_event)
|
|
44
|
+
Atatus.end_transaction
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private # only public methods will be subscribed
|
|
48
|
+
|
|
49
|
+
def start_process_transaction(event:, kind:)
|
|
50
|
+
Atatus.start_transaction(kind, TYPE)
|
|
51
|
+
Atatus.current_transaction.context.set_service(framework_name: 'racecar', framework_version: Racecar::VERSION)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class ProducerSubscriber < ActiveSupport::Subscriber
|
|
56
|
+
def start_deliver_message(event)
|
|
57
|
+
Atatus.start_transaction('deliver_message',TYPE)
|
|
58
|
+
Atatus.current_transaction.context.set_service(framework_name: 'racecar', framework_version: Racecar::VERSION)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def deliver_message(_event)
|
|
62
|
+
Atatus.end_transaction
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def install
|
|
67
|
+
ConsumerSubscriber.attach_to(:racecar)
|
|
68
|
+
ProducerSubscriber.attach_to(:racecar)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
register 'Racecar', 'racecar', RacecarSpy.new
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
rescue LoadError
|
|
76
|
+
# no active support available
|
|
77
|
+
end
|
data/lib/atatus/spies/rake.rb
CHANGED
|
@@ -22,43 +22,43 @@ module Atatus
|
|
|
22
22
|
module Spies
|
|
23
23
|
# @api private
|
|
24
24
|
class RakeSpy
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
alias execute_without_apm execute
|
|
30
|
-
|
|
31
|
-
def execute(*args)
|
|
32
|
-
agent = Atatus.start
|
|
25
|
+
# @api private
|
|
26
|
+
module Ext
|
|
27
|
+
def execute(*args)
|
|
28
|
+
agent = Atatus.start
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
transaction =
|
|
39
|
-
Atatus.start_transaction("Rake::Task[#{name}]", 'Rake')
|
|
30
|
+
unless agent && agent.config.instrumented_rake_tasks.include?(name)
|
|
31
|
+
return super(*args)
|
|
32
|
+
end
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
transaction =
|
|
35
|
+
Atatus.start_transaction("Rake::Task[#{name}]", 'Rake')
|
|
43
36
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
transaction.result = 'error' if transaction
|
|
47
|
-
Atatus.report(e)
|
|
37
|
+
begin
|
|
38
|
+
result = super(*args)
|
|
48
39
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
40
|
+
transaction&.result = 'success'
|
|
41
|
+
transaction&.outcome = Transaction::Outcome::SUCCESS
|
|
42
|
+
rescue StandardError => e
|
|
43
|
+
transaction&.result = 'error'
|
|
44
|
+
transaction&.outcome = Transaction::Outcome::FAILURE
|
|
45
|
+
Atatus.report(e)
|
|
54
46
|
|
|
55
|
-
|
|
56
|
-
|
|
47
|
+
raise
|
|
48
|
+
ensure
|
|
49
|
+
Atatus.end_transaction
|
|
50
|
+
Atatus.stop
|
|
57
51
|
end
|
|
58
52
|
|
|
53
|
+
result
|
|
59
54
|
end
|
|
60
55
|
end
|
|
56
|
+
|
|
57
|
+
def install
|
|
58
|
+
::Rake::Task.prepend(Ext)
|
|
59
|
+
end
|
|
61
60
|
end
|
|
61
|
+
|
|
62
62
|
register 'Rake::Task', 'rake', RakeSpy.new
|
|
63
63
|
end
|
|
64
64
|
end
|
data/lib/atatus/spies/redis.rb
CHANGED
|
@@ -22,23 +22,22 @@ module Atatus
|
|
|
22
22
|
module Spies
|
|
23
23
|
# @api private
|
|
24
24
|
class RedisSpy
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def call(command, &block)
|
|
31
|
-
name = command[0].upcase
|
|
25
|
+
# @api private
|
|
26
|
+
module Ext
|
|
27
|
+
def call(command, &block)
|
|
28
|
+
name = command[0].to_s.upcase
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
return super(command, &block) if command[0] == :auth
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
end
|
|
32
|
+
Atatus.with_span(name.to_s, 'db.redis') do
|
|
33
|
+
super(command, &block)
|
|
39
34
|
end
|
|
40
35
|
end
|
|
41
36
|
end
|
|
37
|
+
|
|
38
|
+
def install
|
|
39
|
+
::Redis::Client.prepend(Ext)
|
|
40
|
+
end
|
|
42
41
|
end
|
|
43
42
|
|
|
44
43
|
register 'Redis', 'redis', RedisSpy.new
|
data/lib/atatus/spies/resque.rb
CHANGED
|
@@ -24,31 +24,26 @@ module Atatus
|
|
|
24
24
|
class ResqueSpy
|
|
25
25
|
TYPE = 'Resque'
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
# @api private
|
|
28
|
+
module Ext
|
|
29
|
+
def perform
|
|
30
|
+
name = @payload && @payload['class']&.to_s
|
|
31
|
+
transaction = Atatus.start_transaction(name, TYPE)
|
|
32
|
+
super
|
|
33
|
+
transaction&.done 'success'
|
|
34
|
+
transaction&.outcome = Transaction::Outcome::SUCCESS
|
|
35
|
+
rescue ::Exception => e
|
|
36
|
+
Atatus.report(e, handled: false)
|
|
37
|
+
transaction&.done 'error'
|
|
38
|
+
transaction&.outcome = Transaction::Outcome::FAILURE
|
|
39
|
+
raise
|
|
40
|
+
ensure
|
|
41
|
+
Atatus.end_transaction
|
|
42
|
+
end
|
|
29
43
|
end
|
|
30
44
|
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
::Resque::Job.class_eval do
|
|
35
|
-
alias :perform_without_atatus :perform
|
|
36
|
-
|
|
37
|
-
def perform
|
|
38
|
-
name = @payload && @payload['class']&.to_s
|
|
39
|
-
transaction = Atatus.start_transaction(name, TYPE)
|
|
40
|
-
perform_without_atatus
|
|
41
|
-
transaction.done 'success'
|
|
42
|
-
rescue ::Exception => e
|
|
43
|
-
Atatus.report(e, handled: false)
|
|
44
|
-
transaction.done 'error' if transaction
|
|
45
|
-
raise
|
|
46
|
-
ensure
|
|
47
|
-
Atatus.end_transaction
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
end
|
|
45
|
+
def install
|
|
46
|
+
::Resque::Job.prepend(Ext)
|
|
52
47
|
end
|
|
53
48
|
end
|
|
54
49
|
|
|
@@ -0,0 +1,132 @@
|
|
|
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
|
+
# @api private
|
|
22
|
+
module Spies
|
|
23
|
+
# @api private
|
|
24
|
+
class S3Spy
|
|
25
|
+
TYPE = 'storage'
|
|
26
|
+
SUBTYPE = 's3'
|
|
27
|
+
AP_REGION_REGEX = /^(?:[^:]+:){3}([^:]+).*/
|
|
28
|
+
AP_REGEX = /:accesspoint.*/
|
|
29
|
+
MUTEX = Mutex.new
|
|
30
|
+
|
|
31
|
+
@@formatted_op_names = {}
|
|
32
|
+
|
|
33
|
+
def self.without_net_http
|
|
34
|
+
return yield unless defined?(NetHTTPSpy)
|
|
35
|
+
|
|
36
|
+
# rubocop:disable Style/ExplicitBlockArgument
|
|
37
|
+
Atatus::Spies::NetHTTPSpy.disable_in do
|
|
38
|
+
yield
|
|
39
|
+
end
|
|
40
|
+
# rubocop:enable Style/ExplicitBlockArgument
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.bucket_name(params)
|
|
44
|
+
return unless (bucket = params[:bucket]&.to_s)
|
|
45
|
+
return bucket unless (index = bucket.rindex(AP_REGEX))
|
|
46
|
+
|
|
47
|
+
bucket[index+1..-1]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.accesspoint_region(params)
|
|
51
|
+
if params[:bucket] && (match = AP_REGION_REGEX.match(params[:bucket]))
|
|
52
|
+
match[1]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.span_name(operation_name, bucket_name)
|
|
57
|
+
bucket_name ? "S3 #{formatted_op_name(operation_name)} #{bucket_name}" :
|
|
58
|
+
"S3 #{formatted_op_name(operation_name)}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.formatted_op_name(operation_name)
|
|
62
|
+
if @@formatted_op_names[operation_name]
|
|
63
|
+
return @@formatted_op_names[operation_name]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
MUTEX.synchronize do
|
|
67
|
+
if @@formatted_op_names[operation_name]
|
|
68
|
+
return @@formatted_op_names[operation_name]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
@@formatted_op_names[operation_name] =
|
|
72
|
+
operation_name.to_s.split('_').collect(&:capitalize).join
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
@@formatted_op_names[operation_name]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# @api private
|
|
80
|
+
module Ext
|
|
81
|
+
def self.prepended(mod)
|
|
82
|
+
# Alias all available operations
|
|
83
|
+
mod.api.operation_names.each do |operation_name|
|
|
84
|
+
define_method(operation_name) do |params = {}, options = {}, &block|
|
|
85
|
+
bucket_name = Atatus::Spies::S3Spy.bucket_name(params)
|
|
86
|
+
region = Atatus::Spies::S3Spy.accesspoint_region(params) || config.region
|
|
87
|
+
|
|
88
|
+
resource = "#{SUBTYPE}/#{bucket_name || 'unknown-bucket'}"
|
|
89
|
+
context = Atatus::Span::Context.new(
|
|
90
|
+
db: {
|
|
91
|
+
instance: config.region,
|
|
92
|
+
type: SUBTYPE
|
|
93
|
+
},
|
|
94
|
+
destination: {
|
|
95
|
+
address: config.endpoint.host,
|
|
96
|
+
port: config.endpoint.port,
|
|
97
|
+
service: {
|
|
98
|
+
name: SUBTYPE,
|
|
99
|
+
type: TYPE,
|
|
100
|
+
resource: resource },
|
|
101
|
+
cloud: { region: region }
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
Atatus.with_span(
|
|
106
|
+
Atatus::Spies::S3Spy.span_name(operation_name, bucket_name),
|
|
107
|
+
TYPE,
|
|
108
|
+
subtype: SUBTYPE,
|
|
109
|
+
action: Atatus::Spies::S3Spy.formatted_op_name(operation_name),
|
|
110
|
+
context: context
|
|
111
|
+
) do
|
|
112
|
+
Atatus::Spies::S3Spy.without_net_http do
|
|
113
|
+
super(params, options, &block)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def install
|
|
122
|
+
::Aws::S3::Client.prepend(Ext)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
register(
|
|
127
|
+
'Aws::S3::Client',
|
|
128
|
+
'aws-sdk-s3',
|
|
129
|
+
S3Spy.new
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
end
|
data/lib/atatus/spies/sequel.rb
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
# frozen_string_literal: true
|
|
19
19
|
|
|
20
|
-
require 'atatus/sql'
|
|
20
|
+
require 'atatus/sql/signature'
|
|
21
21
|
|
|
22
22
|
module Atatus
|
|
23
23
|
# @api private
|
|
@@ -44,8 +44,17 @@ module Atatus
|
|
|
44
44
|
name =
|
|
45
45
|
Atatus::Spies::SequelSpy.summarizer.summarize sql
|
|
46
46
|
|
|
47
|
+
db_name = ''
|
|
48
|
+
# postgresql shows current database
|
|
49
|
+
db_name = connection&.db.to_s if connection.respond_to?(:db)
|
|
50
|
+
# sqlite may expose a filename
|
|
51
|
+
db_name = connection&.filename.to_s if db_name == '' && connection.respond_to?(:filename)
|
|
52
|
+
# fall back to adapter class name
|
|
53
|
+
db_name = connection.class.to_s if db_name == ''
|
|
54
|
+
|
|
47
55
|
context = Atatus::Span::Context.new(
|
|
48
56
|
db: { statement: sql, type: 'sql', user: opts[:user] },
|
|
57
|
+
service: {target: {type: subtype, name: db_name }},
|
|
49
58
|
destination: { service: { resource: subtype } }
|
|
50
59
|
)
|
|
51
60
|
|
|
@@ -84,4 +93,4 @@ module Atatus
|
|
|
84
93
|
|
|
85
94
|
register 'Sequel', 'sequel', SequelSpy.new
|
|
86
95
|
end
|
|
87
|
-
end
|
|
96
|
+
end
|
|
@@ -37,9 +37,11 @@ module Atatus
|
|
|
37
37
|
yield
|
|
38
38
|
|
|
39
39
|
transaction&.done :success
|
|
40
|
+
transaction&.outcome = Transaction::Outcome::SUCCESS
|
|
40
41
|
rescue ::Exception => e
|
|
41
42
|
Atatus.report(e, handled: false)
|
|
42
43
|
transaction&.done :error
|
|
44
|
+
transaction&.outcome = Transaction::Outcome::FAILURE
|
|
43
45
|
raise
|
|
44
46
|
ensure
|
|
45
47
|
Atatus.end_transaction
|
|
@@ -54,12 +56,8 @@ module Atatus
|
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
def install
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
::Shoryuken.server_middleware do |chain|
|
|
60
|
-
chain.add Middleware
|
|
61
|
-
end
|
|
62
|
-
|
|
59
|
+
::Shoryuken.server_middleware do |chain|
|
|
60
|
+
chain.add Middleware
|
|
63
61
|
end
|
|
64
62
|
end
|
|
65
63
|
end
|