diff options
Diffstat (limited to 'lib/gitlab/instrumentation/redis.rb')
-rw-r--r-- | lib/gitlab/instrumentation/redis.rb | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/gitlab/instrumentation/redis.rb b/lib/gitlab/instrumentation/redis.rb new file mode 100644 index 00000000000..f9a6fdc05aa --- /dev/null +++ b/lib/gitlab/instrumentation/redis.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'redis' + +module Gitlab + module Instrumentation + module RedisInterceptor + def call(*args, &block) + start = Time.now + super(*args, &block) + ensure + duration = (Time.now - start) + + if ::RequestStore.active? + ::Gitlab::Instrumentation::Redis.increment_request_count + ::Gitlab::Instrumentation::Redis.add_duration(duration) + ::Gitlab::Instrumentation::Redis.add_call_details(duration, args) + end + end + end + + class Redis + REDIS_REQUEST_COUNT = :redis_request_count + REDIS_CALL_DURATION = :redis_call_duration + REDIS_CALL_DETAILS = :redis_call_details + + def self.get_request_count + ::RequestStore[REDIS_REQUEST_COUNT] || 0 + end + + def self.increment_request_count + ::RequestStore[REDIS_REQUEST_COUNT] ||= 0 + ::RequestStore[REDIS_REQUEST_COUNT] += 1 + end + + def self.detail_store + ::RequestStore[REDIS_CALL_DETAILS] ||= [] + end + + def self.query_time_ms + (self.query_time * 1000).round(2) + end + + def self.query_time + ::RequestStore[REDIS_CALL_DURATION] || 0 + end + + def self.add_duration(duration) + total_time = query_time + duration + ::RequestStore[REDIS_CALL_DURATION] = total_time + end + + def self.add_call_details(duration, args) + return unless Gitlab::PerformanceBar.enabled_for_request? + # redis-rb passes an array (e.g. [:get, key]) + return unless args.length == 1 + + detail_store << { + cmd: args.first, + duration: duration, + backtrace: ::Gitlab::BacktraceCleaner.clean_backtrace(caller) + } + end + end + end +end + +class ::Redis::Client + prepend ::Gitlab::Instrumentation::RedisInterceptor +end |