eye 0.7 → 0.8.celluloid15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +141 -0
  3. data/.travis.yml +5 -3
  4. data/CHANGES.md +9 -1
  5. data/README.md +5 -2
  6. data/Rakefile +6 -6
  7. data/bin/leye +9 -4
  8. data/bin/loader_eye +14 -15
  9. data/examples/custom_check.eye +24 -0
  10. data/examples/custom_trigger.eye +30 -0
  11. data/examples/delayed_job.eye +3 -3
  12. data/examples/dependency.eye +10 -11
  13. data/examples/leye_example/Eyefile +10 -0
  14. data/examples/notify.eye +3 -4
  15. data/examples/plugin/main.eye +5 -5
  16. data/examples/plugin/plugin.rb +10 -2
  17. data/examples/process_thin.rb +8 -8
  18. data/examples/processes/em.rb +18 -12
  19. data/examples/processes/forking.rb +5 -5
  20. data/examples/processes/sample.rb +46 -44
  21. data/examples/puma.eye +9 -8
  22. data/examples/rbenv.eye +5 -5
  23. data/examples/sidekiq.eye +3 -3
  24. data/examples/stress_test.eye +4 -4
  25. data/examples/syslog.eye +1 -1
  26. data/examples/test.eye +1 -2
  27. data/examples/thin-farm.eye +7 -8
  28. data/examples/triggers.eye +13 -15
  29. data/examples/unicorn.eye +12 -13
  30. data/eye.gemspec +16 -14
  31. data/lib/eye.rb +2 -3
  32. data/lib/eye/application.rb +5 -6
  33. data/lib/eye/checker.rb +44 -25
  34. data/lib/eye/checker/children_count.rb +1 -1
  35. data/lib/eye/checker/file_ctime.rb +1 -1
  36. data/lib/eye/checker/http.rb +13 -15
  37. data/lib/eye/checker/nop.rb +1 -0
  38. data/lib/eye/checker/socket.rb +60 -63
  39. data/lib/eye/checker/ssl_socket.rb +5 -5
  40. data/lib/eye/child_process.rb +6 -4
  41. data/lib/eye/cli.rb +74 -46
  42. data/lib/eye/cli/commands.rb +4 -5
  43. data/lib/eye/cli/render.rb +61 -41
  44. data/lib/eye/cli/server.rb +19 -16
  45. data/lib/eye/client.rb +1 -0
  46. data/lib/eye/config.rb +36 -33
  47. data/lib/eye/controller.rb +2 -3
  48. data/lib/eye/controller/commands.rb +1 -1
  49. data/lib/eye/controller/helpers.rb +2 -2
  50. data/lib/eye/controller/load.rb +19 -17
  51. data/lib/eye/controller/options.rb +1 -5
  52. data/lib/eye/controller/send_command.rb +21 -23
  53. data/lib/eye/controller/status.rb +17 -14
  54. data/lib/eye/dsl.rb +6 -1
  55. data/lib/eye/dsl/application_opts.rb +4 -3
  56. data/lib/eye/dsl/chain.rb +2 -2
  57. data/lib/eye/dsl/child_process_opts.rb +3 -3
  58. data/lib/eye/dsl/config_opts.rb +7 -7
  59. data/lib/eye/dsl/group_opts.rb +3 -3
  60. data/lib/eye/dsl/helpers.rb +1 -1
  61. data/lib/eye/dsl/main.rb +4 -3
  62. data/lib/eye/dsl/opts.rb +31 -28
  63. data/lib/eye/dsl/process_opts.rb +13 -7
  64. data/lib/eye/dsl/pure_opts.rb +13 -9
  65. data/lib/eye/dsl/validation.rb +48 -35
  66. data/lib/eye/group.rb +23 -8
  67. data/lib/eye/group/chain.rb +6 -6
  68. data/lib/eye/loader.rb +3 -3
  69. data/lib/eye/local.rb +9 -4
  70. data/lib/eye/logger.rb +11 -4
  71. data/lib/eye/notify.rb +10 -6
  72. data/lib/eye/notify/jabber.rb +1 -1
  73. data/lib/eye/notify/mail.rb +2 -2
  74. data/lib/eye/notify/slack.rb +4 -3
  75. data/lib/eye/process.rb +2 -0
  76. data/lib/eye/process/children.rb +4 -4
  77. data/lib/eye/process/commands.rb +38 -39
  78. data/lib/eye/process/config.rb +22 -16
  79. data/lib/eye/process/controller.rb +5 -19
  80. data/lib/eye/process/data.rb +11 -9
  81. data/lib/eye/process/monitor.rb +86 -76
  82. data/lib/eye/process/notify.rb +10 -10
  83. data/lib/eye/process/scheduler.rb +36 -31
  84. data/lib/eye/process/states.rb +7 -5
  85. data/lib/eye/process/states_history.rb +9 -3
  86. data/lib/eye/process/system.rb +35 -20
  87. data/lib/eye/process/trigger.rb +1 -5
  88. data/lib/eye/process/watchers.rb +12 -9
  89. data/lib/eye/reason.rb +4 -1
  90. data/lib/eye/server.rb +3 -2
  91. data/lib/eye/system.rb +22 -15
  92. data/lib/eye/system_resources.rb +17 -8
  93. data/lib/eye/trigger.rb +18 -16
  94. data/lib/eye/trigger/check_dependency.rb +7 -4
  95. data/lib/eye/trigger/flapping.rb +24 -7
  96. data/lib/eye/trigger/starting_guard.rb +7 -6
  97. data/lib/eye/trigger/stop_children.rb +2 -2
  98. data/lib/eye/trigger/transition.rb +1 -1
  99. data/lib/eye/trigger/wait_dependency.rb +3 -2
  100. data/lib/eye/utils.rb +4 -3
  101. data/lib/eye/utils/alive_array.rb +9 -4
  102. data/lib/eye/utils/celluloid_chain.rb +12 -10
  103. data/lib/eye/utils/mini_active_support.rb +16 -16
  104. data/lib/eye/utils/pmap.rb +2 -0
  105. data/lib/eye/utils/tail.rb +2 -2
  106. metadata +39 -8
  107. data/lib/eye/utils/leak_19.rb +0 -10
