app_perf_rpm 0.0.5 → 0.0.6
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/lib/app_perf_rpm/backtrace.rb +7 -7
- data/lib/app_perf_rpm/configuration.rb +6 -4
- data/lib/app_perf_rpm/instruments/action_controller.rb +33 -16
- data/lib/app_perf_rpm/instruments/action_view.rb +93 -65
- data/lib/app_perf_rpm/instruments/active_record/adapters/mysql2.rb +24 -15
- data/lib/app_perf_rpm/instruments/active_record/adapters/postgresql.rb +95 -52
- data/lib/app_perf_rpm/instruments/active_record/adapters/sqlite3.rb +95 -54
- data/lib/app_perf_rpm/instruments/active_record.rb +1 -1
- data/lib/app_perf_rpm/instruments/activerecord_import.rb +22 -13
- data/lib/app_perf_rpm/instruments/emque_consuming.rb +16 -7
- data/lib/app_perf_rpm/instruments/faraday.rb +26 -16
- data/lib/app_perf_rpm/instruments/net_http.rb +16 -10
- data/lib/app_perf_rpm/instruments/rack.rb +75 -25
- data/lib/app_perf_rpm/instruments/redis.rb +49 -13
- data/lib/app_perf_rpm/instruments/sequel.rb +36 -28
- data/lib/app_perf_rpm/instruments/sidekiq.rb +65 -21
- data/lib/app_perf_rpm/instruments/sinatra.rb +34 -20
- data/lib/app_perf_rpm/instruments/typhoeus.rb +40 -21
- data/lib/app_perf_rpm/rails.rb +2 -1
- data/lib/app_perf_rpm/railtie.rb +4 -4
- data/lib/app_perf_rpm/reporters/json_client.rb +69 -0
- data/lib/app_perf_rpm/reporters/null_client.rb +14 -0
- data/lib/app_perf_rpm/tracer.rb +20 -89
- data/lib/app_perf_rpm/tracing/buffer.rb +25 -0
- data/lib/app_perf_rpm/tracing/carrier.rb +23 -0
- data/lib/app_perf_rpm/tracing/collector.rb +31 -0
- data/lib/app_perf_rpm/tracing/endpoint.rb +19 -0
- data/lib/app_perf_rpm/tracing/managed_span.rb +36 -0
- data/lib/app_perf_rpm/tracing/managed_tracer.rb +32 -0
- data/lib/app_perf_rpm/tracing/span.rb +67 -0
- data/lib/app_perf_rpm/tracing/span_context.rb +41 -0
- data/lib/app_perf_rpm/tracing/thread_span_stack.rb +32 -0
- data/lib/app_perf_rpm/tracing/trace_id.rb +11 -0
- data/lib/app_perf_rpm/tracing/tracer.rb +91 -0
- data/lib/app_perf_rpm/utils.rb +18 -0
- data/lib/app_perf_rpm.rb +59 -26
- metadata +90 -12
- data/lib/app_perf_rpm/aggregator.rb +0 -77
- data/lib/app_perf_rpm/dispatcher.rb +0 -85
- data/lib/app_perf_rpm/middleware.rb +0 -30
- data/lib/app_perf_rpm/span.rb +0 -103
- data/lib/app_perf_rpm/worker.rb +0 -46
@@ -21,11 +21,13 @@ module AppPerfRpm
|
|
21
21
|
end
|
22
22
|
|
23
23
|
{
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
24
|
+
"db.type" => opts[:type],
|
25
|
+
"db.statement" => sanitize_sql(sql),
|
26
|
+
"db.instance" => db_opts[:database],
|
27
|
+
"db.user" => db_opts[:user],
|
28
|
+
"db.vendor" => db_opts[:adapter],
|
29
|
+
"peer.address" => db_opts[:host],
|
30
|
+
"peer.port" => db_opts[:port]
|
29
31
|
}
|
30
32
|
end
|
31
33
|
end
|
@@ -35,19 +37,22 @@ module AppPerfRpm
|
|
35
37
|
|
36
38
|
def run_with_trace(sql, options = ::Sequel::OPTS)
|
37
39
|
if ::AppPerfRpm::Tracer.tracing?
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
span = ::AppPerfRpm.tracer.start_span("sequel", tags: parse_opts(sql, options))
|
41
|
+
span.set_tag "component", "Sequel"
|
42
|
+
span.set_tag "span.kind", "client"
|
43
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
44
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
45
|
+
end
|
41
46
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
else
|
49
|
-
run_without_trace(sql, options)
|
47
|
+
run_without_trace(sql, options)
|
48
|
+
rescue Exception => e
|
49
|
+
if span
|
50
|
+
span.set_tag('error', true)
|
51
|
+
span.log_error(e)
|
50
52
|
end
|
53
|
+
raise
|
54
|
+
ensure
|
55
|
+
span.finish if span
|
51
56
|
end
|
52
57
|
end
|
53
58
|
|
@@ -56,25 +61,28 @@ module AppPerfRpm
|
|
56
61
|
|
57
62
|
def execute_with_trace(sql, options = ::Sequel::OPTS, &block)
|
58
63
|
if ::AppPerfRpm::Tracer.tracing?
|
59
|
-
|
60
|
-
|
61
|
-
|
64
|
+
span = ::AppPerfRpm.tracer.start_span("sequel", tags: parse_opts(sql, options))
|
65
|
+
span.set_tag "component", "Sequel"
|
66
|
+
span.set_tag "span.kind", "client"
|
67
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
68
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
69
|
+
end
|
62
70
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
69
|
-
else
|
70
|
-
execute_without_trace(sql, options, &block)
|
71
|
+
execute_without_trace(sql, options, &block)
|
72
|
+
rescue Exception => e
|
73
|
+
if span
|
74
|
+
span.set_tag('error', true)
|
75
|
+
span.log_error(e)
|
71
76
|
end
|
77
|
+
raise
|
78
|
+
ensure
|
79
|
+
span.finish if span
|
72
80
|
end
|
73
81
|
end
|
74
82
|
end
|
75
83
|
end
|
76
84
|
|
77
|
-
if ::AppPerfRpm.
|
85
|
+
if ::AppPerfRpm.config.instrumentation[:sequel][:enabled] && defined?(::Sequel)
|
78
86
|
::AppPerfRpm.logger.info "Initializing sequel tracer."
|
79
87
|
|
80
88
|
::Sequel::Database.send(:include, AppPerfRpm::Instruments::SequelDatabase)
|
@@ -3,41 +3,85 @@ module AppPerfRpm
|
|
3
3
|
def call(*args)
|
4
4
|
worker, msg, queue = args
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
span
|
12
|
-
|
13
|
-
"
|
14
|
-
"
|
15
|
-
|
16
|
-
|
17
|
-
|
6
|
+
parent_span_context = extract(msg)
|
7
|
+
AppPerfRpm::Tracer.sample!(parent_span_context)
|
8
|
+
|
9
|
+
if AppPerfRpm::Tracer.tracing?
|
10
|
+
operation = "Sidekiq_#{queue}##{msg["wrapped"]}"
|
11
|
+
span = AppPerfRpm.tracer.start_span(operation, :child_of => parent_span_context, tags: {
|
12
|
+
"component" => "Sidekiq",
|
13
|
+
"span.kind" => "server",
|
14
|
+
"http.url" => "/sidekiq/#{queue}/#{msg['wrapped']}",
|
15
|
+
"peer.address" => Socket.gethostname,
|
16
|
+
"bg.queue" => queue,
|
17
|
+
"bg.job_name" => worker.class.to_s
|
18
|
+
})
|
19
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
20
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
21
|
+
end
|
22
|
+
|
23
|
+
yield
|
24
|
+
rescue Exception => e
|
25
|
+
if span
|
26
|
+
span.set_tag('error', true)
|
27
|
+
span.log_error(e)
|
18
28
|
end
|
29
|
+
raise
|
30
|
+
ensure
|
31
|
+
span.finish if span
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
19
35
|
|
20
|
-
|
36
|
+
def extract(job)
|
37
|
+
carrier = job[AppPerfRpm::TRACE_CONTEXT_KEY]
|
38
|
+
return unless carrier
|
39
|
+
AppPerfRpm::tracer.extract(OpenTracing::FORMAT_TEXT_MAP, carrier)
|
21
40
|
end
|
22
41
|
end
|
23
42
|
|
24
43
|
class SidekiqClient
|
25
44
|
def call(*args)
|
45
|
+
worker, msg, queue = args
|
46
|
+
|
26
47
|
if ::AppPerfRpm::Tracer.tracing?
|
27
|
-
|
48
|
+
operation = "Sidekiq_#{queue}##{msg["wrapped"]}"
|
49
|
+
span = AppPerfRpm.tracer.start_span(operation, tags: {
|
50
|
+
"component" => "Sidekiq",
|
51
|
+
"span.kind" => "client",
|
52
|
+
"http.url" => "/sidekiq/#{queue}/#{msg['wrapped']}",
|
53
|
+
"peer.address" => Socket.gethostname,
|
54
|
+
"bg.queue" => queue,
|
55
|
+
"bg.job_name" => worker.class.to_s
|
56
|
+
})
|
57
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
58
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
59
|
+
|
60
|
+
inject(span, msg)
|
61
|
+
end
|
28
62
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
63
|
+
yield
|
64
|
+
rescue Exception => e
|
65
|
+
if span
|
66
|
+
span.set_tag('error', true)
|
67
|
+
span.log_error(e)
|
34
68
|
end
|
35
|
-
|
69
|
+
raise
|
70
|
+
ensure
|
71
|
+
span.finish if span
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def inject(span, job)
|
77
|
+
carrier = {}
|
78
|
+
AppPerfRpm.tracer.inject(span.context, OpenTracing::FORMAT_TEXT_MAP, carrier)
|
79
|
+
job[AppPerfRpm::TRACE_CONTEXT_KEY] = carrier
|
36
80
|
end
|
37
81
|
end
|
38
82
|
end
|
39
83
|
|
40
|
-
if ::AppPerfRpm.
|
84
|
+
if ::AppPerfRpm.config.instrumentation[:sidekiq][:enabled] &&
|
41
85
|
defined?(::Sidekiq)
|
42
86
|
AppPerfRpm.logger.info "Initializing sidekiq tracer."
|
43
87
|
|
@@ -4,15 +4,23 @@ module AppPerfRpm
|
|
4
4
|
module Base
|
5
5
|
def dispatch_with_trace
|
6
6
|
if ::AppPerfRpm::Tracer.tracing?
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
operation = "#{self.class}##{env["PATH_INFO"]}"
|
8
|
+
span = ::AppPerfRpm.tracer.start_span(operation, tags: {
|
9
|
+
component: "Sinatra"
|
10
|
+
})
|
11
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
12
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
13
|
+
end
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
dispatch_without_trace
|
16
|
+
rescue Exception => e
|
17
|
+
if span
|
18
|
+
span.set_tag('error', true)
|
19
|
+
span.log_error(e)
|
15
20
|
end
|
21
|
+
raise
|
22
|
+
ensure
|
23
|
+
span.finish if span
|
16
24
|
end
|
17
25
|
|
18
26
|
def handle_exception_with_trace(boom)
|
@@ -25,27 +33,33 @@ module AppPerfRpm
|
|
25
33
|
if ::AppPerfRpm::Tracer.tracing?
|
26
34
|
name = data
|
27
35
|
|
28
|
-
::AppPerfRpm
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
+
span = ::AppPerfRpm.tracer.start_span("render", tags: {
|
37
|
+
"component" => "Sinatra",
|
38
|
+
"view.engine" => engine,
|
39
|
+
"view.name" => name,
|
40
|
+
"view.line_number" => __LINE__,
|
41
|
+
"view.template" => __FILE__
|
42
|
+
})
|
43
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
44
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
45
|
+
end
|
36
46
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
47
|
+
render_without_trace(engine, data, options, locals, &block)
|
48
|
+
rescue Exception => e
|
49
|
+
if span
|
50
|
+
span.set_tag('error', true)
|
51
|
+
span.log_error(e)
|
41
52
|
end
|
53
|
+
raise
|
54
|
+
ensure
|
55
|
+
span.finish if span
|
42
56
|
end
|
43
57
|
end
|
44
58
|
end
|
45
59
|
end
|
46
60
|
end
|
47
61
|
|
48
|
-
if ::AppPerfRpm.
|
62
|
+
if ::AppPerfRpm.config.instrumentation[:sinatra][:enabled] &&
|
49
63
|
defined?(::Sinatra)
|
50
64
|
::AppPerfRpm.logger.info "Initializing sinatra tracer."
|
51
65
|
|
@@ -2,43 +2,62 @@ module AppPerfRpm
|
|
2
2
|
module Instruments
|
3
3
|
module TyphoeusRequest
|
4
4
|
def run_with_trace
|
5
|
-
if ::AppPerfRpm.tracing?
|
6
|
-
span = ::AppPerfRpm
|
7
|
-
|
8
|
-
|
5
|
+
if ::AppPerfRpm::Tracer.tracing?
|
6
|
+
span = ::AppPerfRpm.tracer.start_span("typhoeus", tags: {
|
7
|
+
"component" => "Typhoeus"
|
8
|
+
})
|
9
|
+
AppPerfRpm.tracer.inject(span.context, OpenTracing::FORMAT_RACK, options[:headers])
|
9
10
|
|
11
|
+
response = run_without_trace
|
12
|
+
span.exit
|
10
13
|
uri = URI(response.effective_url)
|
11
14
|
|
12
|
-
span.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
span.submit(opts)
|
18
|
-
|
19
|
-
response
|
15
|
+
span.set_tag "http.status_code", response.code
|
16
|
+
span.set_tag "http.url", uri.to_s
|
17
|
+
span.set_tag "http.method", options[:method]
|
18
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
19
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
20
20
|
else
|
21
|
-
run_without_trace
|
21
|
+
response = run_without_trace
|
22
|
+
end
|
23
|
+
response
|
24
|
+
rescue Exception => e
|
25
|
+
if span
|
26
|
+
span.set_tag('error', true)
|
27
|
+
span.log_error(e)
|
22
28
|
end
|
29
|
+
raise
|
30
|
+
ensure
|
31
|
+
span.finish if span
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
26
35
|
module TyphoeusHydra
|
27
36
|
def run_with_trace
|
28
|
-
::AppPerfRpm
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
37
|
+
span = ::AppPerfRpm.tracer.start_span("typhoeus", tags: {
|
38
|
+
"component" => "Typhoeus",
|
39
|
+
"method" => "hydra",
|
40
|
+
"http.queued_requests" => queued_requests.count,
|
41
|
+
"http.max_concurrency" => max_concurrency
|
42
|
+
})
|
43
|
+
span.log(event: "backtrace", stack: ::AppPerfRpm::Backtrace.backtrace)
|
44
|
+
span.log(event: "source", stack: ::AppPerfRpm::Backtrace.source_extract)
|
45
|
+
|
46
|
+
run_without_trace
|
47
|
+
rescue Exception => e
|
48
|
+
if span
|
49
|
+
span.set_tag('error', true)
|
50
|
+
span.log_error(e)
|
35
51
|
end
|
52
|
+
raise
|
53
|
+
ensure
|
54
|
+
span.finish if span
|
36
55
|
end
|
37
56
|
end
|
38
57
|
end
|
39
58
|
end
|
40
59
|
|
41
|
-
if ::AppPerfRpm.
|
60
|
+
if ::AppPerfRpm.config.instrumentation[:typhoeus][:enabled] && defined?(::Typhoeus)
|
42
61
|
::AppPerfRpm.logger.info "Initializing typhoeus tracer."
|
43
62
|
|
44
63
|
::Typhoeus::Request::Operations.send(:include, AppPerfRpm::Instruments::TyphoeusRequest)
|
data/lib/app_perf_rpm/rails.rb
CHANGED
@@ -5,7 +5,8 @@ if defined?(::Rails)
|
|
5
5
|
Rails.configuration.after_initialize do
|
6
6
|
unless AppPerfRpm.disable_agent?
|
7
7
|
AppPerfRpm.load
|
8
|
-
|
8
|
+
AppPerfRpm.logger.info "Initializing rack middleware tracer."
|
9
|
+
Rails.configuration.middleware.insert 0, AppPerfRpm::Instruments::Rack
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
data/lib/app_perf_rpm/railtie.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module AppPerfRpm
|
2
2
|
class Railtie < ::Rails::Railtie
|
3
|
-
# TODO: Why this isn't working with the initializer?
|
4
3
|
initializer "app_perf.initialize" do |app|
|
5
4
|
unless AppPerfRpm.disable_agent?
|
6
5
|
require 'app_perf_rpm/instruments/rack'
|
7
|
-
|
6
|
+
AppPerfRpm.logger.info "Initializing rack middleware tracer."
|
7
|
+
app.middleware.insert 0, AppPerfRpm::Instruments::Rack
|
8
8
|
end
|
9
9
|
|
10
10
|
config.after_initialize do
|
11
|
-
AppPerfRpm.
|
12
|
-
AppPerfRpm.
|
11
|
+
AppPerfRpm.config.app_root = Rails.root
|
12
|
+
AppPerfRpm.config.reload
|
13
13
|
AppPerfRpm.load
|
14
14
|
end
|
15
15
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
module AppPerfRpm
|
7
|
+
module Reporters
|
8
|
+
class JsonClient
|
9
|
+
def initialize(url:, collector:, flush_interval:)
|
10
|
+
@collector = collector
|
11
|
+
@flush_interval = flush_interval
|
12
|
+
@spans_uri = URI.parse(url)
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
@thread = Thread.new do
|
17
|
+
loop do
|
18
|
+
emit_batch(@collector.retrieve)
|
19
|
+
sleep @flush_interval
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def stop
|
25
|
+
@thread.terminate if @thread
|
26
|
+
emit_batch(@collector.retrieve)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def compress_body(data)
|
32
|
+
body = Oj.dump({
|
33
|
+
"name" => AppPerfRpm.config.application_name,
|
34
|
+
"host" => AppPerfRpm.host,
|
35
|
+
"data" => data
|
36
|
+
})
|
37
|
+
|
38
|
+
compressed_body = Zlib::Deflate.deflate(body, Zlib::DEFAULT_COMPRESSION)
|
39
|
+
Base64.encode64(compressed_body)
|
40
|
+
end
|
41
|
+
|
42
|
+
def emit_batch(spans)
|
43
|
+
return if spans.empty?
|
44
|
+
|
45
|
+
sock = Net::HTTP.new(@spans_uri.host, @spans_uri.port)
|
46
|
+
sock.use_ssl = ::AppPerfRpm.config.ssl
|
47
|
+
|
48
|
+
request = Net::HTTP::Post.new(@spans_uri.request_uri, {
|
49
|
+
'Content-Type' => 'application/json',
|
50
|
+
"Accept-Encoding" => "gzip",
|
51
|
+
"User-Agent" => "gzip"
|
52
|
+
})
|
53
|
+
request.body = compress_body(spans)
|
54
|
+
request.content_type = "application/octet-stream"
|
55
|
+
|
56
|
+
response = sock.start do |http|
|
57
|
+
http.read_timeout = 30
|
58
|
+
http.request(request)
|
59
|
+
end
|
60
|
+
|
61
|
+
if response.code != 202
|
62
|
+
STDERR.puts(response.body)
|
63
|
+
end
|
64
|
+
rescue => e
|
65
|
+
STDERR.puts("Error emitting spans batch: #{e.message}\n#{e.backtrace.join("\n")}")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/app_perf_rpm/tracer.rb
CHANGED
@@ -1,69 +1,37 @@
|
|
1
|
+
require 'opentracing'
|
2
|
+
|
1
3
|
module AppPerfRpm
|
2
4
|
class Tracer
|
3
5
|
class << self
|
4
|
-
|
5
|
-
|
6
|
+
# This method should be called by any components that are
|
7
|
+
# capable of starting the tracing process.
|
8
|
+
# ie. rack, sidekiq worker, etc
|
9
|
+
def sample!(incoming_trace = nil)
|
10
|
+
# Since we keep track of the active span, meaning we have entered into
|
11
|
+
# tracing at some point, and we no longer have an active span,
|
12
|
+
# reset tracing.
|
13
|
+
Thread.current[:sample] = false if !AppPerfRpm.tracer.active_span
|
14
|
+
|
15
|
+
# Now determine if we want to trace, either by an incoming
|
16
|
+
# trace or meeting the sample rate.
|
17
|
+
Thread.current[:sample] = !!incoming_trace || should_sample?
|
18
|
+
Thread.current[:sample]
|
6
19
|
end
|
7
20
|
|
8
|
-
def
|
9
|
-
Thread.current[:
|
21
|
+
def sampled?
|
22
|
+
!!Thread.current[:sample]
|
10
23
|
end
|
11
24
|
|
12
25
|
def tracing?
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
def in_trace?
|
17
|
-
!Thread.current[:trace_id].nil?
|
18
|
-
end
|
19
|
-
|
20
|
-
def start_span(layer, opts = {})
|
21
|
-
Instance.new(layer, opts)
|
26
|
+
AppPerfRpm.tracing? && sampled?
|
22
27
|
end
|
23
28
|
|
24
29
|
def random_percentage
|
25
30
|
rand * 100
|
26
31
|
end
|
27
32
|
|
28
|
-
def
|
29
|
-
random_percentage
|
30
|
-
end
|
31
|
-
|
32
|
-
def start_trace(layer, opts = {})
|
33
|
-
start = Time.now.to_f
|
34
|
-
|
35
|
-
trace_id = opts.delete("trace_id")
|
36
|
-
if trace_id || should_trace?
|
37
|
-
self.trace_id = trace_id || generate_trace_id
|
38
|
-
result = trace(layer, opts) do |span|
|
39
|
-
yield(span)
|
40
|
-
end
|
41
|
-
self.trace_id = nil
|
42
|
-
else
|
43
|
-
span = Span.new
|
44
|
-
result = yield(span)
|
45
|
-
end
|
46
|
-
|
47
|
-
return result, (Time.now.to_f - start) * 1000
|
48
|
-
end
|
49
|
-
|
50
|
-
def trace(layer, opts = {})
|
51
|
-
result = nil
|
52
|
-
|
53
|
-
if tracing?
|
54
|
-
span = Span.new
|
55
|
-
span.layer = layer
|
56
|
-
span.trace_id = self.trace_id
|
57
|
-
span.started_at = Time.now.to_f
|
58
|
-
result = yield(span)
|
59
|
-
span.ended_at = Time.now.to_f
|
60
|
-
span.options.merge!(opts)
|
61
|
-
::AppPerfRpm.store(span)
|
62
|
-
else
|
63
|
-
result = yield
|
64
|
-
end
|
65
|
-
|
66
|
-
result
|
33
|
+
def should_sample?
|
34
|
+
random_percentage <= ::AppPerfRpm.config.sample_rate.to_i
|
67
35
|
end
|
68
36
|
|
69
37
|
def profile(layer, opts = {})
|
@@ -98,43 +66,6 @@ module AppPerfRpm
|
|
98
66
|
return [], yield
|
99
67
|
end
|
100
68
|
end
|
101
|
-
|
102
|
-
def log_event(event, opts = {})
|
103
|
-
::AppPerfRpm.store([event, generate_trace_id, Time.now.to_f, opts])
|
104
|
-
end
|
105
|
-
|
106
|
-
def generate_trace_id
|
107
|
-
Digest::SHA1.hexdigest([Time.now, rand].join)
|
108
|
-
end
|
109
|
-
|
110
|
-
class Instance
|
111
|
-
attr_accessor :layer, :opts, :start, :duration
|
112
|
-
|
113
|
-
def initialize(layer, opts = {})
|
114
|
-
@span = Span.new
|
115
|
-
@span.layer = layer
|
116
|
-
@span.options = opts
|
117
|
-
@span.started_at = Time.now.to_f
|
118
|
-
end
|
119
|
-
|
120
|
-
def finish(opts = {})
|
121
|
-
@span.options.merge!(opts)
|
122
|
-
@span.ended_at = Time.now.to_f
|
123
|
-
end
|
124
|
-
|
125
|
-
def submit(opts = {})
|
126
|
-
if ::AppPerfRpm::Tracer.tracing?
|
127
|
-
@span.options.merge!(opts)
|
128
|
-
::AppPerfRpm.store(@span)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
private
|
133
|
-
|
134
|
-
def trace_id
|
135
|
-
::AppPerfRpm::Tracer.trace_id
|
136
|
-
end
|
137
|
-
end
|
138
69
|
end
|
139
70
|
end
|
140
71
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Tracing
|
3
|
+
class Buffer
|
4
|
+
def initialize
|
5
|
+
@buffer = []
|
6
|
+
@mutex = Mutex.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def <<(element)
|
10
|
+
@mutex.synchronize do
|
11
|
+
@buffer << element
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def retrieve
|
17
|
+
@mutex.synchronize do
|
18
|
+
elements = @buffer.dup
|
19
|
+
@buffer.clear
|
20
|
+
elements
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module AppPerfRpm
|
2
|
+
module Tracing
|
3
|
+
class Carrier
|
4
|
+
def initialize
|
5
|
+
@data = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
@data[key]
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=(key, value)
|
13
|
+
@data[key] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
def each(&block)
|
17
|
+
@data.each do |datum|
|
18
|
+
yield(datum)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|