app_perf_rpm 0.0.2
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/lib/app_perf_rpm/aggregator.rb +77 -0
- data/lib/app_perf_rpm/backtrace.rb +92 -0
- data/lib/app_perf_rpm/configuration.rb +56 -0
- data/lib/app_perf_rpm/dispatcher.rb +85 -0
- data/lib/app_perf_rpm/instrumentation.rb +21 -0
- data/lib/app_perf_rpm/instruments/action_controller.rb +51 -0
- data/lib/app_perf_rpm/instruments/action_view.rb +126 -0
- data/lib/app_perf_rpm/instruments/active_record/adapters/mysql2.rb +45 -0
- data/lib/app_perf_rpm/instruments/active_record/adapters/postgresql.rb +102 -0
- data/lib/app_perf_rpm/instruments/active_record/adapters/sqlite3.rb +103 -0
- data/lib/app_perf_rpm/instruments/active_record.rb +57 -0
- data/lib/app_perf_rpm/instruments/activerecord_import.rb +47 -0
- data/lib/app_perf_rpm/instruments/emque_consuming.rb +31 -0
- data/lib/app_perf_rpm/instruments/faraday.rb +37 -0
- data/lib/app_perf_rpm/instruments/net_http.rb +36 -0
- data/lib/app_perf_rpm/instruments/rack.rb +41 -0
- data/lib/app_perf_rpm/instruments/rack_middleware.rb +69 -0
- data/lib/app_perf_rpm/instruments/redis.rb +39 -0
- data/lib/app_perf_rpm/instruments/sequel.rb +92 -0
- data/lib/app_perf_rpm/instruments/sidekiq.rb +55 -0
- data/lib/app_perf_rpm/instruments/sinatra.rb +68 -0
- data/lib/app_perf_rpm/instruments/typhoeus.rb +55 -0
- data/lib/app_perf_rpm/introspector.rb +51 -0
- data/lib/app_perf_rpm/logger.rb +32 -0
- data/lib/app_perf_rpm/middleware.rb +30 -0
- data/lib/app_perf_rpm/rails.rb +14 -0
- data/lib/app_perf_rpm/railtie.rb +29 -0
- data/lib/app_perf_rpm/span.rb +103 -0
- data/lib/app_perf_rpm/tracer.rb +139 -0
- data/lib/app_perf_rpm/utils.rb +9 -0
- data/lib/app_perf_rpm/worker.rb +46 -0
- data/lib/app_perf_rpm.rb +124 -0
- data/lib/tasks/install.rake +6 -0
- metadata +146 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
module ActiveRecord
|
4
|
+
module Adapters
|
5
|
+
module Sqlite3
|
6
|
+
include AppPerfRpm::Utils
|
7
|
+
|
8
|
+
IGNORE_STATEMENTS = {
|
9
|
+
"SCHEMA" => true,
|
10
|
+
"EXPLAIN" => true,
|
11
|
+
"CACHE" => true
|
12
|
+
}
|
13
|
+
|
14
|
+
def ignore_trace?(name)
|
15
|
+
IGNORE_STATEMENTS[name.to_s] ||
|
16
|
+
(name && name.to_sym == :skip_logging) ||
|
17
|
+
name == 'ActiveRecord::SchemaMigration Load'
|
18
|
+
end
|
19
|
+
|
20
|
+
def exec_query_with_trace(sql, name = nil, binds = [])
|
21
|
+
if ::AppPerfRpm::Tracer.tracing?
|
22
|
+
if ignore_trace?(name)
|
23
|
+
exec_query_without_trace(sql, name, binds)
|
24
|
+
else
|
25
|
+
sanitized_sql = sanitize_sql(sql, :sqlite)
|
26
|
+
|
27
|
+
AppPerfRpm::Tracer.trace('activerecord', opts) do |span|
|
28
|
+
span.options = {
|
29
|
+
"adapter" => "postgresql",
|
30
|
+
"query" => sanitized_sql,
|
31
|
+
"name" => name
|
32
|
+
}
|
33
|
+
|
34
|
+
exec_query_without_trace(sql, name, binds)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
exec_query_without_trace(sql, name, binds)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def exec_delete_with_trace(sql, name = nil, binds = [])
|
43
|
+
if ::AppPerfRpm::Tracer.tracing?
|
44
|
+
if ignore_trace?(name)
|
45
|
+
exec_delete_without_trace(sql, name, binds)
|
46
|
+
else
|
47
|
+
sanitized_sql = sanitize_sql(sql, :sqlite)
|
48
|
+
|
49
|
+
AppPerfRpm::Tracer.trace('activerecord', opts) do |span|
|
50
|
+
span.options = {
|
51
|
+
"adapter" => "postgresql",
|
52
|
+
"query" => sanitized_sql,
|
53
|
+
"name" => name
|
54
|
+
}
|
55
|
+
|
56
|
+
exec_delete_without_trace(sql, name, binds)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
else
|
60
|
+
exec_delete_without_trace(sql, name, binds)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def exec_insert_with_trace(sql, name = nil, binds = [], *args)
|
65
|
+
if ::AppPerfRpm::Tracer.tracing?
|
66
|
+
if ignore_trace?(name)
|
67
|
+
exec_insert_without_trace(sql, name, binds, *args)
|
68
|
+
else
|
69
|
+
sanitized_sql = sanitize_sql(sql, :sqlite)
|
70
|
+
|
71
|
+
AppPerfRpm::Tracer.trace('activerecord', opts) do |span|
|
72
|
+
span.options = {
|
73
|
+
"adapter" => "postgresql",
|
74
|
+
"query" => sanitized_sql,
|
75
|
+
"name" => name
|
76
|
+
}
|
77
|
+
|
78
|
+
exec_insert_without_trace(sql, name, binds, *args)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
exec_insert_without_trace(sql, name, binds, *args)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def begin_db_transaction_with_trace
|
87
|
+
if ::AppPerfRpm::Tracer.tracing?
|
88
|
+
AppPerfRpm::Tracer.trace('activerecord', opts) do |span|
|
89
|
+
span.options = {
|
90
|
+
"adapter" => "postgresql",
|
91
|
+
"query" => "BEGIN"
|
92
|
+
}
|
93
|
+
begin_db_transaction_without_trace
|
94
|
+
end
|
95
|
+
else
|
96
|
+
begin_db_transaction_without_trace
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
module ActiveRecord
|
4
|
+
module Adapters
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
if ::AppPerfRpm.configuration.instrumentation[:active_record][:enabled] &&
|
11
|
+
defined?(::ActiveRecord)
|
12
|
+
AppPerfRpm.logger.info "Initializing activerecord tracer."
|
13
|
+
|
14
|
+
if defined?(::ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
15
|
+
require 'app_perf_rpm/instruments/active_record/adapters/sqlite3'
|
16
|
+
::ActiveRecord::ConnectionAdapters::SQLite3Adapter.send(:include,
|
17
|
+
::AppPerfRpm::Instruments::ActiveRecord::Adapters::Sqlite3
|
18
|
+
)
|
19
|
+
::ActiveRecord::ConnectionAdapters::SQLite3Adapter.class_eval do
|
20
|
+
alias_method :exec_query_without_trace, :exec_query
|
21
|
+
alias_method :exec_query, :exec_query_with_trace
|
22
|
+
|
23
|
+
alias_method :exec_delete_without_trace, :exec_delete
|
24
|
+
alias_method :exec_delete, :exec_delete_with_trace
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
29
|
+
require 'app_perf_rpm/instruments/active_record/adapters/postgresql'
|
30
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:include,
|
31
|
+
::AppPerfRpm::Instruments::ActiveRecord::Adapters::Postgresql
|
32
|
+
)
|
33
|
+
|
34
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
|
35
|
+
alias_method :exec_query_without_trace, :exec_query
|
36
|
+
alias_method :exec_query, :exec_query_with_trace
|
37
|
+
|
38
|
+
alias_method :exec_delete_without_trace, :exec_delete
|
39
|
+
alias_method :exec_delete, :exec_delete_with_trace
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if defined?(::ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
44
|
+
require 'app_perf_rpm/instruments/active_record/adapters/mysql2'
|
45
|
+
::ActiveRecord::ConnectionAdapters::Mysql2Adapter.send(:include,
|
46
|
+
::AppPerfRpm::Instruments::ActiveRecord::Adapters::Mysql2
|
47
|
+
)
|
48
|
+
|
49
|
+
::ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do
|
50
|
+
if (::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR == 0) ||
|
51
|
+
::ActiveRecord::VERSION::MAJOR == 2
|
52
|
+
alias_method :execute_without_trace, :execute
|
53
|
+
alias_method :execute, :execute_with_trace
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
module ActiveRecordImport
|
4
|
+
include AppPerfRpm::Utils
|
5
|
+
|
6
|
+
def insert_many_with_trace( sql, values, *args )
|
7
|
+
if ::AppPerfRpm::Tracer.tracing?
|
8
|
+
sql_copy = sql.dup
|
9
|
+
base_sql, post_sql = if sql_copy.dup.is_a?( String )
|
10
|
+
[sql_copy, '']
|
11
|
+
elsif sql.is_a?( Array )
|
12
|
+
[sql_copy.shift, sql_copy.join( ' ' )]
|
13
|
+
end
|
14
|
+
|
15
|
+
adapter = ::ActiveRecord::Base.connection_config[:adapter]
|
16
|
+
|
17
|
+
sanitized_sql = sanitize_sql(base_sql + values.join( ',' ) + post_sql, adapter)
|
18
|
+
|
19
|
+
AppPerfRpm::Tracer.trace('activerecord') do |span|
|
20
|
+
span.options = {
|
21
|
+
"adapter" => adapter,
|
22
|
+
"query" => sanitized_sql,
|
23
|
+
"name" => self.class.name
|
24
|
+
}
|
25
|
+
|
26
|
+
insert_many_without_trace(sql, values, *args)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
insert_many_without_trace(sql, values, *args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
if ::AppPerfRpm.configuration.instrumentation[:active_record_import][:enabled] &&
|
38
|
+
defined?(ActiveRecord::Import::PostgreSQLAdapter)
|
39
|
+
AppPerfRpm.logger.info "Initializing activerecord-import tracer."
|
40
|
+
|
41
|
+
ActiveRecord::Import::PostgreSQLAdapter.send(:include, AppPerfRpm::Instruments::ActiveRecordImport)
|
42
|
+
|
43
|
+
ActiveRecord::Import::PostgreSQLAdapter.class_eval do
|
44
|
+
alias_method :insert_many_without_trace, :insert_many
|
45
|
+
alias_method :insert_many, :insert_many_with_trace
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
module EmqueConsuming
|
4
|
+
module Router
|
5
|
+
def route_with_trace(topic, type, message)
|
6
|
+
action = type.to_s.split(".").last
|
7
|
+
|
8
|
+
::AppPerfRpm::Tracer.start_trace("emque-consuming", opts) do |span|
|
9
|
+
span.controller = topic
|
10
|
+
span.action = action
|
11
|
+
span.url = "/#{topic}/#{action}"
|
12
|
+
span.domain = Socket.gethostname
|
13
|
+
|
14
|
+
route_without_trace(topic, type, message)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
if ::AppPerfRpm.configuration.instrumentation[:emque_consuming][:enabled] && defined?(Emque::Consuming)
|
23
|
+
AppPerfRpm.logger.info "Initializing emque-consuming tracer."
|
24
|
+
|
25
|
+
Emque::Consuming::Router.send(:include, AppPerfRpm::Instruments::EmqueConsuming::Router)
|
26
|
+
|
27
|
+
Emque::Consuming::Router.class_eval do
|
28
|
+
alias_method :route_without_trace, :route
|
29
|
+
alias_method :route, :route_with_trace
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
module FaradayConnection
|
4
|
+
def run_request_with_trace(method, url, body, headers, &block)
|
5
|
+
if ::AppPerfRpm.tracing?
|
6
|
+
span = ::AppPerfRpm::Tracer.start_span("faraday")
|
7
|
+
result = run_request_without_trace(method, url, body, headers, &block)
|
8
|
+
span.finish
|
9
|
+
span.options = {
|
10
|
+
"middleware" => @builder.handlers,
|
11
|
+
"protocol" => @url_prefix.scheme,
|
12
|
+
"remote_host" => @url_prefix.host,
|
13
|
+
"remote_port" => @url_prefix.port,
|
14
|
+
"service_url" => url,
|
15
|
+
"http_method" => method,
|
16
|
+
"http_status" => result.status
|
17
|
+
}
|
18
|
+
span.submit(opts)
|
19
|
+
|
20
|
+
result
|
21
|
+
else
|
22
|
+
run_request_without_trace(method, url, body, headers, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if ::AppPerfRpm.configuration.instrumentation[:faraday][:enabled] && defined?(::Faraday)
|
30
|
+
::AppPerfRpm.logger.info "Initializing faraday tracer."
|
31
|
+
|
32
|
+
::Faraday::Connection.send(:include, AppPerfRpm::Instruments::FaradayConnection)
|
33
|
+
::Faraday::Connection.class_eval do
|
34
|
+
alias_method :run_request_without_trace, :run_request
|
35
|
+
alias_method :run_request, :run_request_with_trace
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
if ::AppPerfRpm.configuration.instrumentation[:net_http][:enabled] && defined?(Net::HTTP)
|
2
|
+
::AppPerfRpm.logger.info "Initializing net-http tracer."
|
3
|
+
|
4
|
+
Net::HTTP.class_eval do
|
5
|
+
def request_with_trace(*args, &block)
|
6
|
+
if ::AppPerfRpm::Tracer.tracing?
|
7
|
+
span = ::AppPerfRpm::Tracer.start_span("net-http")
|
8
|
+
|
9
|
+
if args.length && args[0]
|
10
|
+
req = args[0]
|
11
|
+
span.options["protocol"] = use_ssl? ? "https" : "http"
|
12
|
+
span.options["path"] = req.path
|
13
|
+
span.options["method"] = req.method
|
14
|
+
span.options["remote_host"] = addr_port
|
15
|
+
end
|
16
|
+
|
17
|
+
response = request_without_trace(*args, &block)
|
18
|
+
|
19
|
+
span.finish
|
20
|
+
span.options["status"] = response.code
|
21
|
+
|
22
|
+
if (response.code.to_i >= 300 || response.code.to_i <= 308) && response.header["Location"]
|
23
|
+
span.options["location"] = response.header["Location"]
|
24
|
+
end
|
25
|
+
|
26
|
+
trace.submit(opts)
|
27
|
+
else
|
28
|
+
response = request_without_trace(*args, &block)
|
29
|
+
end
|
30
|
+
response
|
31
|
+
end
|
32
|
+
|
33
|
+
alias request_without_trace request
|
34
|
+
alias request request_with_trace
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
class Rack
|
4
|
+
attr_reader :app
|
5
|
+
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
req = ::Rack::Request.new(env)
|
12
|
+
|
13
|
+
incoming_trace = env["HTTP_X_APP_PERF_TRACE"]
|
14
|
+
incoming_trace_id = env["HTTP_X_APP_PERF_TRACE_ID"]
|
15
|
+
|
16
|
+
opts = {}
|
17
|
+
if incoming_trace.to_s.eql?("1")
|
18
|
+
opts.merge!("trace_id" => incoming_trace_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
if ignore_path?(req.path)
|
22
|
+
@status, @headers, @response = @app.call(env)
|
23
|
+
else
|
24
|
+
AppPerfRpm::Tracer.start_trace("rack", opts) do |span|
|
25
|
+
span.type = "web"
|
26
|
+
span.domain = req.host
|
27
|
+
span.url = req.path
|
28
|
+
|
29
|
+
@status, @headers, @response = @app.call(env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
[@status, @headers, @response]
|
34
|
+
end
|
35
|
+
|
36
|
+
def ignore_path?(path)
|
37
|
+
path.to_s =~ /\/assets/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
class RackMiddleware
|
4
|
+
attr_reader :app
|
5
|
+
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
self.extend(AppPerfRpmRack)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
@app.call(env)
|
13
|
+
end
|
14
|
+
|
15
|
+
module AppPerfRpmRack
|
16
|
+
def self.extended(object)
|
17
|
+
object.singleton_class.class_eval do
|
18
|
+
alias_method :call_without_tracing, :call
|
19
|
+
alias_method :call, :call_with_tracing
|
20
|
+
public :call
|
21
|
+
end
|
22
|
+
|
23
|
+
object.instance_eval do
|
24
|
+
recursive_app_perf
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def recursive_app_perf
|
31
|
+
return if @app.nil?
|
32
|
+
return unless @app.respond_to?(:call)
|
33
|
+
@app.extend(AppPerfRpmRack)
|
34
|
+
end
|
35
|
+
|
36
|
+
def call_with_tracing(env)
|
37
|
+
req = ::Rack::Request.new(env)
|
38
|
+
|
39
|
+
incoming_trace = env["HTTP_X_APP_PERF_TRACE"]
|
40
|
+
incoming_trace_id = env["HTTP_X_APP_PERF_TRACE_ID"]
|
41
|
+
|
42
|
+
opts = {}
|
43
|
+
if incoming_trace.to_s.eql?("1")
|
44
|
+
opts.merge!("trace_id" => incoming_trace_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
if !::AppPerfRpm::Tracer.tracing? || ignore_path?(req.path)
|
48
|
+
@status, @headers, @response = @app.call_without_tracing(env)
|
49
|
+
else
|
50
|
+
AppPerfRpm::Tracer.trace("rack-middleware", opts) do |span|
|
51
|
+
span.type = "web"
|
52
|
+
span.domain = req.host
|
53
|
+
span.url = req.path
|
54
|
+
span.options["class"] = self.class.name
|
55
|
+
|
56
|
+
@status, @headers, @response = @app.call_without_tracing(env)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
[@status, @headers, @response]
|
61
|
+
end
|
62
|
+
|
63
|
+
def ignore_path?(path)
|
64
|
+
path.to_s =~ /\/assets/
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module AppPerf
|
2
|
+
module Instruments
|
3
|
+
module Redis
|
4
|
+
def call_with_trace(command, &block)
|
5
|
+
if ::AppPerfRpm::Tracer.tracing?
|
6
|
+
::AppPerfRpm::Tracer.trace("redis") do |span|
|
7
|
+
call_without_trace(command, &block)
|
8
|
+
end
|
9
|
+
else
|
10
|
+
call_without_trace(command, &block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def call_pipeline_with_trace(pipeline)
|
15
|
+
if ::AppPerfRpm::Tracer.tracing?
|
16
|
+
::AppPerfRpm::Tracer.trace("redis") do |span|
|
17
|
+
call_pipeline_without_trace(pipeline)
|
18
|
+
end
|
19
|
+
else
|
20
|
+
call_pipeline_without_trace(pipeline)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if ::AppPerfRpm.configuration.instrumentation[:redis][:enabled] &&
|
28
|
+
defined?(::Redis)
|
29
|
+
::AppPerfRpm.logger.info "Initializing redis tracer."
|
30
|
+
|
31
|
+
::Redis::Client.send(:include, ::AppPerf::Instruments::Redis)
|
32
|
+
|
33
|
+
::Redis::Client.class_eval do
|
34
|
+
alias_method :call_without_trace, :call
|
35
|
+
alias_method :call, :call_with_trace
|
36
|
+
alias_method :call_pipeline_without_trace, :call_pipeline
|
37
|
+
alias_method :call_pipeline, :call_pipeline_with_trace
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
module Sequel
|
4
|
+
def sanitize_sql(sql)
|
5
|
+
regexp = Regexp.new('(\'[\s\S][^\']*\'|\d*\.\d+|\d+|NULL)', Regexp::IGNORECASE)
|
6
|
+
sql.to_s.gsub(regexp, '?')
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse_opts(sql, opts)
|
10
|
+
if ::Sequel::VERSION < '3.41.0' && !(self.class.to_s =~ /Dataset$/)
|
11
|
+
db_opts = @opts
|
12
|
+
elsif @pool
|
13
|
+
db_opts = @pool.db.opts
|
14
|
+
else
|
15
|
+
db_opts = @db.opts
|
16
|
+
end
|
17
|
+
|
18
|
+
if ::Sequel::VERSION > '4.36.0' && !sql.is_a?(String)
|
19
|
+
# In 4.37.0, sql was converted to a prepared statement object
|
20
|
+
sql = sql.prepared_sql unless sql.is_a?(Symbol)
|
21
|
+
end
|
22
|
+
|
23
|
+
{
|
24
|
+
"name" => opts[:type],
|
25
|
+
"query" => sanitize_sql(sql),
|
26
|
+
"database" => db_opts[:database],
|
27
|
+
"host" => db_opts[:host],
|
28
|
+
"adapter" => db_opts[:adapter]
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module SequelDatabase
|
34
|
+
include ::AppPerfRpm::Instruments::Sequel
|
35
|
+
|
36
|
+
def run_with_trace(sql, options = ::Sequel::OPTS)
|
37
|
+
if ::AppPerfRpm::Tracer.tracing?
|
38
|
+
begin
|
39
|
+
::AppPerfRpm::Tracer.trace("sequel") do |span|
|
40
|
+
span.options = parse_opts(sql, options)
|
41
|
+
|
42
|
+
run_without_trace(sql, options)
|
43
|
+
end
|
44
|
+
rescue => e
|
45
|
+
::AppPerfRpm.logger.error e.inspect
|
46
|
+
raise
|
47
|
+
end
|
48
|
+
else
|
49
|
+
run_without_trace(sql, options)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module SequelDataset
|
55
|
+
include ::AppPerfRpm::Instruments::Sequel
|
56
|
+
|
57
|
+
def execute_with_trace(sql, options = ::Sequel::OPTS, &block)
|
58
|
+
if ::AppPerfRpm::Tracer.tracing?
|
59
|
+
begin
|
60
|
+
::AppPerfRpm::Tracer.trace("sequel", opts) do |span|
|
61
|
+
span.options = parse_opts(sql, options)
|
62
|
+
|
63
|
+
execute_without_trace(sql, options, &block)
|
64
|
+
end
|
65
|
+
rescue => e
|
66
|
+
::AppPerfRpm.logger.error e.inspect
|
67
|
+
raise
|
68
|
+
end
|
69
|
+
else
|
70
|
+
execute_without_trace(sql, options, &block)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if ::AppPerfRpm.configuration.instrumentation[:sequel][:enabled] && defined?(::Sequel)
|
78
|
+
::AppPerfRpm.logger.info "Initializing sequel tracer."
|
79
|
+
|
80
|
+
::Sequel::Database.send(:include, AppPerfRpm::Instruments::SequelDatabase)
|
81
|
+
::Sequel::Dataset.send(:include, AppPerfRpm::Instruments::SequelDataset)
|
82
|
+
|
83
|
+
::Sequel::Database.class_eval do
|
84
|
+
alias_method :run_without_trace, :run
|
85
|
+
alias_method :run, :run_with_trace
|
86
|
+
end
|
87
|
+
|
88
|
+
::Sequel::Dataset.class_eval do
|
89
|
+
alias_method :execute_without_trace, :execute
|
90
|
+
alias_method :execute, :execute_with_trace
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
class SidekiqServer
|
3
|
+
def call(*args)
|
4
|
+
worker, msg, queue = args
|
5
|
+
|
6
|
+
result = AppPerfRpm::Tracer.start_trace("sidekiq-worker") do |span|
|
7
|
+
span.type = "job"
|
8
|
+
span.controller = "Sidekiq_#{queue}"
|
9
|
+
span.action = msg["wrapped"]
|
10
|
+
span.url = "/sidekiq/#{queue}/#{msg['wrapped']}"
|
11
|
+
span.domain = Socket.gethostname
|
12
|
+
span.options = {
|
13
|
+
"job_name" => worker.class.to_s,
|
14
|
+
"queue" => queue
|
15
|
+
}
|
16
|
+
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
|
20
|
+
result
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class SidekiqClient
|
25
|
+
def call(*args)
|
26
|
+
if ::AppPerfRpm::Tracer.tracing?
|
27
|
+
worker, msg, queue = args
|
28
|
+
|
29
|
+
result = AppPerfRpm::Tracer.trace("sidekiq-client") do |span|
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
else
|
33
|
+
result = yield
|
34
|
+
end
|
35
|
+
result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
if ::AppPerfRpm.configuration.instrumentation[:sidekiq][:enabled] &&
|
41
|
+
defined?(::Sidekiq)
|
42
|
+
AppPerfRpm.logger.info "Initializing sidekiq tracer."
|
43
|
+
|
44
|
+
::Sidekiq.configure_server do |config|
|
45
|
+
config.server_middleware do |chain|
|
46
|
+
chain.add ::AppPerfRpm::SidekiqServer
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
::Sidekiq.configure_client do |config|
|
51
|
+
config.client_middleware do |chain|
|
52
|
+
chain.add ::AppPerfRpm::SidekiqClient
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Instruments
|
3
|
+
module Sinatra
|
4
|
+
module Base
|
5
|
+
def dispatch_with_trace
|
6
|
+
if ::AppPerfRpm::Tracer.tracing?
|
7
|
+
::AppPerfRpm::Tracer.trace("sinatra") do |span|
|
8
|
+
span.controller = self.class.to_s
|
9
|
+
span.action = env["PATH_INFO"]
|
10
|
+
|
11
|
+
dispatch_without_trace
|
12
|
+
end
|
13
|
+
else
|
14
|
+
dispatch_without_trace
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def handle_exception_with_trace(boom)
|
19
|
+
handle_exception_without_trace(boom)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Templates
|
24
|
+
def render_with_trace(engine, data, options = {}, locals = {}, &block)
|
25
|
+
if ::AppPerfRpm::Tracer.tracing?
|
26
|
+
name = data
|
27
|
+
|
28
|
+
::AppPerfRpm::Tracer.trace("sinatra") do |span|
|
29
|
+
span.options = {
|
30
|
+
"engine" => engine,
|
31
|
+
"name" => name,
|
32
|
+
"type" => "render",
|
33
|
+
"file" => __FILE__,
|
34
|
+
"line_number" => __LINE__
|
35
|
+
}
|
36
|
+
|
37
|
+
render_without_trace(engine, data, options, locals, &block)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
render_without_trace(engine, data, options, locals, &block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
if ::AppPerfRpm.configuration.instrumentation[:sinatra][:enabled] &&
|
49
|
+
defined?(::Sinatra)
|
50
|
+
::AppPerfRpm.logger.info "Initializing sinatra tracer."
|
51
|
+
|
52
|
+
::Sinatra::Base.use AppPerfRpm::Instruments::Rack
|
53
|
+
|
54
|
+
unless defined?(::Padrino)
|
55
|
+
::Sinatra::Base.send(:include, ::AppPerfRpm::Instruments::Sinatra::Base)
|
56
|
+
::Sinatra::Base.class_eval do
|
57
|
+
alias_method :dispatch_without_trace, :dispatch!
|
58
|
+
alias_method :dispatch!, :dispatch_with_trace
|
59
|
+
alias_method :handle_exception_without_trace, :handle_exception!
|
60
|
+
alias_method :handle_exception!, :handle_exception_with_trace
|
61
|
+
end
|
62
|
+
|
63
|
+
::Sinatra::Templates.send(:include, ::AppPerfRpm::Instruments::Sinatra::Templates)
|
64
|
+
::Sinatra::Base.class_eval do
|
65
|
+
alias_method :render_without_trace, :render
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|