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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/app_perf_rpm/backtrace.rb +7 -7
  3. data/lib/app_perf_rpm/configuration.rb +6 -4
  4. data/lib/app_perf_rpm/instruments/action_controller.rb +33 -16
  5. data/lib/app_perf_rpm/instruments/action_view.rb +93 -65
  6. data/lib/app_perf_rpm/instruments/active_record/adapters/mysql2.rb +24 -15
  7. data/lib/app_perf_rpm/instruments/active_record/adapters/postgresql.rb +95 -52
  8. data/lib/app_perf_rpm/instruments/active_record/adapters/sqlite3.rb +95 -54
  9. data/lib/app_perf_rpm/instruments/active_record.rb +1 -1
  10. data/lib/app_perf_rpm/instruments/activerecord_import.rb +22 -13
  11. data/lib/app_perf_rpm/instruments/emque_consuming.rb +16 -7
  12. data/lib/app_perf_rpm/instruments/faraday.rb +26 -16
  13. data/lib/app_perf_rpm/instruments/net_http.rb +16 -10
  14. data/lib/app_perf_rpm/instruments/rack.rb +75 -25
  15. data/lib/app_perf_rpm/instruments/redis.rb +49 -13
  16. data/lib/app_perf_rpm/instruments/sequel.rb +36 -28
  17. data/lib/app_perf_rpm/instruments/sidekiq.rb +65 -21
  18. data/lib/app_perf_rpm/instruments/sinatra.rb +34 -20
  19. data/lib/app_perf_rpm/instruments/typhoeus.rb +40 -21
  20. data/lib/app_perf_rpm/rails.rb +2 -1
  21. data/lib/app_perf_rpm/railtie.rb +4 -4
  22. data/lib/app_perf_rpm/reporters/json_client.rb +69 -0
  23. data/lib/app_perf_rpm/reporters/null_client.rb +14 -0
  24. data/lib/app_perf_rpm/tracer.rb +20 -89
  25. data/lib/app_perf_rpm/tracing/buffer.rb +25 -0
  26. data/lib/app_perf_rpm/tracing/carrier.rb +23 -0
  27. data/lib/app_perf_rpm/tracing/collector.rb +31 -0
  28. data/lib/app_perf_rpm/tracing/endpoint.rb +19 -0
  29. data/lib/app_perf_rpm/tracing/managed_span.rb +36 -0
  30. data/lib/app_perf_rpm/tracing/managed_tracer.rb +32 -0
  31. data/lib/app_perf_rpm/tracing/span.rb +67 -0
  32. data/lib/app_perf_rpm/tracing/span_context.rb +41 -0
  33. data/lib/app_perf_rpm/tracing/thread_span_stack.rb +32 -0
  34. data/lib/app_perf_rpm/tracing/trace_id.rb +11 -0
  35. data/lib/app_perf_rpm/tracing/tracer.rb +91 -0
  36. data/lib/app_perf_rpm/utils.rb +18 -0
  37. data/lib/app_perf_rpm.rb +59 -26
  38. metadata +90 -12
  39. data/lib/app_perf_rpm/aggregator.rb +0 -77
  40. data/lib/app_perf_rpm/dispatcher.rb +0 -85
  41. data/lib/app_perf_rpm/middleware.rb +0 -30
  42. data/lib/app_perf_rpm/span.rb +0 -103
  43. data/lib/app_perf_rpm/worker.rb +0 -46
@@ -21,11 +21,13 @@ module AppPerfRpm
21
21
  end
22
22
 
23
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]
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
- begin
39
- ::AppPerfRpm::Tracer.trace("sequel") do |span|
40
- span.options = parse_opts(sql, options)
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
- 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)
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
- begin
60
- ::AppPerfRpm::Tracer.trace("sequel", opts) do |span|
61
- span.options = parse_opts(sql, options)
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
- 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
+ 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.configuration.instrumentation[:sequel][:enabled] && defined?(::Sequel)
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
- 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
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
- result
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
- worker, msg, queue = args
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
- result = AppPerfRpm::Tracer.trace("sidekiq-client") do |span|
30
- yield
31
- end
32
- else
33
- result = yield
63
+ yield
64
+ rescue Exception => e
65
+ if span
66
+ span.set_tag('error', true)
67
+ span.log_error(e)
34
68
  end
35
- result
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.configuration.instrumentation[:sidekiq][:enabled] &&
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
- ::AppPerfRpm::Tracer.trace("sinatra") do |span|
8
- span.controller = self.class.to_s
9
- span.action = env["PATH_INFO"]
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
- dispatch_without_trace
12
- end
13
- else
14
- dispatch_without_trace
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::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
+ 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
- render_without_trace(engine, data, options, locals, &block)
38
- end
39
- else
40
- render_without_trace(engine, data, options, locals, &block)
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.configuration.instrumentation[:sinatra][:enabled] &&
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::Tracer.start_span("typhoeus")
7
- response = run_without_trace
8
- span.finish
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.options = {
13
- "http_status" => response.code,
14
- "remote_url" => uri.to_s,
15
- "http_method" => options[:method]
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::Tracer.trace("typhoeus") do |span|
29
- span.options = {
30
- "method" => :hydra,
31
- "queued_requests" => queued_requests.count,
32
- "max_concurrency" => max_concurrency
33
- }
34
- run_without_trace
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.configuration.instrumentation[:typhoeus][:enabled] && defined?(::Typhoeus)
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)
@@ -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
- Rails.configuration.middleware.use AppPerfRpm::Middleware
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
@@ -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
- app.middleware.use AppPerfRpm::Middleware
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.configuration.app_root = Rails.root
12
- AppPerfRpm.configuration.reload
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
@@ -0,0 +1,14 @@
1
+ module AppPerfRpm
2
+ module Reporters
3
+ class NullClient
4
+ def initialize
5
+ end
6
+
7
+ def start
8
+ end
9
+
10
+ def stop
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,69 +1,37 @@
1
+ require 'opentracing'
2
+
1
3
  module AppPerfRpm
2
4
  class Tracer
3
5
  class << self
4
- def trace_id
5
- Thread.current[:trace_id]
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 trace_id=(t)
9
- Thread.current[:trace_id] = t
21
+ def sampled?
22
+ !!Thread.current[:sample]
10
23
  end
11
24
 
12
25
  def tracing?
13
- Thread.current[:trace_id]
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 should_trace?
29
- random_percentage < ::AppPerfRpm.configuration.sample_rate.to_i
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