Skip to content

Commit

Permalink
Change the Redis client patch to use prepend (#1743)
Browse files Browse the repository at this point in the history
  • Loading branch information
justinhoward authored Oct 28, 2021
1 parent 6180c0e commit e84cdfa
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 114 deletions.
90 changes: 90 additions & 0 deletions lib/ddtrace/contrib/redis/instrumentation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# typed: false
require 'ddtrace/contrib/patcher'
require 'ddtrace/contrib/redis/ext'
require 'ddtrace/contrib/redis/configuration/resolver'

module Datadog
module Contrib
module Redis
# Instrumentation for Redis
module Instrumentation
def self.included(base)
base.prepend(InstanceMethods)
end

# InstanceMethods - implementing instrumentation
module InstanceMethods
def call(*args, &block)
pin = Datadog::Pin.get_from(self)
return super unless pin && pin.tracer

response = nil
pin.tracer.trace(Datadog::Contrib::Redis::Ext::SPAN_COMMAND) do |span|
span.service = pin.service
span.span_type = Datadog::Contrib::Redis::Ext::TYPE
span.resource = get_command(args)
Datadog::Contrib::Redis::Tags.set_common_tags(self, span)

response = super
end

response
end

def call_pipeline(*args, &block)
pin = Datadog::Pin.get_from(self)
return super unless pin && pin.tracer

response = nil
pin.tracer.trace(Datadog::Contrib::Redis::Ext::SPAN_COMMAND) do |span|
span.service = pin.service
span.span_type = Datadog::Contrib::Redis::Ext::TYPE
commands = get_pipeline_commands(args)
span.resource = commands.join("\n")
span.set_metric Datadog::Contrib::Redis::Ext::METRIC_PIPELINE_LEN, commands.length
Datadog::Contrib::Redis::Tags.set_common_tags(self, span)

response = super
end

response
end

def datadog_pin
@datadog_pin ||= begin
pin = Datadog::Pin.new(
datadog_configuration[:service_name],
app: Ext::APP,
app_type: Datadog::Ext::AppTypes::DB,
tracer: -> { datadog_configuration[:tracer] }
)
pin.onto(self)
end
end

private

def get_command(args)
if datadog_configuration[:command_args]
Datadog::Contrib::Redis::Quantize.format_command_args(*args)
else
Datadog::Contrib::Redis::Quantize.get_verb(*args)
end
end

def get_pipeline_commands(args)
if datadog_configuration[:command_args]
args[0].commands.map { |c| Datadog::Contrib::Redis::Quantize.format_command_args(c) }
else
args[0].commands.map { |c| Datadog::Contrib::Redis::Quantize.get_verb(c) }
end
end

def datadog_configuration
Datadog.configuration[:redis, options]
end
end
end
end
end
end
86 changes: 2 additions & 84 deletions lib/ddtrace/contrib/redis/patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,92 +23,10 @@ def patch
require 'ddtrace/ext/app_types'
require 'ddtrace/contrib/redis/tags'
require 'ddtrace/contrib/redis/quantize'
require 'ddtrace/contrib/redis/instrumentation'

patch_redis_client
::Redis::Client.include(Instrumentation)
end

# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/BlockLength
# rubocop:disable Metrics/AbcSize
def patch_redis_client
::Redis::Client.class_eval do
alias_method :call_without_datadog, :call
remove_method :call
def call(*args, &block)
pin = Datadog::Pin.get_from(self)
return call_without_datadog(*args, &block) unless pin && pin.tracer

response = nil
pin.tracer.trace(Datadog::Contrib::Redis::Ext::SPAN_COMMAND) do |span|
span.service = pin.service
span.span_type = Datadog::Contrib::Redis::Ext::TYPE
span.resource = get_command(args)
Datadog::Contrib::Redis::Tags.set_common_tags(self, span)

response = call_without_datadog(*args, &block)
end

response
end

alias_method :call_pipeline_without_datadog, :call_pipeline
remove_method :call_pipeline
def call_pipeline(*args, &block)
pin = Datadog::Pin.get_from(self)
return call_pipeline_without_datadog(*args, &block) unless pin && pin.tracer

response = nil
pin.tracer.trace(Datadog::Contrib::Redis::Ext::SPAN_COMMAND) do |span|
span.service = pin.service
span.span_type = Datadog::Contrib::Redis::Ext::TYPE
commands = get_pipeline_commands(args)
span.resource = commands.join("\n")
span.set_metric Datadog::Contrib::Redis::Ext::METRIC_PIPELINE_LEN, commands.length
Datadog::Contrib::Redis::Tags.set_common_tags(self, span)

response = call_pipeline_without_datadog(*args, &block)
end

response
end

def datadog_pin
@datadog_pin ||= begin
pin = Datadog::Pin.new(
datadog_configuration[:service_name],
app: Ext::APP,
app_type: Datadog::Ext::AppTypes::DB,
tracer: -> { datadog_configuration[:tracer] }
)
pin.onto(self)
end
end

private

def get_command(args)
if datadog_configuration[:command_args]
Datadog::Contrib::Redis::Quantize.format_command_args(*args)
else
Datadog::Contrib::Redis::Quantize.get_verb(*args)
end
end

def get_pipeline_commands(args)
if datadog_configuration[:command_args]
args[0].commands.map { |c| Datadog::Contrib::Redis::Quantize.format_command_args(c) }
else
args[0].commands.map { |c| Datadog::Contrib::Redis::Quantize.get_verb(c) }
end
end

def datadog_configuration
Datadog.configuration[:redis, options]
end
end
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/BlockLength
end
end
end
Expand Down
30 changes: 0 additions & 30 deletions spec/ddtrace/contrib/redis/method_replaced_spec.rb

This file was deleted.

14 changes: 14 additions & 0 deletions spec/ddtrace/contrib/redis/patcher_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# typed: false
require 'ddtrace/contrib/support/spec_helper'
require 'ddtrace'

RSpec.describe Datadog::Contrib::Redis::Patcher do
describe '.patch' do
it 'adds Instrumentation methods to ancestors of Redis class' do
described_class.patch

expect(Redis::Client.ancestors).to include(Datadog::Contrib::Redis::Instrumentation)
expect(Redis::Client.ancestors).to include(Datadog::Contrib::Redis::Instrumentation)
end
end
end

0 comments on commit e84cdfa

Please sign in to comment.