class StackifyRubyAPM::Spies::RedisSpy

@api private

Public Instance Methods

call(command, &block) click to toggle source
# File lib/stackify_apm/spies/redis.rb, line 16
def call(command, &block)
  begin
    name = command[0].upcase.to_s
    type = 'db.redis'
    redis_details = command[1].is_a?(String) ? command[1].split(':') : []
    # use length instead of .blank?
    # reason: will throw error if activesupport missing
    redis_nspace = redis_details.length ? redis_details[0] : ''
    redis_key = ''

    # Checks CACHEKEY value
    if redis_details.length && redis_details[1]
      # Initially sets the CACHEKEY value
      args = redis_details[1].split('/')
      redis_key = args[0]

      # If command has passed __method__, it will be included in the CACHEKEY value
      # Possible formats:
      # `<namespace:key/method_name/expires_in=300/ttl=60/>`
      # `<namespace:key/expires_in=300/ttl=60/>`
      if redis_key.nil?
        redis_key = redis_details[1]
      else
        redis_key = args[0..1].join('/') if args.length > 1 && !args[1].include?('=')
      end
    end

    return call_without_apm(command, &block) if command[0] == :auth

    context = {
      PROVIDER: 'Redis',
      CATEGORY: 'Cache',
      SUBCATEGORY: 'Execute',
      COMPONENT_CATEGORY: 'Cache',
      COMPONENT_DETAIL: 'Execute',
      THREAD_ID: Thread.current.object_id,
      OPERATION: name,
      URL: "#{self.options[:host]}:#{self.options[:port]}"
    }.tap do |hash|
      hash[:CACHEKEY] = redis_key unless redis_key.nil? || redis_key.empty?
      hash[:CACHENAME] = redis_nspace unless redis_nspace.nil? || redis_nspace.empty?
    end

    ctx = Span::Context.new(context)
  rescue Exception => e
    StackifyRubyAPM.agent.error "[RedisSpy] Error: creating span context."
    StackifyRubyAPM.agent.error "[RedisSpy] #{e.inspect}"
    return call_without_apm(command, &block)
  end

  StackifyRubyAPM.span name, type, context: ctx do
    call_without_apm(command, &block)
  end
end
install() click to toggle source

rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity

# File lib/stackify_apm/spies/redis.rb, line 12
def install
  ::Redis::Client.class_eval do
    alias_method 'call_without_apm', 'call'

    def call(command, &block)
      begin
        name = command[0].upcase.to_s
        type = 'db.redis'
        redis_details = command[1].is_a?(String) ? command[1].split(':') : []
        # use length instead of .blank?
        # reason: will throw error if activesupport missing
        redis_nspace = redis_details.length ? redis_details[0] : ''
        redis_key = ''

        # Checks CACHEKEY value
        if redis_details.length && redis_details[1]
          # Initially sets the CACHEKEY value
          args = redis_details[1].split('/')
          redis_key = args[0]

          # If command has passed __method__, it will be included in the CACHEKEY value
          # Possible formats:
          # `<namespace:key/method_name/expires_in=300/ttl=60/>`
          # `<namespace:key/expires_in=300/ttl=60/>`
          if redis_key.nil?
            redis_key = redis_details[1]
          else
            redis_key = args[0..1].join('/') if args.length > 1 && !args[1].include?('=')
          end
        end

        return call_without_apm(command, &block) if command[0] == :auth

        context = {
          PROVIDER: 'Redis',
          CATEGORY: 'Cache',
          SUBCATEGORY: 'Execute',
          COMPONENT_CATEGORY: 'Cache',
          COMPONENT_DETAIL: 'Execute',
          THREAD_ID: Thread.current.object_id,
          OPERATION: name,
          URL: "#{self.options[:host]}:#{self.options[:port]}"
        }.tap do |hash|
          hash[:CACHEKEY] = redis_key unless redis_key.nil? || redis_key.empty?
          hash[:CACHENAME] = redis_nspace unless redis_nspace.nil? || redis_nspace.empty?
        end

        ctx = Span::Context.new(context)
      rescue Exception => e
        StackifyRubyAPM.agent.error "[RedisSpy] Error: creating span context."
        StackifyRubyAPM.agent.error "[RedisSpy] #{e.inspect}"
        return call_without_apm(command, &block)
      end

      StackifyRubyAPM.span name, type, context: ctx do
        call_without_apm(command, &block)
      end
    end
  end
end