atatus 1.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 +7 -0
- data/.gitignore +16 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +57 -0
- data/LICENSE +65 -0
- data/LICENSE-THIRD-PARTY +205 -0
- data/README.md +13 -0
- data/Rakefile +19 -0
- data/atatus.gemspec +36 -0
- data/atatus.yml +2 -0
- data/bench/.gitignore +2 -0
- data/bench/app.rb +53 -0
- data/bench/benchmark.rb +36 -0
- data/bench/report.rb +55 -0
- data/bench/rubyprof.rb +39 -0
- data/bench/stackprof.rb +23 -0
- data/bin/build_docs +5 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/bin/with_framework +7 -0
- data/lib/atatus.rb +325 -0
- data/lib/atatus/agent.rb +260 -0
- data/lib/atatus/central_config.rb +141 -0
- data/lib/atatus/central_config/cache_control.rb +34 -0
- data/lib/atatus/collector/base.rb +329 -0
- data/lib/atatus/collector/builder.rb +317 -0
- data/lib/atatus/collector/transport.rb +72 -0
- data/lib/atatus/config.rb +248 -0
- data/lib/atatus/config/bytes.rb +25 -0
- data/lib/atatus/config/duration.rb +23 -0
- data/lib/atatus/config/options.rb +134 -0
- data/lib/atatus/config/regexp_list.rb +13 -0
- data/lib/atatus/context.rb +33 -0
- data/lib/atatus/context/request.rb +11 -0
- data/lib/atatus/context/request/socket.rb +19 -0
- data/lib/atatus/context/request/url.rb +42 -0
- data/lib/atatus/context/response.rb +22 -0
- data/lib/atatus/context/user.rb +42 -0
- data/lib/atatus/context_builder.rb +97 -0
- data/lib/atatus/deprecations.rb +22 -0
- data/lib/atatus/error.rb +22 -0
- data/lib/atatus/error/exception.rb +46 -0
- data/lib/atatus/error/log.rb +24 -0
- data/lib/atatus/error_builder.rb +76 -0
- data/lib/atatus/instrumenter.rb +224 -0
- data/lib/atatus/internal_error.rb +6 -0
- data/lib/atatus/logging.rb +55 -0
- data/lib/atatus/metadata.rb +19 -0
- data/lib/atatus/metadata/process_info.rb +18 -0
- data/lib/atatus/metadata/service_info.rb +61 -0
- data/lib/atatus/metadata/system_info.rb +35 -0
- data/lib/atatus/metadata/system_info/container_info.rb +121 -0
- data/lib/atatus/metadata/system_info/hw_info.rb +118 -0
- data/lib/atatus/metadata/system_info/os_info.rb +31 -0
- data/lib/atatus/metrics.rb +98 -0
- data/lib/atatus/metrics/cpu_mem.rb +240 -0
- data/lib/atatus/metrics/vm.rb +60 -0
- data/lib/atatus/metricset.rb +19 -0
- data/lib/atatus/middleware.rb +76 -0
- data/lib/atatus/naively_hashable.rb +21 -0
- data/lib/atatus/normalizers.rb +68 -0
- data/lib/atatus/normalizers/action_controller.rb +27 -0
- data/lib/atatus/normalizers/action_mailer.rb +26 -0
- data/lib/atatus/normalizers/action_view.rb +77 -0
- data/lib/atatus/normalizers/active_record.rb +45 -0
- data/lib/atatus/opentracing.rb +346 -0
- data/lib/atatus/rails.rb +61 -0
- data/lib/atatus/railtie.rb +30 -0
- data/lib/atatus/span.rb +125 -0
- data/lib/atatus/span/context.rb +40 -0
- data/lib/atatus/span_helpers.rb +44 -0
- data/lib/atatus/spies.rb +86 -0
- data/lib/atatus/spies/action_dispatch.rb +28 -0
- data/lib/atatus/spies/delayed_job.rb +68 -0
- data/lib/atatus/spies/elasticsearch.rb +36 -0
- data/lib/atatus/spies/faraday.rb +70 -0
- data/lib/atatus/spies/http.rb +44 -0
- data/lib/atatus/spies/json.rb +22 -0
- data/lib/atatus/spies/mongo.rb +87 -0
- data/lib/atatus/spies/net_http.rb +70 -0
- data/lib/atatus/spies/rake.rb +45 -0
- data/lib/atatus/spies/redis.rb +27 -0
- data/lib/atatus/spies/sequel.rb +47 -0
- data/lib/atatus/spies/sidekiq.rb +89 -0
- data/lib/atatus/spies/sinatra.rb +41 -0
- data/lib/atatus/spies/tilt.rb +27 -0
- data/lib/atatus/sql_summarizer.rb +35 -0
- data/lib/atatus/stacktrace.rb +16 -0
- data/lib/atatus/stacktrace/frame.rb +52 -0
- data/lib/atatus/stacktrace_builder.rb +104 -0
- data/lib/atatus/subscriber.rb +77 -0
- data/lib/atatus/trace_context.rb +85 -0
- data/lib/atatus/transaction.rb +100 -0
- data/lib/atatus/transport/base.rb +174 -0
- data/lib/atatus/transport/connection.rb +156 -0
- data/lib/atatus/transport/connection/http.rb +116 -0
- data/lib/atatus/transport/connection/proxy_pipe.rb +75 -0
- data/lib/atatus/transport/filters.rb +43 -0
- data/lib/atatus/transport/filters/secrets_filter.rb +74 -0
- data/lib/atatus/transport/serializers.rb +93 -0
- data/lib/atatus/transport/serializers/context_serializer.rb +85 -0
- data/lib/atatus/transport/serializers/error_serializer.rb +77 -0
- data/lib/atatus/transport/serializers/metadata_serializer.rb +70 -0
- data/lib/atatus/transport/serializers/metricset_serializer.rb +28 -0
- data/lib/atatus/transport/serializers/span_serializer.rb +80 -0
- data/lib/atatus/transport/serializers/transaction_serializer.rb +37 -0
- data/lib/atatus/transport/worker.rb +73 -0
- data/lib/atatus/util.rb +42 -0
- data/lib/atatus/util/inflector.rb +93 -0
- data/lib/atatus/util/lru_cache.rb +48 -0
- data/lib/atatus/util/prefixed_logger.rb +18 -0
- data/lib/atatus/util/throttle.rb +35 -0
- data/lib/atatus/version.rb +5 -0
- data/vendor/.gitkeep +0 -0
- metadata +190 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class ElasticsearchSpy
|
|
8
|
+
NAME_FORMAT = '%s %s'
|
|
9
|
+
TYPE = 'db.elasticsearch'
|
|
10
|
+
|
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
|
12
|
+
def install
|
|
13
|
+
::Elasticsearch::Transport::Client.class_eval do
|
|
14
|
+
alias perform_request_without_apm perform_request
|
|
15
|
+
|
|
16
|
+
def perform_request(method, path, *args, &block)
|
|
17
|
+
name = format(NAME_FORMAT, method, path)
|
|
18
|
+
statement = args[0].is_a?(String) ? args[0] : args[0].to_json
|
|
19
|
+
context = Span::Context.new(db: { statement: statement })
|
|
20
|
+
|
|
21
|
+
Atatus.with_span name, TYPE, context: context do
|
|
22
|
+
perform_request_without_apm(method, path, *args, &block)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
# rubocop:enable Metrics/MethodLength
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
register(
|
|
31
|
+
'Elasticsearch::Transport::Client',
|
|
32
|
+
'elasticsearch-transport',
|
|
33
|
+
ElasticsearchSpy.new
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class FaradaySpy
|
|
8
|
+
TYPE = 'ext'
|
|
9
|
+
SUBTYPE = 'faraday'
|
|
10
|
+
|
|
11
|
+
def self.without_net_http
|
|
12
|
+
return yield unless defined?(NetHTTPSpy)
|
|
13
|
+
|
|
14
|
+
Atatus::Spies::NetHTTPSpy.disable_in do
|
|
15
|
+
yield
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
20
|
+
# rubocop:disable Metrics/BlockLength, Metrics/PerceivedComplexity
|
|
21
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
22
|
+
def install
|
|
23
|
+
::Faraday::Connection.class_eval do
|
|
24
|
+
alias run_request_without_apm run_request
|
|
25
|
+
|
|
26
|
+
def run_request(method, url, body, headers, &block)
|
|
27
|
+
unless (transaction = Atatus.current_transaction)
|
|
28
|
+
return run_request_without_apm(method, url, body, headers, &block)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
host = if url_prefix.is_a?(URI) && url_prefix.host
|
|
32
|
+
url_prefix.host
|
|
33
|
+
elsif url.nil?
|
|
34
|
+
tmp_request = build_request(method) do |req|
|
|
35
|
+
yield(req) if block_given?
|
|
36
|
+
end
|
|
37
|
+
URI(tmp_request.path).host
|
|
38
|
+
else
|
|
39
|
+
URI(url).host
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
name = "#{method.upcase} #{host}"
|
|
43
|
+
|
|
44
|
+
Atatus.with_span(
|
|
45
|
+
name,
|
|
46
|
+
TYPE,
|
|
47
|
+
subtype: SUBTYPE,
|
|
48
|
+
action: method.to_s
|
|
49
|
+
) do |span|
|
|
50
|
+
Atatus::Spies::FaradaySpy.without_net_http do
|
|
51
|
+
trace_context = span&.trace_context || transaction.trace_context
|
|
52
|
+
|
|
53
|
+
run_request_without_apm(method, url, body, headers) do |req|
|
|
54
|
+
req['Atatus-Apm-Traceparent'] = trace_context.to_header
|
|
55
|
+
|
|
56
|
+
yield req if block_given?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
64
|
+
# rubocop:enable Metrics/BlockLength, Metrics/PerceivedComplexity
|
|
65
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
register 'Faraday', 'faraday', FaradaySpy.new
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class HTTPSpy
|
|
8
|
+
TYPE = 'ext'
|
|
9
|
+
SUBTYPE = 'http_rb'
|
|
10
|
+
|
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
|
12
|
+
def install
|
|
13
|
+
::HTTP::Client.class_eval do
|
|
14
|
+
alias perform_without_apm perform
|
|
15
|
+
|
|
16
|
+
def perform(req, options)
|
|
17
|
+
unless (transaction = Atatus.current_transaction)
|
|
18
|
+
return perform_without_apm(req, options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
method = req.verb.to_s.upcase
|
|
22
|
+
host = req.uri.host
|
|
23
|
+
|
|
24
|
+
name = "#{method} #{host}"
|
|
25
|
+
|
|
26
|
+
Atatus.with_span(
|
|
27
|
+
name,
|
|
28
|
+
TYPE,
|
|
29
|
+
subtype: SUBTYPE,
|
|
30
|
+
action: method
|
|
31
|
+
) do |span|
|
|
32
|
+
trace_context = span&.trace_context || transaction.trace_context
|
|
33
|
+
req['Atatus-Apm-Traceparent'] = trace_context.to_header
|
|
34
|
+
perform_without_apm(req, options)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
# rubocop:enable Metrics/MethodLength
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
register 'HTTP', 'http', HTTPSpy.new
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'atatus/span_helpers'
|
|
4
|
+
|
|
5
|
+
module Atatus
|
|
6
|
+
# @api private
|
|
7
|
+
module Spies
|
|
8
|
+
# @api private
|
|
9
|
+
class JSONSpy
|
|
10
|
+
def install
|
|
11
|
+
::JSON.class_eval do
|
|
12
|
+
include SpanHelpers
|
|
13
|
+
span_class_method :parse, 'JSON#parse', 'json.parse'
|
|
14
|
+
span_class_method :parse!, 'JSON#parse!', 'json.parse'
|
|
15
|
+
span_class_method :generate, 'JSON#generate', 'json.generate'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
register 'JSON', 'json', JSONSpy.new
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class MongoSpy
|
|
8
|
+
def install
|
|
9
|
+
::Mongo::Monitoring::Global.subscribe(
|
|
10
|
+
::Mongo::Monitoring::COMMAND,
|
|
11
|
+
Subscriber.new
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @api private
|
|
16
|
+
class Subscriber
|
|
17
|
+
TYPE = 'db'
|
|
18
|
+
SUBTYPE = 'mongodb'
|
|
19
|
+
ACTION = 'query'
|
|
20
|
+
|
|
21
|
+
def initialize
|
|
22
|
+
@events = {}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def started(event)
|
|
26
|
+
push_event(event)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def failed(event)
|
|
30
|
+
pop_event(event)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def succeeded(event)
|
|
34
|
+
pop_event(event)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# rubocop:disable Metrics/MethodLength
|
|
40
|
+
def push_event(event)
|
|
41
|
+
return unless Atatus.current_transaction
|
|
42
|
+
# Some MongoDB commands are not on collections but rather are db
|
|
43
|
+
# admin commands. For these commands, the value at the `command_name`
|
|
44
|
+
# key is the integer 1.
|
|
45
|
+
unless event.command[event.command_name] == 1
|
|
46
|
+
collection = event.command[event.command_name]
|
|
47
|
+
end
|
|
48
|
+
name = [event.database_name,
|
|
49
|
+
collection,
|
|
50
|
+
event.command_name].compact.join('.')
|
|
51
|
+
|
|
52
|
+
span =
|
|
53
|
+
Atatus.start_span(
|
|
54
|
+
name,
|
|
55
|
+
TYPE,
|
|
56
|
+
subtype: SUBTYPE,
|
|
57
|
+
action: ACTION,
|
|
58
|
+
context: build_context(event)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@events[event.operation_id] = span
|
|
62
|
+
end
|
|
63
|
+
# rubocop:enable Metrics/MethodLength
|
|
64
|
+
|
|
65
|
+
def pop_event(event)
|
|
66
|
+
return unless (curr = Atatus.current_span)
|
|
67
|
+
span = @events.delete(event.operation_id)
|
|
68
|
+
|
|
69
|
+
curr == span && Atatus.end_span
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def build_context(event)
|
|
73
|
+
Span::Context.new(
|
|
74
|
+
db: {
|
|
75
|
+
instance: event.database_name,
|
|
76
|
+
statement: event.command.to_s,
|
|
77
|
+
type: 'mongodb',
|
|
78
|
+
user: nil
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
register 'Mongo', 'mongo', MongoSpy.new
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class NetHTTPSpy
|
|
8
|
+
KEY = :__atatus_net_http_disabled
|
|
9
|
+
TYPE = 'ext'
|
|
10
|
+
SUBTYPE = 'net_http'
|
|
11
|
+
|
|
12
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
13
|
+
class << self
|
|
14
|
+
def disabled=(disabled)
|
|
15
|
+
Thread.current[KEY] = disabled
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def disabled?
|
|
19
|
+
Thread.current[KEY] ||= false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def disable_in
|
|
23
|
+
self.disabled = true
|
|
24
|
+
|
|
25
|
+
begin
|
|
26
|
+
yield
|
|
27
|
+
ensure
|
|
28
|
+
self.disabled = false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def install
|
|
34
|
+
Net::HTTP.class_eval do
|
|
35
|
+
alias request_without_apm request
|
|
36
|
+
|
|
37
|
+
def request(req, body = nil, &block)
|
|
38
|
+
unless (transaction = Atatus.current_transaction)
|
|
39
|
+
return request_without_apm(req, body, &block)
|
|
40
|
+
end
|
|
41
|
+
if Atatus::Spies::NetHTTPSpy.disabled?
|
|
42
|
+
return request_without_apm(req, body, &block)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
host, = req['host'] && req['host'].split(':')
|
|
46
|
+
method = req.method
|
|
47
|
+
|
|
48
|
+
host ||= address
|
|
49
|
+
|
|
50
|
+
name = "#{method} #{host}"
|
|
51
|
+
|
|
52
|
+
Atatus.with_span(
|
|
53
|
+
name,
|
|
54
|
+
TYPE,
|
|
55
|
+
subtype: SUBTYPE,
|
|
56
|
+
action: method.to_s
|
|
57
|
+
) do |span|
|
|
58
|
+
trace_context = span&.trace_context || transaction.trace_context
|
|
59
|
+
req['Atatus-Apm-Traceparent'] = trace_context.to_header
|
|
60
|
+
request_without_apm(req, body, &block)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
register 'Net::HTTP', 'net/http', NetHTTPSpy.new
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class RakeSpy
|
|
8
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
9
|
+
def install
|
|
10
|
+
::Rake::Task.class_eval do
|
|
11
|
+
alias execute_without_apm execute
|
|
12
|
+
|
|
13
|
+
def execute(*args)
|
|
14
|
+
agent = Atatus.start
|
|
15
|
+
|
|
16
|
+
unless agent && agent.config.instrumented_rake_tasks.include?(name)
|
|
17
|
+
return execute_without_apm(*args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
transaction =
|
|
21
|
+
Atatus.start_transaction("Rake::Task[#{name}]", 'Rake')
|
|
22
|
+
|
|
23
|
+
begin
|
|
24
|
+
result = execute_without_apm(*args)
|
|
25
|
+
|
|
26
|
+
transaction.result = 'success' if transaction
|
|
27
|
+
rescue StandardError => e
|
|
28
|
+
transaction.result = 'error' if transaction
|
|
29
|
+
Atatus.report(e)
|
|
30
|
+
|
|
31
|
+
raise
|
|
32
|
+
ensure
|
|
33
|
+
Atatus.end_transaction
|
|
34
|
+
Atatus.stop
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
result
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
42
|
+
end
|
|
43
|
+
register 'Rake::Task', 'rake', RakeSpy.new
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Atatus
|
|
4
|
+
# @api private
|
|
5
|
+
module Spies
|
|
6
|
+
# @api private
|
|
7
|
+
class RedisSpy
|
|
8
|
+
def install
|
|
9
|
+
::Redis::Client.class_eval do
|
|
10
|
+
alias call_without_apm call
|
|
11
|
+
|
|
12
|
+
def call(command, &block)
|
|
13
|
+
name = command[0].upcase
|
|
14
|
+
|
|
15
|
+
return call_without_apm(command, &block) if command[0] == :auth
|
|
16
|
+
|
|
17
|
+
Atatus.with_span(name.to_s, 'db.redis') do
|
|
18
|
+
call_without_apm(command, &block)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
register 'Redis', 'redis', RedisSpy.new
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'atatus/sql_summarizer'
|
|
4
|
+
|
|
5
|
+
module Atatus
|
|
6
|
+
# @api private
|
|
7
|
+
module Spies
|
|
8
|
+
# @api private
|
|
9
|
+
class SequelSpy
|
|
10
|
+
TYPE = 'db.sequel.sql'
|
|
11
|
+
|
|
12
|
+
def self.summarizer
|
|
13
|
+
@summarizer ||= SqlSummarizer.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.build_context(sql, opts)
|
|
17
|
+
Span::Context.new(
|
|
18
|
+
db: { statement: sql, type: 'sql', user: opts[:user] }
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# rubocop:disable Metrics/MethodLength
|
|
23
|
+
def install
|
|
24
|
+
require 'sequel/database/logging'
|
|
25
|
+
|
|
26
|
+
::Sequel::Database.class_eval do
|
|
27
|
+
alias log_connection_yield_without_apm log_connection_yield
|
|
28
|
+
|
|
29
|
+
def log_connection_yield(sql, *args, &block)
|
|
30
|
+
unless Atatus.current_transaction
|
|
31
|
+
return log_connection_yield_without_apm(sql, *args, &block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
summarizer = Atatus::Spies::SequelSpy.summarizer
|
|
35
|
+
name = summarizer.summarize sql
|
|
36
|
+
context = Atatus::Spies::SequelSpy.build_context(sql, opts)
|
|
37
|
+
|
|
38
|
+
Atatus.with_span(name, TYPE, context: context, &block)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
# rubocop:enable Metrics/MethodLength
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
register 'Sequel', 'sequel', SequelSpy.new
|
|
46
|
+
end
|
|
47
|
+
end
|