Class: Dbwatcher::Storage::SystemInfoStorage

Inherits:
BaseStorage
  • Object
show all
Includes:
Logging
Defined in:
lib/dbwatcher/storage/system_info_storage.rb

Overview

System information storage class

Handles storage, caching, and retrieval of system information data. Provides intelligent caching with configurable TTL and refresh capabilities.

This class is necessarily complex due to the comprehensive system information storage and retrieval functionality it provides. rubocop:disable Metrics/ClassLength

Examples:

storage = SystemInfoStorage.new
info = storage.cached_info
storage.refresh_info

Constant Summary

Constants inherited from BaseStorage

BaseStorage::DEFAULT_PERMISSIONS, BaseStorage::JSON_FILE_EXTENSION

Instance Attribute Summary

Attributes inherited from BaseStorage

#file_manager, #storage_path

Instance Method Summary collapse

Methods included from Logging

#debug_enabled?, #log_debug, #log_error, #log_info, #log_warn

Methods included from Concerns::Timestampable

#age, included, #initialize_timestamps, #recently_created?, #recently_updated?, #touch_updated_at

Methods included from Concerns::ErrorHandler

#safe_operation, #with_error_handling

Constructor Details

#initializeSystemInfoStorage

Initialize system info storage



24
25
26
27
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 24

def initialize
  super
  @info_file = File.join(storage_path, "system_info.json")
end

Instance Method Details

#cached_info(max_age: nil) ⇒ Hash

Get cached system information with TTL support

Parameters:

  • max_age (Integer) (defaults to: nil)

    maximum age in seconds (default: from config)

Returns:

  • (Hash)

    cached or refreshed system information



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 76

def cached_info(max_age: nil)
  max_age ||= Dbwatcher.configuration.system_info_cache_duration

  info = load_info

  # If no cached info exists, collect new data
  return refresh_info if info.empty?

  # Check if cached info is expired
  if info_expired?(info, max_age)
    log_info "System information cache expired, refreshing"
    return refresh_info
  end

  log_info "Using cached system information"
  info
rescue StandardError => e
  log_error "Failed to get cached system information: #{e.message}"
  { error: e.message }
end

#clear_cacheBoolean

Clear cached system information

Returns:

  • (Boolean)

    true if successful



124
125
126
127
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 124

def clear_cache
  log_info "Clearing system information cache"
  safe_delete_file(@info_file)
end

#info_ageInteger?

Get system information age in seconds

Returns:

  • (Integer, nil)

    age in seconds or nil if not available



110
111
112
113
114
115
116
117
118
119
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 110

def info_age
  info = load_info
  return nil if info.empty? || !info[:collected_at]

  collected_at = info[:collected_at]
  current_time - Time.parse(collected_at)
rescue StandardError => e
  log_error "Failed to get info age: #{e.message}"
  nil
end

#info_available?Boolean

Check if system information is available

Returns:

  • (Boolean)

    true if system information exists



100
101
102
103
104
105
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 100

def info_available?
  !load_info.empty?
rescue StandardError => e
  log_error "Failed to check info availability: #{e.message}"
  false
end

#load_infoHash

Load system information from storage

Returns:

  • (Hash)

    system information data or empty hash



42
43
44
45
46
47
48
49
50
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 42

def load_info
  # Override the base class default to return {} instead of []
  safe_operation("read JSON from #{@info_file}", {}) do
    result = file_manager.read_json(@info_file)
    result = {} if result.is_a?(Array) && result.empty?
    # Convert string keys back to symbols for consistent access in the app
    convert_keys_to_symbols(result)
  end
end

#refresh_infoHash

Refresh system information by collecting new data

Returns:

  • (Hash)

    refreshed system information



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 55

def refresh_info
  log_info "Refreshing system information"

  info = Services::SystemInfo::SystemInfoCollector.call
  save_info(info)

  log_info "System information refreshed successfully"
  # Return the info with symbol keys for consistent access
  convert_keys_to_symbols(info)
rescue StandardError => e
  log_error "Failed to refresh system information: #{e.message}"

  # Return cached info if available, otherwise empty hash with error
  cached_info = load_info
  cached_info.empty? ? { error: e.message } : cached_info
end

#save_info(info) ⇒ Boolean

Save system information to storage

Parameters:

  • info (Hash)

    system information data

Returns:

  • (Boolean)

    true if successful



33
34
35
36
37
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 33

def save_info(info)
  # Convert all keys to strings before saving to ensure consistent format
  info_with_string_keys = convert_keys_to_strings(info)
  safe_write_json(@info_file, info_with_string_keys)
end

#summaryHash

Get system information summary for dashboard

rubocop:disable Metrics/MethodLength

Returns:

  • (Hash)

    summary information



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/dbwatcher/storage/system_info_storage.rb', line 133

def summary
  info = cached_info
  return {} if info.empty? || info[:error]

  {
    hostname: dig_with_indifferent_access(info, :machine, :hostname),
    os: dig_with_indifferent_access(info, :machine, :os, :name),
    ruby_version: dig_with_indifferent_access(info, :runtime, :ruby_version),
    rails_version: dig_with_indifferent_access(info, :runtime, :rails_version),
    database_adapter: dig_with_indifferent_access(info, :database, :adapter, :name),
    memory_usage: dig_with_indifferent_access(info, :machine, :memory, :usage_percent),
    cpu_load: dig_with_indifferent_access(info, :machine, :load_average, "1min") ||
      dig_with_indifferent_access(info, :machine, :cpu, :load_average, "1min") ||
      dig_with_indifferent_access(info, :machine, :load, :one_minute),
    active_connections: dig_with_indifferent_access(info, :database, :active_connections) ||
      dig_with_indifferent_access(info, :database, :connection_pool, :connections),
    collected_at: info[:collected_at],
    collection_duration: info[:collection_duration]
  }
rescue StandardError => e
  log_error "Failed to get system info summary: #{e.message}"
  {}
end