Class: BrainzLab::Utilities::HealthCheck

Inherits:
Object
  • Object
show all
Defined in:
lib/brainzlab/utilities/health_check.rb

Overview

Health check utility for application health endpoints Provides checks for database, cache, queues, and external services

Examples:

Basic usage in Rails routes

# config/routes.rb
mount BrainzLab::Utilities::HealthCheck::Engine => "/health"

Manual usage

result = BrainzLab::Utilities::HealthCheck.run
result[:status]  # => "healthy" or "unhealthy"
result[:checks]  # => { database: { status: "ok", latency_ms: 5 }, ... }

Defined Under Namespace

Classes: Engine, HealthController

Constant Summary collapse

CHECKS =
%i[database redis cache queue memory disk].freeze

Class Method Summary collapse

Class Method Details

.check_cacheObject

Rails cache check



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/brainzlab/utilities/health_check.rb', line 79

def check_cache
  return { status: 'skip', message: 'Rails not loaded' } unless defined?(Rails)

  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  key = "brainzlab_health_check_#{SecureRandom.hex(4)}"
  Rails.cache.write(key, 'ok', expires_in: 10.seconds)
  value = Rails.cache.read(key)
  Rails.cache.delete(key)
  latency = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).round(2)

  if value == 'ok'
    { status: 'ok', latency_ms: latency }
  else
    { status: 'error', message: 'Cache read/write failed' }
  end
rescue StandardError => e
  { status: 'error', message: e.message }
end

.check_databaseObject

Database connectivity check



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/brainzlab/utilities/health_check.rb', line 50

def check_database
  return { status: 'skip', message: 'ActiveRecord not loaded' } unless defined?(ActiveRecord::Base)

  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  ActiveRecord::Base.connection.execute('SELECT 1')
  latency = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).round(2)

  { status: 'ok', latency_ms: latency }
rescue StandardError => e
  { status: 'error', message: e.message }
end

.check_diskObject

Disk space check



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/brainzlab/utilities/health_check.rb', line 133

def check_disk
  disk_info = disk_usage

  status = if disk_info[:percentage] > 90
             'warning'
           elsif disk_info[:percentage] > 95
             'error'
           else
             'ok'
           end

  {
    status: status,
    used_gb: disk_info[:used_gb],
    available_gb: disk_info[:available_gb],
    percentage: disk_info[:percentage]
  }
rescue StandardError => e
  { status: 'error', message: e.message }
end

.check_memoryObject

Memory usage check



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/brainzlab/utilities/health_check.rb', line 112

def check_memory
  mem_info = memory_usage

  status = if mem_info[:percentage] > 90
             'warning'
           elsif mem_info[:percentage] > 95
             'error'
           else
             'ok'
           end

  {
    status: status,
    used_mb: mem_info[:used_mb],
    percentage: mem_info[:percentage]
  }
rescue StandardError => e
  { status: 'error', message: e.message }
end

.check_queueObject

Queue system check



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/brainzlab/utilities/health_check.rb', line 99

def check_queue
  if defined?(SolidQueue)
    check_solid_queue
  elsif defined?(Sidekiq)
    check_sidekiq
  elsif defined?(GoodJob)
    check_good_job
  else
    { status: 'skip', message: 'No queue system detected' }
  end
end

.check_redisObject

Redis connectivity check



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/brainzlab/utilities/health_check.rb', line 63

def check_redis
  return { status: 'skip', message: 'Redis not configured' } unless defined?(Redis)

  redis = find_redis_connection
  return { status: 'skip', message: 'No Redis connection found' } unless redis

  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  redis.ping
  latency = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).round(2)

  { status: 'ok', latency_ms: latency }
rescue StandardError => e
  { status: 'error', message: e.message }
end

.custom_checksObject



159
160
161
# File 'lib/brainzlab/utilities/health_check.rb', line 159

def custom_checks
  @custom_checks ||= {}
end

.healthy?Boolean

Quick check - just returns status

Returns:

  • (Boolean)


44
45
46
47
# File 'lib/brainzlab/utilities/health_check.rb', line 44

def healthy?
  result = run
  result[:status] == 'healthy'
end

.register(name, &block) ⇒ Object

Register a custom health check



155
156
157
# File 'lib/brainzlab/utilities/health_check.rb', line 155

def register(name, &block)
  custom_checks[name.to_sym] = block
end

.run(checks: nil) ⇒ Object

Run all configured health checks



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/brainzlab/utilities/health_check.rb', line 22

def run(checks: nil)
  checks_to_run = checks || CHECKS
  results = {}
  overall_healthy = true

  checks_to_run.each do |check|
    result = send("check_#{check}")
    results[check] = result
    overall_healthy = false if result[:status] != 'ok'
  rescue StandardError => e
    results[check] = { status: 'error', message: e.message }
    overall_healthy = false
  end

  {
    status: overall_healthy ? 'healthy' : 'unhealthy',
    timestamp: Time.now.utc.iso8601,
    checks: results
  }
end