class StackifyRubyAPM::Spies::SequelSpy

@api private

Constants

DEFAULT
FORMAT
REGEXES
TABLE_REGEX
TYPE

Public Instance Methods

check_prepared_stmt(statement, payload) click to toggle source
# File lib/stackify_apm/spies/sequel.rb, line 63
def check_prepared_stmt(statement, payload)
  if StackifyRubyAPM.agent.config.prefix_enabled
    case get_profiler(payload[:db_adapter])
    when 'generic', 'mysql', 'sqlite', 'oracle', 'db2'
      # We check the placeholder of sequel mysql by ? and sometimes sequel sqlite is using : or ?
      if check_prepared_stmt_by_placeholder(payload[:sql].include?('?'), statement, payload)
      else check_prepared_stmt_by_placeholder(payload[:sql].include?(':'), statement, payload)
      end
    when 'postgresql'
      check_prepared_stmt_by_placeholder(!!payload[:sql].match(/\$\d/), statement, payload)
    end
  end
end
install() click to toggle source
# File lib/stackify_apm/spies/sequel.rb, line 26
def install
  require 'sequel/database/logging'

  ::Sequel::Database.class_eval do
    alias_method 'log_connection_yield_without_apm', 'log_connection_yield'

    def log_connection_yield(sql, *args, &block)
      return log_connection_yield_without_apm(sql, *args, &block) unless StackifyRubyAPM.current_transaction

      name = summarize sql
      db_adapter = ''
      db_adapter = args[0].class.to_s.gsub('::Database', '').downcase if args[0]
      payload = {sql: sql, db_adapter: db_adapter, binds: defined?(args[1]) ? args[1]: []}
      statement = query_variables(payload)
      check_prepared_stmt(statement, payload)
      ctx = Span::Context.new(statement)

      StackifyRubyAPM.span(name, TYPE, context: ctx, &block)
    end

    # rubocop:disable Lint/UselessAssignment
    def summarize(sql)
      current_sql ||=
        REGEXES.find do |regex, sig|
          if (match = sql.match(regex))
            break format(FORMAT, sig, match[1] && match[1].gsub(/["']/, ''))
          end
        end || DEFAULT
    end

    def query_variables(payload)
      props = get_common_db_properties
      props[:PROVIDER] = get_profiler(payload[:db_adapter])
      props[:SQL] = payload[:sql]
      props
    end

    def check_prepared_stmt(statement, payload)
      if StackifyRubyAPM.agent.config.prefix_enabled
        case get_profiler(payload[:db_adapter])
        when 'generic', 'mysql', 'sqlite', 'oracle', 'db2'
          # We check the placeholder of sequel mysql by ? and sometimes sequel sqlite is using : or ?
          if check_prepared_stmt_by_placeholder(payload[:sql].include?('?'), statement, payload)
          else check_prepared_stmt_by_placeholder(payload[:sql].include?(':'), statement, payload)
          end
        when 'postgresql'
          check_prepared_stmt_by_placeholder(!!payload[:sql].match(/\$\d/), statement, payload)
        end
      end
    end
  end
  # rubocop:enable Lint/UselessAssignment
end
log_connection_yield(sql, *args, &block) click to toggle source
# File lib/stackify_apm/spies/sequel.rb, line 32
def log_connection_yield(sql, *args, &block)
  return log_connection_yield_without_apm(sql, *args, &block) unless StackifyRubyAPM.current_transaction

  name = summarize sql
  db_adapter = ''
  db_adapter = args[0].class.to_s.gsub('::Database', '').downcase if args[0]
  payload = {sql: sql, db_adapter: db_adapter, binds: defined?(args[1]) ? args[1]: []}
  statement = query_variables(payload)
  check_prepared_stmt(statement, payload)
  ctx = Span::Context.new(statement)

  StackifyRubyAPM.span(name, TYPE, context: ctx, &block)
end
query_variables(payload) click to toggle source
# File lib/stackify_apm/spies/sequel.rb, line 56
def query_variables(payload)
  props = get_common_db_properties
  props[:PROVIDER] = get_profiler(payload[:db_adapter])
  props[:SQL] = payload[:sql]
  props
end
summarize(sql) click to toggle source

rubocop:disable Lint/UselessAssignment

# File lib/stackify_apm/spies/sequel.rb, line 47
def summarize(sql)
  current_sql ||=
    REGEXES.find do |regex, sig|
      if (match = sql.match(regex))
        break format(FORMAT, sig, match[1] && match[1].gsub(/["']/, ''))
      end
    end || DEFAULT
end