lib/instana/instrumentation/redis.rb in instana-1.213.3 vs lib/instana/instrumentation/redis.rb in instana-1.214.0
- old
+ new
@@ -1,59 +1,86 @@
-# (c) Copyright IBM Corp. 2021
+# (c) Copyright IBM Corp. 2024
# (c) Copyright Instana Inc. 2017
module Instana
module RedisInstrumentation
- def call(*args, &block)
- kv_payload = { redis: {} }
- dnt_spans = [:redis, :'resque-client', :'sidekiq-client']
+ if Gem::Specification.find_by_name('redis').version >= Gem::Version.new('5.0') && defined?(::RedisClient)
+ ORIGINAL_METHODS = {
+ :call_v => ::RedisClient.instance_method(:call_v),
+ :pipelined => ::RedisClient.instance_method(:pipelined),
+ :multi => ::RedisClient.instance_method(:multi)
+ }.freeze
- if !Instana.tracer.tracing? || dnt_spans.include?(::Instana.tracer.current_span.name) || !Instana.config[:redis][:enabled]
- return super(*args, &block)
+ def call_v(*args, &block)
+ if skip_instrumentation?
+ super(*args, &block)
+ else
+ call_with_instana(args[0][0].to_s.upcase, ORIGINAL_METHODS[:call_v], *args, &block)
+ end
end
- begin
- ::Instana.tracer.log_entry(:redis)
+ def pipelined(*args, &block)
+ if skip_instrumentation?
+ super(*args, &block)
+ else
+ call_with_instana('PIPELINE', ORIGINAL_METHODS[:pipelined], *args, &block)
+ end
+ end
- begin
- kv_payload[:redis][:connection] = "#{self.host}:#{self.port}"
- kv_payload[:redis][:db] = db.to_s
- kv_payload[:redis][:command] = args[0][0].to_s.upcase
- rescue
- nil
+ # Since, starting with 5.1 redis/client.rb:114:multi takes an unused default argument `watch: nil`
+ # but calls redis_client.rb:442:multi, which doesn't take any argument,
+ # here we have to take arguments but we should not use it.
+ def multi(*_, &block)
+ if skip_instrumentation?
+ super(&block)
+ else
+ call_with_instana('MULTI', ORIGINAL_METHODS[:multi], &block)
end
+ end
- super(*args, &block)
- rescue => e
- ::Instana.tracer.log_info({ redis: {error: true} })
- ::Instana.tracer.log_error(e)
- raise
- ensure
- ::Instana.tracer.log_exit(:redis, kv_payload)
+ else
+ ORIGINAL_METHODS = {
+ :call => ::Redis::Client.instance_method(:call),
+ :call_pipeline => ::Redis::Client.instance_method(:call_pipeline)
+ }.freeze
+
+ def call(*args, &block)
+ if skip_instrumentation?
+ super(*args, &block)
+ else
+ call_with_instana(args[0][0].to_s.upcase, ORIGINAL_METHODS[:call], *args, &block)
+ end
end
+
+ def call_pipeline(*args, &block)
+ if skip_instrumentation?
+ super(*args, &block)
+ else
+ call_with_instana(args.first.is_a?(::Redis::Pipeline::Multi) ? 'MULTI' : 'PIPELINE', ORIGINAL_METHODS[:call_pipeline], *args, &block)
+ end
+ end
end
- def call_pipeline(*args, &block)
- kv_payload = { redis: {} }
+ def skip_instrumentation?
dnt_spans = [:redis, :'resque-client', :'sidekiq-client']
+ !Instana.tracer.tracing? || dnt_spans.include?(::Instana.tracer.current_span.name) || !Instana.config[:redis][:enabled]
+ end
- if !Instana.tracer.tracing? || dnt_spans.include?(::Instana.tracer.current_span.name) || !Instana.config[:redis][:enabled]
- return super(*args, &block)
- end
+ def call_with_instana(*args, &block)
+ command, original_super, *original_args = *args
+ kv_payload = { redis: {} }
begin
::Instana.tracer.log_entry(:redis)
- pipeline = args.first
begin
kv_payload[:redis][:connection] = "#{self.host}:#{self.port}"
kv_payload[:redis][:db] = db.to_s
- kv_payload[:redis][:command] = pipeline.is_a?(::Redis::Pipeline::Multi) ? 'MULTI' : 'PIPELINE'
+ kv_payload[:redis][:command] = command
rescue
nil
end
-
- super(*args, &block)
+ original_super.bind(self).call(*original_args, &block)
rescue => e
::Instana.tracer.log_info({ redis: {error: true} })
::Instana.tracer.log_error(e)
raise
ensure