@@ -32,7 +32,7 @@ private
32
32
 
33
33
  def ordered_by_date_children_pids
34
34
  children = process.children.values
35
- children.sort_by { |ch| Eye::SystemResources.start_time(ch.pid).to_i }.map &:pid
35
+ children.sort_by { |ch| Eye::SystemResources.start_time(ch.pid).to_i }.map(&:pid)
36
36
  end
37
37
 
38
38
  end
@@ -15,7 +15,7 @@ class Eye::Checker::FileCTime < Eye::Checker
15
15
  end
16
16
 
17
17
  def human_value(value)
18
- if value == nil
18
+ if value.nil?
19
19
  'Err'
20
20
  else
21
21
  value.strftime('%H:%M')
@@ -21,46 +21,43 @@ class Eye::Checker::Http < Eye::Checker::Defer
21
21
  @uri = URI.parse(url)
22
22
  @proxy_uri = URI.parse(proxy_url) if proxy_url
23
23
  @kind = case kind
24
- when Fixnum then Net::HTTPResponse::CODE_TO_OBJ[kind.to_s]
25
- when String, Symbol then Net.const_get("HTTP#{kind.to_s.camelize}") rescue Net::HTTPSuccess
26
- else Net::HTTPSuccess
27
- end
24
+ when Fixnum then Net::HTTPResponse::CODE_TO_OBJ[kind.to_s]
25
+ when String, Symbol then Net.const_get("HTTP#{kind.to_s.camelize}") rescue Net::HTTPSuccess
26
+ else Net::HTTPSuccess
27
+ end
28
28
  @open_timeout = (open_timeout || 3).to_f
29
29
  @read_timeout = (read_timeout || timeout || 15).to_f
30
30
  end
31
31
 
32
32
  def get_value
33
- res = session.start{ |http| http.get(@uri.request_uri) }
34
- {:result => res}
33
+ res = session.start { |http| http.get(@uri.request_uri) }
34
+ { result: res }
35
35
 
36
36
  rescue Timeout::Error => ex
37
37
  debug { ex.inspect }
38
38
 
39
39
  if defined?(Net::OpenTimeout) # for ruby 2.0
