Skip to content

Commit

Permalink
Feature: Add a limit of the number of logs to put in redis
Browse files Browse the repository at this point in the history
  • Loading branch information
syphax-bouazzouni committed Jan 21, 2025
1 parent da3c909 commit ff0459f
Showing 1 changed file with 35 additions and 3 deletions.
38 changes: 35 additions & 3 deletions lib/sparql/client/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ class Logging

REDIS_EXPIRY = 86_400 # 24 hours

def initialize(redis:, redis_key: 'query_logs', redis_expiry: REDIS_EXPIRY, logger: nil)
def initialize(redis:, redis_key: 'query_logs', redis_expiry: REDIS_EXPIRY, logger: nil, max_logs: 1000)
@redis = redis
@logger = logger
@redis_key = redis_key
@redis_expiry = redis_expiry
@enabled = !logger.nil?
@max_logs = max_logs
@count_key = "#{@redis_key}-count"
end

def log(query, id: SecureRandom.uuid, cached: nil, user: nil, &block)
Expand Down Expand Up @@ -47,6 +49,9 @@ def info(query, id: SecureRandom.uuid, cached: 'null', user: 'null', execution_t

@redis.set(key, entry)
@redis.expire(key, @redis_expiry)
@redis.incr(@count_key)

enforce_log_limit(@redis.get(@count_key).to_i)
end

def get_logs
Expand All @@ -62,8 +67,8 @@ def queries_last_n_seconds(seconds)
loop do
cursor, keys = @redis.scan(cursor, match: "#{@redis_key}-*", count: 100)
keys.each do |key|
timestamp = key.split('-').last
next unless timestamp && timestamp.include?('T')
timestamp = extract_timestamp_from_key(key)
next if timestamp.nil?

log_time = Time.parse(timestamp)
if (current_time - log_time) <= seconds
Expand All @@ -85,6 +90,33 @@ def logger=(logger)

private

def extract_timestamp_from_key(key)
timestamp = key.split('-').last
return nil unless timestamp.include?('T')
timestamp
end

def enforce_log_limit(log_count)
return unless log_count >= @max_logs * 2

keys = @redis.keys("#{@redis_key}-*")
keys_with_timestamps = keys.map do |key|
timestamp = extract_timestamp_from_key(key)
[key, Time.parse(timestamp)] if timestamp
end.compact

keys_with_timestamps.sort_by! { |_, time| time }

old_logs = keys_with_timestamps.first(keys_with_timestamps.size - @max_logs).map(&:first)

@redis.del(*old_logs) unless old_logs.empty?

if old_logs.any?
old_count = @redis.get(@count_key).to_i
@redis.set(@count_key, old_count - old_logs.size)
end
end

def encode_data(entry)
data = Marshal.dump(entry.to_json)
if data.length > 50e6 # 50MB of marshal object
Expand Down

0 comments on commit ff0459f

Please sign in to comment.