Skip to content

Commit

Permalink
move cli to module
Browse files Browse the repository at this point in the history
  • Loading branch information
kostya committed Sep 22, 2013
1 parent 67293c7 commit 79494ea
Show file tree
Hide file tree
Showing 15 changed files with 638 additions and 543 deletions.
300 changes: 0 additions & 300 deletions bin/eye
Original file line number Diff line number Diff line change
Expand Up @@ -2,304 +2,4 @@
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib]))
require 'eye'

gem 'thor'
require 'thor'

class Eye::Cli < Thor
desc "info [MASK]", "processes info"
def info(mask = nil)
print cmd(:info, *Array(mask))
end

desc "status", "processes info (deprecated)"
def status
say ":status is deprecated, use :info instead", :yellow
info
end

desc "xinfo", "eye-deamon info (-c show current config)"
method_option :config, :type => :boolean, :aliases => "-c"
method_option :processes, :type => :boolean, :aliases => "-p"
def xinfo
print cmd(:xinfo, :config => options[:config], :processes => options[:processes])
end

desc "oinfo", "onelined info"
def oinfo
print cmd(:oinfo)
end

desc "load [CONF, ...]", "load config (start eye-daemon if not) (-f foregraund start)"
method_option :foregraund, :type => :boolean, :aliases => "-f"
def load(*configs)
configs.map!{ |c| File.expand_path(c) } if !configs.empty?

if options[:foregraund]
# in foregraund we stop another server, and run just 1 current config version
error!("foregraund expected only one config") if configs.size != 1
server_start_foregraund(configs.first)

elsif server_started?
say_load_result cmd(:load, *configs)

else
server_start(configs)

end
end

desc "quit", "eye-daemon quit"
def quit
res = _cmd(:quit)

# if eye server got crazy, stop by force
ensure_stop_previous_server if res != :corrupred_data

# remove pid_file
File.delete(Eye::Settings.pid_path) if File.exists?(Eye::Settings.pid_path)

say "quit...", :yellow
end

[:start, :stop, :restart, :unmonitor, :monitor, :delete, :match].each do |_cmd|
desc "#{_cmd} MASK[,...]", "#{_cmd} app,group or process"
define_method(_cmd) do |*masks|
send_command(_cmd, *masks)
end
end

desc "signal SIG MASK[,...]", "send signal to app,group or process"
def signal(sig, *masks)
send_command(:signal, sig, *masks)
end

desc "break MASK[,...]", "break chain executing"
def break(*masks)
send_command(:break_chain, *masks)
end

desc "history [MASK,...]", "processes history"
def history(*masks)
print cmd(:history, *masks)
end

desc "trace [MASK]", "tracing log(tail + grep) for app,group or process"
def trace(mask = "")
log_trace(mask)
end

map ["-v", "--version"] => :version
desc "version", "version"
def version
say Eye::ABOUT
end

desc "check CONF", "check config file syntax"
method_option :host, :type => :string, :aliases => "-h"
method_option :verbose, :type => :boolean, :aliases => "-v"
def check(conf)
conf = File.expand_path(conf) if conf && !conf.empty?

Eye::System.host = options[:host] if options[:host]
Eye::Dsl.verbose = options[:verbose]

say_load_result Eye::Controller.new.check(conf), :syntax => true
end

desc "explain CONF", "explain config tree"
method_option :host, :type => :string, :aliases => "-h"
method_option :verbose, :type => :boolean, :aliases => "-v"
def explain(conf)
conf = File.expand_path(conf) if conf && !conf.empty?

Eye::System.host = options[:host] if options[:host]
Eye::Dsl.verbose = options[:verbose]

say_load_result Eye::Controller.new.explain(conf), :print_config => true, :syntax => true
end

desc "watch [MASK]", "interactive processes info"
def watch(*args)
pid = Process.spawn("watch -n 1 --color #{$0} i #{args * ' '}")
Process.waitpid(pid)
rescue Interrupt
end

private

def error!(msg)
say msg, :red
exit 1
end

def print(msg, new_line = true)
say msg if msg && !msg.empty?
say if new_line
end

def client
@client ||= Eye::Client.new(Eye::Settings.socket_path)
end