40
40
  mes = ex.is_a?(Net::OpenTimeout) ? "OpenTimeout<#{@open_timeout}>" : "ReadTimeout<#{@read_timeout}>"
41
- {:exception => mes}
41
+ { exception: mes }
42
42
  else
43
- {:exception => "Timeout<#{@open_timeout},#{@read_timeout}>"}
43
+ { exception: "Timeout<#{@open_timeout},#{@read_timeout}>" }
44
44
  end
45
45
 
46
46
  rescue => ex
47
- {:exception => "Error<#{ex.message}>"}
47
+ { exception: "Error<#{ex.message}>" }
48
48
  end
49
49
 
50
50
  def good?(value)
51
51
  return false unless value[:result]
52
-
53
- unless value[:result].kind_of?(@kind)
54
- return false
55
- end
52
+ return false unless value[:result].is_a?(@kind)
56
53
 
57
54
  if pattern
58
55
  matched = if pattern.is_a?(Regexp)
59
- pattern === value[:result].body
56
+ !!value[:result].body.match(pattern)
60
57
  else
61
58
  value[:result].body.include?(pattern.to_s)
62
59
  end
63
- value[:notice] = "missing '#{pattern.to_s}'" unless matched
60
+ value[:notice] = "missing '#{pattern}'" unless matched
64
61
  matched
65
62
  else
66
63
  true
@@ -102,4 +99,5 @@ private
102
99
  Net::HTTP.new(@uri.host, @uri.port)
103
100
  end
104
101
  end
102
+
105
103
  end
@@ -3,4 +3,5 @@ class Eye::Checker::Nop < Eye::Checker
3
3
  # check :nop, :every => 10.hours # means restart every 10 hours
4
4
 
5
5
  def get_value; end
6
+
6
7
  end
@@ -27,78 +27,75 @@ class Eye::Checker::Socket < Eye::Checker::Defer
27
27
 
