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.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/lib/app_perf_rpm/aggregator.rb +77 -0
  3. data/lib/app_perf_rpm/backtrace.rb +92 -0
  4. data/lib/app_perf_rpm/configuration.rb +56 -0
  5. data/lib/app_perf_rpm/dispatcher.rb +85 -0
  6. data/lib/app_perf_rpm/instrumentation.rb +21 -0
  7. data/lib/app_perf_rpm/instruments/action_controller.rb +51 -0
  8. data/lib/app_perf_rpm/instruments/action_view.rb +126 -0
  9. data/lib/app_perf_rpm/instruments/active_record/adapters/mysql2.rb +45 -0
  10. data/lib/app_perf_rpm/instruments/active_record/adapters/postgresql.rb +102 -0
  11. data/lib/app_perf_rpm/instruments/active_record/adapters/sqlite3.rb +103 -0
  12. data/lib/app_perf_rpm/instruments/active_record.rb +57 -0
  13. data/lib/app_perf_rpm/instruments/activerecord_import.rb +47 -0
  14. data/lib/app_perf_rpm/instruments/emque_consuming.rb +31 -0
  15. data/lib/app_perf_rpm/instruments/faraday.rb +37 -0
  16. data/lib/app_perf_rpm/instruments/net_http.rb +36 -0
  17. data/lib/app_perf_rpm/instruments/rack.rb +41 -0
  18. data/lib/app_perf_rpm/instruments/rack_middleware.rb +69 -0
  19. data/lib/app_perf_rpm/instruments/redis.rb +39 -0
  20. data/lib/app_perf_rpm/instruments/sequel.rb +92 -0
  21. data/lib/app_perf_rpm/instruments/sidekiq.rb +55 -0
  22. data/lib/app_perf_rpm/instruments/sinatra.rb +68 -0
  23. data/lib/app_perf_rpm/instruments/typhoeus.rb +55 -0
  24. data/lib/app_perf_rpm/introspector.rb +51 -0
  25. data/lib/app_perf_rpm/logger.rb +32 -0
  26. data/lib/app_perf_rpm/middleware.rb +30 -0
  27. data/lib/app_perf_rpm/rails.rb +14 -0
  28. data/lib/app_perf_rpm/railtie.rb +29 -0
  29. data/lib/app_perf_rpm/span.rb +103 -0
  30. data/lib/app_perf_rpm/tracer.rb +139 -0
  31. data/lib/app_perf_rpm/utils.rb +9 -0
  32. data/lib/app_perf_rpm/worker.rb +46 -0
  33. data/lib/app_perf_rpm.rb +124 -0
  34. data/lib/tasks/install.rake +6 -0
  35. metadata +146 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b34ed99c3e8e44848ad0973d852d87017529d97e
