lib/runit-man/service_info.rb in runit-man-1.6.4 vs lib/runit-man/service_info.rb in runit-man-1.7.0
- old
+ new
@@ -2,27 +2,29 @@
class ServiceInfo
attr_reader :name
def initialize(a_name)
- @name = a_name
+ @name = a_name
+ @data = ''
+ @files = {}
end
def to_json(*a)
data = {}
- [ :name, :stat, :active?, :logged?, :switchable?, :run?, :pid, :log_pid, :log_file_location ].each do |sym|
+ [ :name, :stat, :active?, :logged?, :switchable?, :run?, :pid, :log_pid, :log_file_location, :finish?, :down?, :started_at, :uptime ].each do |sym|
data[sym] = send(sym)
end
data.to_json(*a)
end
def logged?
File.directory?(log_supervise_folder)
end
def stat
- r = ServiceInfo.data_from_file(File.join(supervise_folder, 'stat'))
+ r = data_from_file(File.join(supervise_folder, 'stat'))
r ? r : 'inactive'
end
def active?
File.directory?(active_service_folder) || File.symlink?(active_service_folder)
@@ -30,14 +32,22 @@
def switchable?
File.symlink?(active_service_folder) || File.directory?(inactive_service_folder)
end
+ def down?
+ status_byte == 0
+ end
+
def run?
- !!(stat =~ /\brun\b/)
+ status_byte == 1
end
+ def finish?
+ status_byte == 2
+ end
+
def up!
send_signal :u
end
def down!
@@ -57,15 +67,29 @@
down!
up!
end
def pid
- ServiceInfo.data_from_file(File.join(supervise_folder, 'pid'))
+ return nil if down?
+ st = raw_status
+ st.unpack('xxxxxxxxxxxxV').first
end
+ def started_at
+ st = raw_status
+ return nil unless st
+ vals = st.unpack('NN')
+ Time.at((vals[0] << 32) + vals[1] - 4611686018427387914)
+ end
+
+ def uptime
+ return nil if down?
+ Time.now - started_at
+ end
+
def log_pid
- ServiceInfo.data_from_file(File.join(log_supervise_folder, 'pid'))
+ data_from_file(File.join(log_supervise_folder, 'pid'))
end
def log_file_location
rel_path = self.class.log_location_cache[log_pid]
return nil if rel_path.nil?
@@ -94,11 +118,11 @@
def urls_to_view
return [] unless File.directory?(urls_to_view_folder)
Dir.entries(urls_to_view_folder).select do |name|
name =~ /\.url$/ && File.file?(File.join(urls_to_view_folder, name))
end.map do |name|
- ServiceInfo.data_from_file(File.join(urls_to_view_folder, name))
+ data_from_file(File.join(urls_to_view_folder, name))
end.select do |url|
!url.nil?
end
end
@@ -133,10 +157,31 @@
def supervise?
File.directory?(supervise_folder)
end
+ def raw_status
+ # status in daemontools supervise format
+ # look at runit's sv.c for details
+ if @data == ''
+ data = data_from_file(File.join(supervise_folder, 'status'))
+ @data = !data.nil? && data.length == 20 ? data : nil
+ end
+ @data
+ end
+
+ def status_byte
+ st = raw_status
+ return 0 unless st
+ st.unpack('xxxxxxxxxxxxxxxxxxxC').first
+ end
+
+ def data_from_file(file_name)
+ return @files[file_name] if @files.include?(file_name)
+ @files[file_name] = self.class.real_data_from_file(file_name)
+ end
+
class << self
def all
all_service_names.sort.map do |name|
ServiceInfo.new(name)
end
@@ -151,10 +196,10 @@
@log_location_cache = LogLocationCache.new
end
@log_location_cache
end
- def data_from_file(file_name)
+ def real_data_from_file(file_name)
return nil unless File.readable?(file_name)
data = IO.read(file_name)
data.chomp! unless data.nil?
data.empty? ? nil : data
end