Module: Bigcommerce::Lightstep::ActiveRecord::Adapter

Extended by:
ActiveSupport::Concern
Defined in:
lib/bigcommerce/lightstep/active_record/adapter.rb

Overview

Patches mysql and ActiveRecord to allow for mysql span tracing

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.enabled?Boolean

Note: we only support patching mysql2 gem at this point

Returns:

  • (Boolean)


43
44
45
46
47
48
# File 'lib/bigcommerce/lightstep/active_record/adapter.rb', line 43

def self.enabled?
  defined?(::ActiveRecord) && ::Bigcommerce::Lightstep.active_record && ::ActiveRecord::Base.connection_config[:adapter].to_s.casecmp('mysql2').zero?
rescue StandardError => e
  ::Bigcommerce::Lightstep.logger&.warn "Failed to determine ActiveRecord database adapter in bc-lightstep-ruby initializer: #{e.message}"
  false
end

.patchObject

Patch ActiveRecord to enable mysql span traces



30
31
32
33
34
35
36
# File 'lib/bigcommerce/lightstep/active_record/adapter.rb', line 30

def self.patch
  return unless enabled?

  # rubocop:disable Lint/SendWithMixinArgument
  ::ActiveRecord::ConnectionAdapters::Mysql2Adapter.send(:include, ::Bigcommerce::Lightstep::ActiveRecord::Adapter)
  # rubocop:enable Lint/SendWithMixinArgument
end

Instance Method Details

#execute_with_inst(sql, name = 'SQL') ⇒ Object

Parameters:

  • sql (String)

    The raw sql query

  • name (String) (defaults to: 'SQL')

    The type of sql query



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/bigcommerce/lightstep/active_record/adapter.rb', line 54

def execute_with_inst(sql, name = 'SQL')
  # bail out early if not enabled. This should not get here, but is provided as a failsafe.
  return execute_without_inst(sql, name) unless ::Bigcommerce::Lightstep.active_record

  sanitized_sql = lightstep_sanitize_sql(sql)
  name = 'QUERY' if name.to_s.strip.empty?

  # we dont need to track all sql
  return execute_without_inst(sql, name) if lightstep_skip_tracing?(name, sanitized_sql)

  lightstep_tracer.db_trace(
    statement: sanitized_sql,
    host: @config[:host],
    adapter: @config[:adapter],
    database: @config[:database]
  ) do
    execute_without_inst(sql, name)
  end
end

#lightstep_sanitization_regexpRegexp

Returns:

  • (Regexp)


87
88
89
# File 'lib/bigcommerce/lightstep/active_record/adapter.rb', line 87

def lightstep_sanitization_regexp
  @lightstep_sanitization_regexp ||= ::Regexp.new('(\'[\s\S][^\']*\'|\d*\.\d+|\d+|NULL)', ::Regexp::IGNORECASE)
end

#lightstep_sanitize_sql(sql) ⇒ String

Sanitize the sql for safe logging

Parameters:

  • (String)

Returns:

  • (String)


80
81
82
# File 'lib/bigcommerce/lightstep/active_record/adapter.rb', line 80

def lightstep_sanitize_sql(sql)
  sql.to_s.gsub(lightstep_sanitization_regexp, '?').tr("\n", ' ').to_s
end

#lightstep_skip_tracing?(name, sql) ⇒ Boolean

Filter out sql queries from tracing we don’t care about

Parameters:

  • name (String)
  • sql (String)

Returns:

  • (Boolean)


97
98
99
# File 'lib/bigcommerce/lightstep/active_record/adapter.rb', line 97

def lightstep_skip_tracing?(name, sql)
  name.empty? || sql.empty? || sql.include?('COMMIT') || sql.include?('SCHEMA') || sql.include?('SHOW FULL FIELDS')
end

#lightstep_tracer::Bigcommerce::Lightstep::ActiveRecord::Tracer



104
105
106
# File 'lib/bigcommerce/lightstep/active_record/adapter.rb', line 104

def lightstep_tracer
  @lightstep_tracer ||= ::Bigcommerce::Lightstep::ActiveRecord::Tracer.new
end