def _cmd(cmd, *args)
client.command(cmd, *args)
rescue Errno::ECONNREFUSED, Errno::ENOENT
:not_started
end

def cmd(cmd, *args)
res = _cmd(cmd, *args)

if res == :not_started
error! "socket(#{Eye::Settings.socket_path}) not found, did you `eye load`?"
elsif res == :timeouted
error! "eye does not answer, timeouted..."
end

res
end

def server_started?
_cmd(:ping) == :pong
end

def say_load_result(res = {}, opts = {})
error!(res) unless res.is_a?(Hash)
say_filename = (res.size > 1)
say "eye started!", :green if opts[:started]
error = false
res.each do |filename, _res|
say "#{filename}: ", nil, true if say_filename
show_load_message(_res, opts)
error = true if _res[:error]
end

exit(1) if error
end

def show_load_message(res, opts = {})
if res[:error]
say res[:message], :red
res[:backtrace].to_a.each{|line| say line, :red }
else
if opts[:syntax]
say "config ok!", :green if !res[:empty]
else
say "config loaded!", :green if !res[:empty]
end

if opts[:print_config]
require 'pp'
PP.pp res[:config], STDOUT, 150
end
end
end

def send_command(_cmd, *args)
res = cmd(_cmd, *args)
if res == :unknown_command
error! "unknown command :#{_cmd}"
elsif res == :corrupred_data
error! "something crazy wrong, check eye logs!"
elsif res.is_a?(Hash)
if res[:error]
error! "Error: #{res[:error]}"
elsif res = res[:result]
if res == []
error! "command :#{_cmd}, objects not found!"
else
say "command :#{_cmd} sended to [#{res * ", "}]"
end
end
else
error! "unknown result #{res.inspect}"
end
end

def log_trace(tag = '')
log_file = cmd(:logger_dev)
if log_file && File.exists?(log_file)
Process.exec "tail -n 100 -f #{log_file} | grep '#{tag}'"
else
error! "log file not found #{log_file.inspect}"
end
end

def loader_path
filename = File.expand_path(File.join(File.dirname(__FILE__), %w[loader_eye]))
File.exists?(filename) ? filename : nil
end

def ruby_path
require 'rbconfig'
RbConfig::CONFIG['bindir'] + "/ruby"
end

def ensure_loader_path
unless loader_path
error! "start monitoring needs to run under ruby with installed gem 'eye'"
end
end

def server_start_foregraund(conf = nil)
ensure_loader_path
Eye::Settings.ensure_eye_dir

if server_started?
_cmd(:quit) && sleep(1) # stop previous server
end

args = []
args += ['-c', conf] if conf
args += ['-l', 'stdout']

Process.exec(ruby_path, loader_path, *args)
end

def server_start(configs)
ensure_loader_path
Eye::Settings.ensure_eye_dir

ensure_stop_previous_server

args = []
pid = Process.spawn(ruby_path, loader_path, *args, :out => '/dev/null', :err => '/dev/null', :in => '/dev/null',
:chdir => '/', :pgroup => true)
Process.detach(pid)
File.open(Eye::Settings.pid_path, 'w'){|f| f.write(pid) }

unless wait_server
error! "server not runned in 15 seconds, something crazy wrong"
end

configs.unshift(Eye::Settings.eyeconfig) if File.exists?(Eye::Settings.eyeconfig)

if !configs.empty?
say_load_result cmd(:load, *configs), :started => true
else
say "started!", :green
end
end

def ensure_stop_previous_server
Eye::Settings.ensure_eye_dir
pid = File.read(Eye::Settings.pid_path).to_i rescue nil
if pid
Process.kill(9, pid) rescue nil
end
File.delete(Eye::Settings.pid_path) rescue nil
true
end

def wait_server(timeout = 15)
Timeout.timeout(timeout) do
sleep 0.3 while !server_started?
end
true
rescue Timeout::Error
false
end

end

Eye::Cli.start
1 change: 1 addition & 0 deletions lib/eye.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ module Eye

autoload :Controller, 'eye/controller'
autoload :Control, 'eye/control'
autoload :Cli, 'eye/cli'
end
Loading

0 comments on commit 79494ea

Please sign in to comment.