app_perf_rpm 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|