Class: CpuInspectCore::Backends::RedisBackend

Inherits:
Object
  • Object
show all
Defined in:
lib/cpu_inspect_core/backends/redis_backend.rb

Overview

Redis backend: each dyno writes its latest sample to a Redis key tagged with the Heroku $DYNO identifier (web.1, web.2, …). Keys expire after ‘config.redis_ttl` seconds so dead dynos disappear automatically without manual cleanup.

Requires the ‘redis` gem:

gem "redis", "~> 5.0"

Configure in an initializer:

CpuInspectCore.configure do |c|
  c.backend   = :redis
  c.redis_url = ENV["REDIS_URL"]
end

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ RedisBackend

Returns a new instance of RedisBackend.



22
23
24
25
26
27
28
29
30
# File 'lib/cpu_inspect_core/backends/redis_backend.rb', line 22

def initialize(config)
  load_redis_gem!

  @redis      = Redis.new(url: config.redis_url)
  @prefix     = config.redis_key_prefix
  @ttl        = config.redis_ttl
  @store      = Store.new # in-process latest for fast local reads
  @log_writer = LogWriter.new(config) # local rotating file log (per-dyno)
end

Instance Method Details

#all_dynosObject

Returns { “web.1” => sample, “web.2” => sample, … } for every live dyno. Dynos whose TTL has expired are automatically absent.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/cpu_inspect_core/backends/redis_backend.rb', line 46

def all_dynos
  results = {}
  cursor  = '0'

  loop do
    cursor, keys = @redis.scan(cursor, match: "#{@prefix}:*", count: 100)
    keys.each do |key|
      dyno = key.delete_prefix("#{@prefix}:")
      raw  = @redis.get(key)
      next unless raw

      results[dyno] = JSON.parse(raw, symbolize_names: true)
    end
    break if cursor == '0'
  end

  results.sort_by { |k, _| k }.to_h
end

#latestObject

Most recent sample written by this process (no network round-trip).



40
41
42
# File 'lib/cpu_inspect_core/backends/redis_backend.rb', line 40

def latest
  @store.latest
end

#write(payload) ⇒ Object



32
33
34
35
36
37
# File 'lib/cpu_inspect_core/backends/redis_backend.rb', line 32

def write(payload)
  dyno = ENV.fetch('DYNO', 'local')
  @redis.set(redis_key(dyno), JSON.generate(payload), ex: @ttl)
  @store.push(payload)
  @log_writer.write(payload)
end