4
+ data.tar.gz: 21b6044514766bc7fc0df5ab6fe191e22d896cd9
5
+ SHA512:
6
+ metadata.gz: 31f24ad79ef22b4a7835daec2a2abf9bdb8d5c8d3b02b48d223eba656eda148841bb12724dc95ddd479f01241e951f42a5862378444c283fa1811bec2adeca48
7
+ data.tar.gz: d1f1aaf3e684d319ff06378ccac8c8e0ccf9f482dd3cc309493dca89a2c7ed79479b3a40f06117e8cc9b0589cf10aebc0781f7f0fc73bba9c461f005bf9145af
@@ -0,0 +1,77 @@
1
+ require 'digest/md5'
2
+
3
+ module AppPerfRpm
4
+ class Aggregator
5
+ def initialize
6
+ end
7
+
8
+ def aggregate(traces)
9
+ metrics = []
10
+ traces = arrange_traces(traces)
11
+ spans = traces_to_spans(traces)
12
+ spans_by_time(spans).each_pair do |time, spans|
13
+ group_spans(spans).each_pair do |(type, layer, domain, url, controller, action), grouped_spans|
14
+ opts = {}
15
+ opts["type"] = type if type
16
+ opts["layer"] = layer if layer
17
+ opts["domain"] = domain if domain
18
+ opts["url"] = url if url
19
+ opts["controller"] = controller if controller
20
+ opts["action"] = action if action
21
+ metrics << build_metric("trace.web.request.duration", time, grouped_spans, opts)
22
+ end
23
+ end
24
+
25
+ return metrics
26
+ end
27
+
28
+ private
29
+
30
+ def build_metric(metric_name, time, spans, opts)
31
+ num_spans = spans.uniq(&:trace_id).size
32
+ durations = spans.inject(0.0) {|s, x| s + x.exclusive_duration }.to_f
33
+ hits = spans.size
34
+
35
+ tags = {
36
+ "traces" => num_spans,
37
+ "hits" => hits
38
+ }.merge(opts)
39
+
40
+ ["metric", time.to_f, metric_name, durations, tags]
41
+ end
42
+
43
+ def arrange_traces(traces)
44
+ traces
45
+ .group_by(&:trace_id)
46
+ .map {|span| Span.arrange(span.last.dup) }
47
+ end
48
+
49
+ def traces_to_spans(traces)
50
+ traces
51
+ .map {|trace| trace.to_spans}
52
+ .flatten
53
+ end
54
+
55
+ def spans_by_time(spans)
56
+ spans.group_by {|span|
57
+ AppPerfRpm.floor_time(Time.at(span.started_at), dispatch_interval)
58
+ }
59
+ end
60
+
61
+ def group_spans(spans)
62
+ spans
63
+ .group_by {|span| [
64
+ span.type,
65
+ span.layer,
66
+ span.domain,
67
+ span.url,
68
+ span.controller,
69
+ span.action
70
+ ]}
71
+ end
72
+
73
+ def dispatch_interval
74
+ 30
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,92 @@
1
+ module AppPerfRpm
2
+ class Backtrace
3
+ class << self
4
+ def backtrace
5
+ bt = Kernel.caller
6
+ bt = clean(bt)
7
+ trim_backtrace(bt)
8
+ end
9
+
10
+ def clean(backtrace)
11
+ backtrace
12
+ .map {|b| clean_line(b) }
13
+ .select {|b| b !~ %r{lib/app_perf_rpm} }
14
+ end
15
+
16
+ #def source_extract(_backtrace = Kernel.caller(2))
17
+ # if(trace = _backtrace.first)
18
+ # file, line_number = extract_file_and_line_number(trace)
19
+
20
+ # {
21
+ # code: source_fragment(file, line_number),
22
+ # line_number: line_number
23
+ # }
24
+ # else
25
+ # nil
26
+ # end
27
+ #end
28
+
29
+ def source_extract(_backtrace = Kernel.caller(0))
30
+ Array(_backtrace).select {|bt| bt[/^#{::AppPerfRpm.configuration.app_root.to_s}\//] }.map do |trace|
31
+ file, line_number = extract_file_and_line_number(trace)
32
+ source_to_hash(file, line_number)
33
+ end
34
+ end
35
+
36
+ def source_to_hash(file, line_number)
37
+ {
38
+ "file" => clean_line(file),
39
+ "code" => source_fragment(file, line_number),
40
+ "line_number" => line_number
41
+ }
42
+ end
43
+
44
+ private
45
+
46
+ def clean_line(line)
47
+ line
48
+ .sub(/#{::AppPerfRpm.configuration.app_root.to_s}\//, "[APP_PATH]/")
49
+ .sub(gems_regexp, '\2 (\3) [GEM_PATH]/\4')
50
+ end
51
+
52
+ def gems_regexp
53
+ gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
54
+ if gems_paths
55
+ %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w.]+)/(.*)}
56
+ else
57
+ nil
58
+ end
59
+ end
60
+
61
+ def source_fragment(path, line)
62
+ return unless AppPerfRpm.configuration.app_root
63
+ full_path = AppPerfRpm.configuration.app_root.join(path)
64
+ if File.exist?(full_path)
65
+ File.open(full_path, "r") do |file|
66
+ start = [line - 3, 0].max
67
+ lines = file.each_line.drop(start).take(6)
68
+ Hash[*(start + 1..(lines.count + start)).zip(lines).flatten]
69
+ end
70
+ end
71
+ end
72
+
73
+ def extract_file_and_line_number(trace)
74
+ file, line = trace.match(/^(.+?):(\d+).*$/, &:captures) || trace
75
+ [file, line.to_i]
76
+ end
77
+
78
+ def trim_backtrace(_backtrace)
79
+ return _backtrace unless _backtrace.is_a?(Array)
80
+
81
+ length = _backtrace.size
82
+ if length > 100
83
+ # Trim backtraces by getting the first 180 and last 20 lines
84
+ trimmed = _backtrace[0, 80] + ['...[snip]...'] + _backtrace[length - 20, 20]
85
+ else
86
+ trimmed = _backtrace
87
+ end
88
+ trimmed
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,56 @@
1
+ require 'yaml'
2
+
3
+ module AppPerfRpm
4
+ class Configuration
5
+ attr_accessor :app_root,
6
+ :host,
7
+ :port,
8
+ :license_key,
9
+ :ssl,
10
+ :sample_rate,
11
+ :sample_threshold,
12
+ :dispatch_interval,
13
+ :application_name,
14
+ :instrumentation,
15
+ :agent_disabled
16
+
17
+ def initialize
18
+ reload
19
+ end
20
+
21
+ def reload
22
+ ::AppPerfRpm.mutex.synchronize do
23
+ self.app_root = app_root ? Pathname.new(app_root.to_s) : nil
24
+ self.host ||= default_if_blank(ENV["APP_PERF_HOST"], "http://localhost:5000")
25
+ self.ssl ||= false
26
+ self.license_key ||= default_if_blank(ENV["APP_PERF_LICENSE_KEY"], nil)
27
+ self.application_name ||= "Default"
28
+ self.sample_rate ||= 10 # Percentage of request to sample
29
+ self.sample_threshold ||= 0 # Minimum amount of duration to sample
30
+ self.dispatch_interval ||= 60 # In seconds
31
+ self.agent_disabled ||= default_if_blank(ENV["APP_PERF_AGENT_DISABLED"], false)
32
+ self.instrumentation = {
33
+ :rack => { :enabled => true, :backtrace => false, :trace_middleware => true },
34
+ :active_record => { :enabled => true, :backtrace => false },
35
+ :active_record_import => { :enabled => true, :backtrace => false },
36
+ :action_view => { :enabled => true, :backtrace => false },
37
+ :action_controller => { :enabled => true, :backtrace => false },
38
+ :emque_consuming => { :enabled => true, :backtrace => false },
39
+ :redis => { :enabled => true, :backtrace => false },
40
+ :sequel => { :enabled => true, :backtrace => false },
41
+ :sidekiq => { :enabled => true, :backtrace => false },
42
+ :sinatra => { :enabled => true, :backtrace => false },
43
+ :net_http => { :enabled => true, :backtrace => false },
44
+ :typhoeus => { :enabled => true, :backtrace => false },
45
+ :faraday => { :enabled => true, :backtrace => false }
46
+ }
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def default_if_blank(value, default)
53
+ value.nil? || value.blank? ? default : value
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,85 @@
1
+ require 'net/http'
2
+
3
+ module AppPerfRpm
4
+ class Dispatcher
5
+ def initialize
6
+ @start_time = Time.now
7
+ @queue = Queue.new
8
+ @aggregator = Aggregator.new
9
+ end
10
+
11
+ def add_event(event)
12
+ @queue << event
13
+ end
14
+
15
+ def configuration
16
+ ::AppPerfRpm.configuration
17
+ end
18
+
19
+ def ready?
20
+ Time.now > @start_time + configuration.dispatch_interval.to_f &&
21
+ @queue.size.to_i > 0
22
+ end
23
+
24
+ def reset
25
+ @queue.clear
26
+ @start_time = Time.now
27
+ end
28
+
29
+ def dispatch
30
+ begin
31
+ spans = drain(@queue)
32
+ metrics = []#@aggregator.aggregate(spans)
33
+
34
+ dispatch_events(spans.map(&:to_a) + metrics)
35
+ rescue => ex
36
+ ::AppPerfRpm.logger.error "#{ex.inspect}"
37
+ ::AppPerfRpm.logger.error "#{ex.backtrace.inspect}"
38
+ ensure
39
+ reset
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def dispatch_events(data)
46
+ if data && data.length > 0
47
+ uri = URI(url)
48
+
49
+ sock = Net::HTTP.new(uri.host, uri.port)
50
+ sock.use_ssl = configuration.ssl
51
+
52
+ req = Net::HTTP::Post.new(uri.path, { "Content-Type" => "application/json", "Accept-Encoding" => "gzip", "User-Agent" => "gzip" })
53
+ req.body = compress_body(data)
54
+ req.content_type = "application/octet-stream"
55
+
56
+ res = sock.start do |http|
57
+ http.read_timeout = 30
58
+ http.request(req)
59
+ end
60
+ data.clear
61
+ end
62
+ end
63
+
64
+ def compress_body(data)
65
+ body = Oj.dump({
66
+ "name" => configuration.application_name,
67
+ "host" => AppPerfRpm.host,
68
+ "data" => data
69
+ })
70
+
71
+ compressed_body = Zlib::Deflate.deflate(body, Zlib::DEFAULT_COMPRESSION)
72
+ Base64.encode64(compressed_body)
73
+ end
74
+
75
+ def drain(queue)
76
+ Array.new(queue.size) { queue.pop }
77
+ end
78
+
79
+ def url
80
+ host = configuration.host
81
+ license_key = configuration.license_key
82
+ @url ||= "#{host}/api/listener/2/#{license_key}"
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,21 @@
1
+ module AppPerfRpm
2
+ class Instrumentation
3
+ class << self
4
+ def load
5
+ pattern = File.join(File.dirname(__FILE__), 'instruments', '**', '*.rb')
6
+ Dir.glob(pattern) do |f|
7
+ begin
8
+ require f
9
+ rescue => e
10
+ AppPerfRpm.logger.error "Error loading instrumentation file '#{f}' : #{e}"
11
+ AppPerfRpm.logger.error "#{e.backtrace[0..10]}"
12
+ end
13
+ end
14
+
15
+ if defined? Rails::Railtie
16
+ require "app_perf_rpm/railtie"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,51 @@
1
+ module AppPerfRpm
2
+ module Instruments
3
+ module ActionController
4
+ def process_action_with_trace(method_name, *args)
5
+ if ::AppPerfRpm::Tracer.tracing?
6
+ AppPerfRpm::Tracer.trace('actioncontroller') do |span|
7
+ span.controller = self.class.name
8
+ span.action = self.action_name
9
+
10
+ process_action_without_trace(method_name, *args)
11
+ end
12
+ else
13
+ process_action_without_trace(method_name, *args)
14
+ end
15
+ end
16
+
17
+ def perform_action_with_trace(*arguments)
18
+ if ::AppPerfRpm::Tracer.tracing?
19
+ AppPerfRpm::Tracer.trace('actioncontroller') do |span|
20
+ span.controller = @_request.path_parameters['controller']
21
+ span.action = @_request.path_parameters['action']
22
+
23
+ perform_action_without_trace(*arguments)
24
+ end
25
+ else
26
+ perform_action_without_trace(*arguments)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ if ::AppPerfRpm.configuration.instrumentation[:action_controller][:enabled] &&
34
+ defined?(::ActionController)
35
+ AppPerfRpm.logger.info "Initializing actioncontroller tracer."
36
+
37
+ ::ActionController::Base.send(
38
+ :include,
39
+ AppPerfRpm::Instruments::ActionController
40
+ )
41
+
42
+ ::ActionController::Base.class_eval do
43
+ if ::Rails::VERSION::MAJOR > 2
44
+ alias_method :process_action_without_trace, :process_action
45
+ alias_method :process_action, :process_action_with_trace
46
+ else
47
+ alias_method :perform_action_without_trace, :perform_action
48
+ alias_method :perform_action, :perform_action_with_trace
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,126 @@
1
+ if ::AppPerfRpm.configuration.instrumentation[:action_view][:enabled] && defined?(::ActionView)
2
+ if defined?(Rails) && Rails::VERSION::MAJOR == 2
3
+ ActionView::Partials.module_eval do
4
+ alias :render_partial_without_trace :render_partial
5
+ def render_partial(options = {})
6
+ if ::AppPerfRpm::Tracer.tracing? && options.key?(:partial) && options[:partial].is_a?(String)
7
+ opts = {
8
+ "method" => "render_partial",
9
+ "name" => options[:partial]
10
+ }
11
+
12
+ opts["backtrace"] = ::AppPerfRpm::Backtrace.backtrace
13
+ opts["source"] = ::AppPerfRpm::Backtrace.source_extract
14
+
15
+ AppPerfRpm::Tracer.trace("actionview", opts) do |span|
16
+ span.controller = @_request.path_parameters['controller']
17
+ span.action = @_request.path_parameters['action']
18
+ span.backtrace = ::AppPerfRpm::Backtrace.backtrace
19
+ span.source = ::AppPerfRpm::Backtrace.source_extract
20
+
21
+ render_partial_without_trace(options)
22
+ end
23
+ else
24
+ render_partial_without_trace(options)
25
+ end
26
+ end
27
+
28
+ alias :render_partial_collection_without_trace :render_partial_collection
29
+ def render_partial_collection(options = {})
30
+ if ::AppPerfRpm::Tracer.tracing?
31
+ AppPerfRpm::Tracer.trace("actionview") do |span|
32
+ span.backtrace = ::AppPerfRpm::Backtrace.backtrace
33
+ span.source = ::AppPerfRpm::Backtrace.source_extract
34
+ span.options = {
35
+ "method" => "render_partial_collection",
36
+ "name" => @path
37
+ }
38
+
39
+ render_partial_collection_without_trace(options)
40
+ end
41
+ else
42
+ render_partial_collection_without_trace(options)
43
+ end
44
+ end
45
+ end
46
+ else
47
+ ActionView::PartialRenderer.class_eval do
48
+ alias :render_partial_without_trace :render_partial
49
+ def render_partial
50
+ if ::AppPerfRpm::Tracer.tracing?
51
+ AppPerfRpm::Tracer.trace("actionview") do |span|
52
+ span.backtrace = ::AppPerfRpm::Backtrace.backtrace
53
+ span.source = ::AppPerfRpm::Backtrace.source_extract
54
+ span.options = {
55
+ "method" => "render_partial",
56
+ "name" => @options[:partial]
57
+ }
58
+
59
+ render_partial_without_trace
60
+ end
61
+ else
62
+ render_partial_without_trace
63
+ end
64
+ end
65
+
66
+ alias :render_collection_without_trace :render_collection
67
+ def render_collection
68
+ if ::AppPerfRpm::Tracer.tracing?
69
+ AppPerfRpm::Tracer.trace("actionview") do |span|
70
+ span.options = {
71
+ "method" => "render_collection",
72
+ "name" => @path
73
+ }
74
+
75
+ render_collection_without_trace
76
+ end
77
+ else
78
+ render_collection_without_trace
79
+ end
80
+ end
81
+ end
82
+
83
+ ::ActionView::TemplateRenderer.class_eval do
84
+ alias render_with_layout_without_trace render_with_layout
85
+
86
+ def render_with_layout(path, locals, *args, &block)
87
+ if ::AppPerfRpm::Tracer.tracing?
88
+ layout = nil
89
+
90
+ if path
91
+ if method(:find_layout).arity == 3
92
+ # Rails 5
93
+ layout = find_layout(path, locals.keys, [formats.first])
94
+ else
95
+ # Rails 3, 4
96
+ layout = find_layout(path, locals.keys)
97
+ end
98
+
99
+ @path = path
100
+ end
101
+
102
+ AppPerfRpm::Tracer.trace("actionview") do |span|
103
+ if layout
104
+ span.options = {
105
+ "method" => "render_with_layout",
106
+ "name" => layout.identifier,
107
+ "path" => @path,
108
+ "layout" => layout
109
+ }
110
+ else
111
+ span.options = {
112
+ "method" => "render_without_layout",
113
+ "path" => @path
114
+ }
115
+ end
116
+ render_with_layout_without_trace(path, locals, *args, &block)
117
+ end
118
+ else
119
+ render_with_layout_without_trace(path, locals, *args, &block)
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ AppPerfRpm.logger.info "Initializing actionview tracer."
126
+ end
@@ -0,0 +1,45 @@
1
+ module AppPerfRpm
2
+ module Instruments
3
+ module ActiveRecord
4
+ module Adapters
5
+ module Mysql2
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 execute_with_trace(sql, name = nil)
21
+ if ::AppPerfRpm::Tracer.tracing?
22
+ if ignore_trace?(name)
23
+ execute_without_trace(sql, name)
24
+ else
25
+ sanitized_sql = sanitize_sql(sql, :mysql2)
26
+
27
+ AppPerfRpm::Tracer.trace('activerecord') do |span|
28
+ span.options ={
29
+ "adapter" => "mysql2",
30
+ "query" => sanitized_sql,
31
+ "name" => name
32
+ }
33
+
34
+ execute_without_trace(sql, name)
35
+ end
36
+ end
37
+ else
38
+ execute_without_trace(sql, name)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,102 @@
1
+ module AppPerfRpm
2
+ module Instruments
3
+ module ActiveRecord
4
+ module Adapters
5
+ module Postgresql
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, :postgres)
26
+
27
+ AppPerfRpm::Tracer.trace('activerecord') do |span|
28
+ span.options = {
29
+ "adapter" => "postgresql",
30
+ "query" => sanitized_sql,
31
+ "name" => name
32
+ }
33
+ exec_query_without_trace(sql, name, binds)
34
+ end
35
+ end
36
+ else
37
+ exec_query_without_trace(sql, name, binds)
38
+ end
39
+ end
40
+
41
+ def exec_delete_with_trace(sql, name = nil, binds = [])
42
+ if ::AppPerfRpm::Tracer.tracing?
43
+ if ignore_trace?(name)
44
+ exec_delete_without_trace(sql, name, binds)
45
+ else
46
+ sanitized_sql = sanitize_sql(sql)
47
+
48
+ AppPerfRpm::Tracer.trace('activerecord') do |span|
49
+ span.options = {
50
+ "adapter" => "postgresql",
51
+ "query" => sanitized_sql,
52
+ "name" => name
53
+ }
54
+ exec_delete_without_trace(sql, name, binds)
55
+ end
56
+ end
57
+ else
58
+ exec_delete_without_trace(sql, name, binds)
59
+ end
60
+ end
61
+
62
+ def exec_insert_with_trace(sql, name = nil, binds = [], *args)
63
+ if ::AppPerfRpm::Tracer.tracing?
64
+ if ignore_trace?(name)
65
+ exec_insert_without_trace(sql, name, binds, *args)
66
+ else
67
+ sanitized_sql = sanitize_sql(sql, :postgres)
68
+
69
+ AppPerfRpm::Tracer.trace('activerecord') do |span|
70
+ span.options = {
71
+ "adapter" => "postgresql",
72
+ "query" => sanitized_sql,
73
+ "name" => name
74
+ }
75
+
76
+ exec_insert_without_trace(sql, name, binds, *args)
77
+ end
78
+ end
79
+ else
80
+ exec_insert_without_trace(sql, name, binds, *args)
81
+ end
82
+ end
83
+
84
+ def begin_db_transaction_with_trace
85
+ if ::AppPerfRpm::Tracer.tracing?
86
+ AppPerfRpm::Tracer.trace('activerecord') do |span|
87
+ span.options = {
88
+ "adapter" => "postgresql",
89
+ "query" => "BEGIN"
90
+ }
91
+
92
+ begin_db_transaction_without_trace
93
+ end
94
+ else
95
+ begin_db_transaction_without_trace
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end