Module: DeadBro::Collectors::ProcessInfo
- Defined in:
- lib/dead_bro/collectors/process_info.rb
Overview
ProcessInfo collector exposes Ruby / Rails / process level metrics such as RSS, thread count, file descriptor count, GC stats and uptime.
All methods are best-effort and will return nil on failure rather than raising exceptions.
Class Method Summary collapse
- .collect ⇒ Object
- .fd_count ⇒ Object
- .gc_stats ⇒ Object
- .linux? ⇒ Boolean
- .macos? ⇒ Boolean
- .parse_proc_status_for_rss(path) ⇒ Object
- .process_start_time ⇒ Object
- .rails_boot_time ⇒ Object
- .rss_bytes ⇒ Object
- .rss_from_ps ⇒ Object
- .safe_hostname ⇒ Object
- .safe_rails_version ⇒ Object
- .thread_count ⇒ Object
- .uptime_seconds(now = Time.now.utc) ⇒ Object
Class Method Details
.collect ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/dead_bro/collectors/process_info.rb', line 17 def collect now = Time.now.utc { pid: Process.pid, hostname: safe_hostname, boot_time: rails_boot_time, uptime_s: uptime_seconds(now), ruby_version: RUBY_VERSION, rails_version: safe_rails_version, app_env: DeadBro.env, rss_bytes: rss_bytes, thread_count: thread_count, fd_count: fd_count, gc: gc_stats } rescue => e { error_class: e.class.name, error_message: e..to_s[0, 500] } end |
.fd_count ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/dead_bro/collectors/process_info.rb', line 149 def fd_count if linux? && File.directory?("/proc/self/fd") Dir.entries("/proc/self/fd").size - 2 # exclude . and .. elsif macos? && File.directory?("/dev/fd") Dir.entries("/dev/fd").size - 2 else # Best-effort: count file descriptors under /proc when available nil end rescue nil end |
.gc_stats ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/dead_bro/collectors/process_info.rb', line 162 def gc_stats return {} unless defined?(GC) && GC.respond_to?(:stat) stats = GC.stat { heap_live_slots: stats[:heap_live_slots], heap_free_slots: stats[:heap_free_slots], total_allocated_objects: stats[:total_allocated_objects], major_gc_count: stats[:major_gc_count], minor_gc_count: stats[:minor_gc_count] } rescue {} end |
.linux? ⇒ Boolean
40 41 42 43 44 45 |
# File 'lib/dead_bro/collectors/process_info.rb', line 40 def linux? host_os = RbConfig::CONFIG["host_os"].to_s.downcase host_os.include?("linux") rescue false end |
.macos? ⇒ Boolean
47 48 49 50 51 52 |
# File 'lib/dead_bro/collectors/process_info.rb', line 47 def macos? host_os = RbConfig::CONFIG["host_os"].to_s.downcase host_os.include?("darwin") rescue false end |
.parse_proc_status_for_rss(path) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/dead_bro/collectors/process_info.rb', line 103 def parse_proc_status_for_rss(path) File.foreach(path) do |line| next unless line.start_with?("VmRSS:") parts = line.split value_kb = begin Integer(parts[1]) rescue nil end return value_kb * 1024 if value_kb end nil rescue nil end |
.process_start_time ⇒ Object
73 74 75 |
# File 'lib/dead_bro/collectors/process_info.rb', line 73 def process_start_time @process_start_time ||= Time.now.utc end |
.rails_boot_time ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/dead_bro/collectors/process_info.rb', line 60 def rails_boot_time return nil unless defined?(Rails) if Rails.respond_to?(:application) && Rails.application.respond_to?(:config) # Rails does not expose boot time directly; approximate with process start process_start_time else process_start_time end rescue nil end |
.rss_bytes ⇒ Object
93 94 95 96 97 98 99 100 101 |
# File 'lib/dead_bro/collectors/process_info.rb', line 93 def rss_bytes if linux? && File.readable?("/proc/self/status") parse_proc_status_for_rss("/proc/self/status") else rss_from_ps end rescue nil end |
.rss_from_ps ⇒ Object
120 121 122 123 124 125 126 127 |
# File 'lib/dead_bro/collectors/process_info.rb', line 120 def rss_from_ps rss_kb = `ps -o rss= -p #{Process.pid}`.to_i return nil if rss_kb <= 0 rss_kb * 1024 rescue nil end |
.safe_hostname ⇒ Object
54 55 56 57 58 |
# File 'lib/dead_bro/collectors/process_info.rb', line 54 def safe_hostname Socket.gethostname rescue "unknown" end |
.safe_rails_version ⇒ Object
83 84 85 86 87 88 89 90 91 |
# File 'lib/dead_bro/collectors/process_info.rb', line 83 def safe_rails_version if defined?(Rails) && Rails.respond_to?(:version) Rails.version elsif defined?(Rails::VERSION) && Rails::VERSION::STRING Rails::VERSION::STRING end rescue nil end |
.thread_count ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/dead_bro/collectors/process_info.rb', line 129 def thread_count if linux? && File.readable?("/proc/self/status") File.foreach("/proc/self/status") do |line| next unless line.start_with?("Threads:") parts = line.split begin return Integer(parts[1]) rescue nil end end nil else Thread.list.size end rescue nil end |
.uptime_seconds(now = Time.now.utc) ⇒ Object
77 78 79 80 81 |
# File 'lib/dead_bro/collectors/process_info.rb', line 77 def uptime_seconds(now = Time.now.utc) (now.to_f - process_start_time.to_f).round(2) rescue nil end |