eye 0.7 → 0.8.celluloid15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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