28
28
  if addr =~ %r[\Atcp://(.*?):(.*?)\z]
29
29
  @socket_family = :tcp
30
- @socket_addr = $1
31
- @socket_port = $2.to_i
30
+ @socket_addr = Regexp.last_match(1)
31
+ @socket_port = Regexp.last_match(2).to_i
32
32
  elsif addr =~ %r[\Aunix:(.*)\z]
33
33
  @socket_family = :unix
34
- @socket_path = $1
34
+ @socket_path = Regexp.last_match(1)
35
35
  end
36
36
  end
37
37
 
38
38
  def get_value
39
39
  sock = begin
40
- Timeout::timeout(@open_timeout){ open_socket }
40
+ Timeout.timeout(@open_timeout) { open_socket }
41
41
  rescue Timeout::Error
42
- return { :exception => "OpenTimeout<#{@open_timeout}>" }
42
+ return { exception: "OpenTimeout<#{@open_timeout}>" }
43
43
  end
44
44
 
45
- if send_data
46
- begin
47
- Timeout::timeout(@read_timeout) do
48
- _write_data(sock, send_data)
49
- result = _read_data(sock)
45
+ return { result: :listen } unless send_data
50
46
 
51
- { :result => result }
52
- end
53
- rescue Timeout::Error
54
- if protocol == :raw
55
- return { :result => @buffer }
56
- else
57
- return { :exception => "ReadTimeout<#{@read_timeout}>" }
58
- end
47
+ begin
48
+ Timeout.timeout(@read_timeout) do
49
+ _write_data(sock, send_data)
50
+ result = _read_data(sock)
51
+
52
+ { result: result }
53
+ end
54
+ rescue Timeout::Error
55
+ if protocol == :raw
56
+ return { result: @buffer }
57
+ else
58
+ return { exception: "ReadTimeout<#{@read_timeout}>" }
59
59
  end
60
- else
61
- { :result => :listen }
62
60
  end
63
61
 
64
62
  rescue Exception => e
65
- { :exception => "Error<#{e.message}>" }
63
+ { exception: "Error<#{e.message}>" }
66
64
 
67
65
  ensure
68
66
  sock.close if sock
69
67
  end
70
68
 
71
69
  def good?(value)
72
- return false if !value[:result]
73
-
74
- if expect_data
75
- if expect_data.is_a?(Proc)
76
- match = begin
77
- !!expect_data[value[:result]]
78
- rescue Timeout::Error, Exception => ex
79
- mes = "proc match failed with '#{ex.message}'"
80
- error(mes)
81
- value[:notice] = mes
82
- return false
83
- end
84
-
85
- unless match
86
- warn "proc #{expect_data} not matched (#{value[:result].truncate(30)}) answer"
87
- value[:notice] = 'missing proc validation'
88
- end
89
-
90
- return match
70
+ return false unless value[:result]
71
+
72
+ return true unless expect_data
73
+
74
+ if expect_data.is_a?(Proc)
75
+ match = begin
76
+ !!expect_data[value[:result]]
77
+ rescue Object => ex
78
+ mes = "proc match failed with '#{ex.message}'"
79
+ error(mes)
80
+ value[:notice] = mes
81
+ return false
91
82
  end
92
83
 
93
- return true if expect_data.is_a?(Regexp) && expect_data.match(value[:result])
94
- return true if value[:result].to_s == expect_data.to_s
84
+ unless match
85
+ warn "proc #{expect_data} not matched (#{value[:result].truncate(30)}) answer"
86
+ value[:notice] = 'missing proc validation'
87
+ end
95
88
 
96
- warn "#{expect_data} not matched (#{value[:result].truncate(30)}) answer"
97
- value[:notice] = "missing '#{expect_data.to_s}'"
98
- return false
89
+ return match
99
90
  end
100
91
 
101
- return true
92
+ return true if expect_data.is_a?(Regexp) && expect_data.match(value[:result])
93
+ return true if value[:result].to_s == expect_data.to_s
94
+
95
+ warn "#{expect_data} not matched (#{value[:result].truncate(30)}) answer"
96
+ value[:notice] = "missing '#{expect_data}'"
97
+
98
+ false
102
99
  end
103
100
 
104
101
  def human_value(value)
@@ -131,28 +128,28 @@ private
131
128
 
132
129
  def _write_data(socket, data)
133
130
  case protocol
134
- when :em_object
135
- data = Marshal.dump(data)
136
- socket.write([data.bytesize, data].pack('Na*'))
137
- else
138
- socket.write(data.to_s)
131
+ when :em_object
132
+ data = Marshal.dump(data)
133
+ socket.write([data.bytesize, data].pack('Na*'))
134
+ else
135
+ socket.write(data.to_s)
139
136
  end
140
137
  end
141
138
 
142
139
  def _read_data(socket)
143
140
  case protocol
144
- when :em_object
145
- content = ''
146
- msg_size = socket.recv(4).unpack('N')[0] rescue 0
147
- content << socket.recv(msg_size - content.length) while content.length < msg_size
148
- if content.present?
149
- Marshal.load(content) rescue 'corrupted_marshal'
150
- end
151
- when :raw
152
- @buffer = ''
153
- loop { @buffer << socket.recv(1) }
154
- else
155
- socket.readline.chop
141
+ when :em_object
142
+ content = ''
143
+ msg_size = socket.recv(4).unpack('N')[0] rescue 0
144
+ content << socket.recv(msg_size - content.length) while content.length < msg_size
145
+ if content.present?
146
+ Marshal.load(content) rescue 'corrupted_marshal'
147
+ end
148
+ when :raw
149
+ @buffer = ''
150
+ loop { @buffer << socket.recv(1) }
151
+ else
152
+ socket.readline.chop
156
153
  end
157
154
  end
158
155
 
@@ -1,17 +1,16 @@
1
1
  require 'openssl'
2
2
 
3
3
  class Eye::Checker::SslSocket < Eye::Checker::Socket
4
- param :ctx, Hash, nil, {ssl_version: :SSLv23, verify_mode: OpenSSL::SSL::VERIFY_NONE}
5
4
 
6
- # other params inherits from socket check
5
+ # ctx params from http://ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html
7
6
  #
8
7
  # examples:
9
8
  #
10
9
  # check :ssl_socket, :addr => "tcp://127.0.0.1:443", :every => 5.seconds, :times => 1, :timeout => 1.second,
11
10
  # :ctx => {ssl_version: :SSLv23, verify_mode: OpenSSL::SSL::VERIFY_NONE}
12
11
  #
13
- #
14
- # ctx_params from http://ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html
12
+
13
+ param :ctx, Hash, nil, ssl_version: :SSLv23, verify_mode: OpenSSL::SSL::VERIFY_NONE
15
14
 
16
15
  private
17
16
 
@@ -23,6 +22,7 @@ private
23
22
  end
24
23
 
25
24
  def ctx_params
26
- @ctx_params ||= OpenSSL::SSL::SSLContext.new().tap { |c| c.set_params(ctx) }
25
+ @ctx_params ||= OpenSSL::SSL::SSLContext.new.tap { |c| c.set_params(ctx) }
27
26
  end
27
+
28
28
  end
@@ -1,6 +1,7 @@
1
1
  require 'celluloid'
2
2
 
3
3
  class Eye::ChildProcess
4
+
4
5
  include Celluloid
5
6
 
6
7
  # needs: kill_process
@@ -33,7 +34,7 @@ class Eye::ChildProcess
33
34
  @parent = parent
34
35
  @config = prepare_config(config)
35
36
  @name = "child-#{pid}"
36
- @full_name = [logger_prefix, @name] * ':'
37
+ @full_name = [logger_prefix, @name].join(':')
37
38
 
38
39
  @watchers = {}
39
40
 
@@ -88,14 +89,15 @@ class Eye::ChildProcess
88
89
  end
89
90
 
90
91
  def signal(sig)
91
- send_signal(sig) if self.pid
92
+ send_signal(sig) if pid
92
93
  end
93
94
 
94
- def status_data(debug = false)
95
- self_status_data(debug)
95
+ def status_data(opts = {})
96
+ self_status_data(opts)
96
97
  end
97
98
 
98
99
  def prepare_command(command) # override
99
100
  super.gsub('{PARENT_PID}', @parent.pid.to_s)
100
101
  end
102
+
101
103
  end
@@ -4,6 +4,7 @@ gem 'thor'
4
4
  require 'thor'
5
5
 
6
6
  class Eye::Cli < Thor
7
+
7
8
  autoload :Server, 'eye/cli/server'
8
9
  autoload :Commands, 'eye/cli/commands'
9
10
  autoload :Render, 'eye/cli/render'
@@ -12,24 +13,27 @@ class Eye::Cli < Thor
12
13
  include Eye::Cli::Commands
13
14
  include Eye::Cli::Render
14
15
 
15
- desc "info [MASK]", "processes info"
16
- method_option :json, :type => :boolean, :aliases => "-j"
16
+ desc 'info [MASK]', 'processes info'
17
+ method_option :json, type: :boolean, aliases: '-j'
18
+ method_option :procline, type: :boolean, aliases: '-p'
17
19
  def info(mask = nil)
18
- res = cmd(:info_data, *Array(mask))
20
+ h = {}
21
+ h[:procline] = true if options[:procline]
22
+
23
+ res = cmd(:info_data, *Array(mask), h)
19
24
  if mask && res[:subtree] && res[:subtree].empty?
20
- error!("command :info, objects not found!")
25
+ error!('command :info, objects not found!')
21
26
  end
22
27
 
23
28
  if options[:json]
24
- require 'json'
25
- say JSON.dump(res)
29
+ say_json(res)
26
30
  else
27
31
  say render_info(res)
28
32
  say
29
33
  end
30
34
  end
31
35
 
32
- desc "status NAME", "return exit status for process name 0-up, 3-unmonitored"
36
+ desc 'status NAME', 'return exit status for process name 0-up, 3-unmonitored'
33
37
  def status(name)
34
38
  res = cmd(:info_data, *Array(name))
35
39
  es, msg = render_status(res)
@@ -37,43 +41,58 @@ class Eye::Cli < Thor
37
41
  exit(es)
38
42
  end
39
43
 
40
- desc "xinfo", "eye-deamon info (-c show current config)"
41
- method_option :config, :type => :boolean, :aliases => "-c"
44
+ desc 'xinfo', 'eye-deamon info (-c show current config)'
45
+ method_option :config, type: :boolean, aliases: '-c'
46
+ method_option :json, type: :boolean, aliases: '-j'
42
47
  def xinfo
43
- res = cmd(:debug_data, :config => options[:config])
44
- say render_debug_info(res)
45
- say
48
+ res = cmd(:debug_data, config: options[:config])
49
+ if options[:json]
50
+ say_json(res)
51
+ else
52
+ say render_debug_info(res)
53
+ say
54
+ end
46
55
  end
47
56
 
48
- desc "oinfo", "onelined info"
57
+ desc 'oinfo', 'onelined info'
58
+ method_option :json, type: :boolean, aliases: '-j'
49
59
  def oinfo(mask = nil)
50
60
  res = cmd(:short_data, *Array(mask))
51
- say render_info(res)
52
- say
61
+ if options[:json]
62
+ say_json(res)
63
+ else
64
+ say render_info(res)
65
+ say
66
+ end
53
67
  end
54
68
 
55
- desc "history [MASK,...]", "processes history"
69
+ desc 'history [MASK,...]', 'processes history'
70
+ method_option :json, type: :boolean, aliases: '-j'
56
71
  def history(*masks)
57
72
  res = cmd(:history_data, *masks)
58
73
  if !masks.empty? && res && res.empty?
59
- error!("command :history, objects not found!")
74
+ error!('command :history, objects not found!')
75
+ end
76
+ if options[:json]
77
+ say_json(res)
78
+ else
79
+ say render_history(res)
80
+ say
60
81
  end
61
- say render_history(res)
62
- say
63
82
  end
64
83
 
65
- desc "load [CONF, ...]", "load config (run eye-daemon if not) (-f foreground load)"
66
- method_option :foreground, :type => :boolean, :aliases => "-f"
84
+ desc 'load [CONF, ...]', 'load config (run eye-daemon if not) (-f foreground load)'
85
+ method_option :foreground, type: :boolean, aliases: '-f'
67
86
  def load(*configs)
68
- configs.map!{ |c| File.expand_path(c) } if !configs.empty?
87
+ configs.map! { |c| File.expand_path(c) }
69
88
 
70
89
  if options[:foreground]
71
90
  # in foreground we stop another server, and run just 1 current config version
72
- error!("foreground expected only one config") if configs.size > 1
91
+ error!('foreground expected only one config') if configs.size > 1
73
92
  server_start_foreground(configs.first)
74
93
 
75
94
  elsif server_started?
76
- configs << Eye::Local.eyefile if Eye::Local.local_runner
95
+ configs << Eye::Local.eyefile if Eye::Local.local_runner && configs.empty? && Eye::Local.eyefile
77
96
  say_load_result cmd(:load, *configs)
78
97
 
79
98
  else
@@ -82,9 +101,9 @@ class Eye::Cli < Thor
82
101
  end
83
102
  end
84
103
 
85
- desc "quit", "eye-daemon quit"
86
- method_option :stop_all, :type => :boolean, :aliases => "-s"
87
- method_option :timeout, :type => :string, :aliases => "-t", :default => "600"
104
+ desc 'quit', 'eye-daemon quit'
105
+ method_option :stop_all, type: :boolean, aliases: '-s'
106
+ method_option :timeout, type: :string, aliases: '-t', default: '600'
88
107
  def quit
89
108
  if options[:stop_all]
90
109
  Eye::Local.client_timeout = options[:timeout].to_i
@@ -100,7 +119,7 @@ class Eye::Cli < Thor
100
119
  # remove pid_file
101
120
  File.delete(Eye::Local.pid_path) if File.exist?(Eye::Local.pid_path)
102
121
 
103
- say "Quit ಠ╭╮ಠ", :yellow
122
+ say "Eye quit ಠ╭╮ಠ (#{Eye::Local.home})", :yellow
104
123
  end
105
124
 
106
125
  [:start, :stop, :restart, :unmonitor, :monitor, :delete, :match].each do |command|
@@ -110,60 +129,61 @@ class Eye::Cli < Thor
110
129
  end
111
130
  end
112
131
 
113
- desc "force_restart MASK[,...]", "restart by stop;start (not by restart_command)"
132
+ desc 'force_restart MASK[,...]', 'restart by stop;start (not by restart_command)'
114
133
  def force_restart(*masks)
115
134
  send_command(:stop, *masks)
116
135
  send_command(:start, *masks)
117
136
  end
118
137
 
119
- desc "signal SIG MASK[,...]", "send signal to app,group or process"
138
+ desc 'signal SIG MASK[,...]', 'send signal to app,group or process'
120
139
  def signal(sig, *masks)
121
140
  send_command(:signal, sig, *masks)
122
141
  end
123
142
 
124
- desc "break MASK[,...]", "break chain executing"
143
+ desc 'break MASK[,...]', 'break chain executing'
125
144
  def break(*masks)
126
145
  send_command(:break_chain, *masks)
127
146
  end
128
147
 
129
- desc "trace [MASK]", "tracing log(tail + grep) for app,group or process"
130
- def trace(mask = "")
148
+ desc 'trace [MASK]', 'tracing log(tail + grep) for app,group or process'
149
+ def trace(mask = '')
131
150
  log_trace(mask)
132
151
  end
133
152
 
134
- map ["-v", "--version"] => :version
135
- desc "version", "version"
153
+ map ['-v', '--version'] => :version
154
+ desc 'version', 'version'
136
155
  def version
137
156
  say Eye::ABOUT
138
157
  end
139
158
 
140
- desc "check CONF", "check config file syntax"
141
- method_option :host, :type => :string, :aliases => "-h"
142
- method_option :verbose, :type => :boolean, :aliases => "-v"
159
+ desc 'check CONF', 'check config file syntax'
160
+ method_option :host, type: :string, aliases: '-h'
161
+ method_option :verbose, type: :boolean, aliases: '-v'
143
162
  def check(conf)
144
163
  conf = File.expand_path(conf) if conf && !conf.empty?
145
164
 
146
165
  Eye::Local.host = options[:host] if options[:host]
147
166
  Eye::Dsl.verbose = options[:verbose]
148
167
 
149
- say_load_result Eye::Controller.new.check(conf), :syntax => true
168
+ say_load_result Eye::Controller.new.check(conf), syntax: true
150
169
  end
151
170
 
152
- desc "explain CONF", "explain config tree"
153
- method_option :host, :type => :string, :aliases => "-h"
154
- method_option :verbose, :type => :boolean, :aliases => "-v"
171
+ desc 'explain CONF', 'explain config tree'
172
+ method_option :host, type: :string, aliases: '-h'
173
+ method_option :verbose, type: :boolean, aliases: '-v'
155
174
  def explain(conf)
156
175
  conf = File.expand_path(conf) if conf && !conf.empty?
157
176
 
158
177
  Eye::Local.host = options[:host] if options[:host]
159
178
  Eye::Dsl.verbose = options[:verbose]
160
179
 
161
- say_load_result Eye::Controller.new.explain(conf), :print_config => true, :syntax => true
180
+ say_load_result Eye::Controller.new.explain(conf), print_config: true, syntax: true
162
181
  end
163
182
 
164
- desc "watch [MASK]", "interactive processes info"
183
+ desc 'watch [MASK]', 'interactive processes info'
184
+ method_option :procline, type: :boolean, aliases: '-p'
165
185
  def watch(*args)
166
- error!("You should install watch utility") if `which watch`.empty?
186
+ error!('You should install watch utility') if `which watch`.empty?
167
187
 
168
188
  cmd = if `watch --version 2>&1`.chop > '0.2.0'
169
189
  "watch -n 1 --color #{$0} i #{args * ' '}"
@@ -171,12 +191,14 @@ class Eye::Cli < Thor
171
191
  "watch -n 1 #{$0} i #{args * ' '}"
172
192
  end
173
193
 
194
+ cmd += ' -p' if options[:procline]
195
+
174
196
  pid = Process.spawn(cmd)
175
197
  Process.waitpid(pid)
176
198
  rescue Interrupt
177
199
  end
178
200
 
179
- desc "user_command CMD [MASK]", "execute user_command (dsl command)"
201
+ desc 'user_command CMD [MASK]', 'execute user_command (dsl command)'
180
202
  def user_command(cmd, *args)
181
203
  send_command(:user_command, cmd, *args)
182
204
  end
@@ -202,7 +224,13 @@ private
202
224
  end
203
225
  end
204
226
 
227
+ def say_json(obj)
228
+ require 'json'
229
+ say JSON.dump(obj)
230
+ end
231
+
205
232
  def self.exit_on_failure?
206
233
  true
207
234
  end
235
+
208
236
  end