bluepill 0.0.21 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/LICENSE CHANGED
@@ -1,3 +1,22 @@
1
- Copyright (c) 2009 arya garru
2
- license tbd
1
+ Copyright (c) 2009 Arya Asemanfar, Rohith Ravi, Gary Tsang
3
2
 
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -6,7 +6,7 @@ It's hosted on [gemcutter.org][gemcutter].
6
6
 
7
7
  sudo gem install bluepill
8
8
 
9
- In order to take advantage of logging, you also need to setup your syslog to log the local6 facility. Edit the appropriate config file for your syslogger (/etc/syslog.conf for syslog) and add a line for local6:
9
+ In order to take advantage of logging with syslog, you also need to setup your syslog to log the local6 facility. Edit the appropriate config file for your syslogger (/etc/syslog.conf for syslog) and add a line for local6:
10
10
 
11
11
  local6.* /var/log/bluepill.log
12
12
 
@@ -15,7 +15,7 @@ You'll also want to add _/var/log/bluepill.log_ to _/etc/logrotate.d/syslog_ so
15
15
  Lastly, create the _/var/bluepill_ directory for bluepill to store its pid and sock files.
16
16
 
17
17
  ## Usage
18
- ### DSL
18
+ ### Config
19
19
  Bluepill organizes processes into 3 levels: application -> group -> process. Each process has a few attributes that tell bluepill how to start, stop, and restart it, where to look or put the pid file, what process conditions to monitor and the options for each of those.
20
20
 
21
21
  The minimum config file looks something like this:
@@ -105,9 +105,44 @@ If you want to run the process as someone other than root:
105
105
  end
106
106
  end
107
107
 
108
+ You can also set an app-wide uid/gid:
109
+
110
+ Bluepill.application("app_name") do |app|
111
+ app.uid = "deploy"
112
+ app.gid = "deploy"
113
+ app.process("process_name") do |process|
114
+ process.start_command = "/usr/bin/some_start_command"
115
+ process.pid_file = "/tmp/some_pid_file.pid"
116
+ end
117
+ end
118
+
108
119
  To check for flapping:
109
120
 
110
121
  process.checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
122
+
123
+ To set the working directory to _cd_ into when starting the command:
124
+
125
+ Bluepill.application("app_name") do |app|
126
+ app.process("process_name") do |process|
127
+ process.start_command = "/usr/bin/some_start_command"
128
+ process.pid_file = "/tmp/some_pid_file.pid"
129
+ process.working_dir = "/path/to/some_directory"
130
+ end
131
+ end
132
+
133
+ You can also have an app-wide working directory:
134
+
135
+
136
+ Bluepill.application("app_name") do |app|
137
+ app.working_dir = "/path/to/some_directory"
138
+ app.process("process_name") do |process|
139
+ process.start_command = "/usr/bin/some_start_command"
140
+ process.pid_file = "/tmp/some_pid_file.pid"
141
+ end
142
+ end
143
+
144
+ Note: We also set the PWD in the environment to the working dir you specify. This is useful for when the working dir is a symlink. Unicorn in particular will cd into the environment variable in PWD when it re-execs to deal with a change in the symlink.
145
+
111
146
 
112
147
  And lastly, to monitor child processes:
113
148
 
@@ -131,7 +166,7 @@ While you can specify shell tricks like the following in the start_command of a
131
166
  end
132
167
  end
133
168
 
134
- We recommend that you not do that and instead use the DSL to capture output from your daemons. Like so:
169
+ We recommend that you _not_ do that and instead use the config options to capture output from your daemons. Like so:
135
170
 
136
171
  Bluepill.application("app_name") do |app|
137
172
  app.process("process_name") do |process|
@@ -144,6 +179,7 @@ We recommend that you not do that and instead use the DSL to capture output from
144
179
  end
145
180
  end
146
181
 
182
+ The main benefit of using the config options is that Bluepill will be able to monitor the correct process instead of just watching the shell that spawned your actual server.
147
183
 
148
184
  ### CLI
149
185
  To start a bluepill process and load a config:
@@ -165,6 +201,15 @@ To view the log for a process or group:
165
201
  To quit bluepill:
166
202
 
167
203
  sudo bluepill quit
204
+
205
+ ### Logging
206
+ By default, bluepill uses syslog local6 facility as described in the installation section. But if for any reason you don't want to use syslog, you can use a log file. You can do this by setting the :log\_file option in the config:
207
+
208
+ Bluepill.application("app_name", :log_file => "/path/to/bluepill.log") do |app|
209
+ # ...
210
+ end
211
+
212
+ Keep in mind that you still need to set up log rotation (described in the installation section) to keep the log file from growing huge.
168
213
 
169
214
  ## Contribute
170
215
  Code: [http://github.com/arya/bluepill](http://github.com/arya/bluepill)
data/Rakefile CHANGED
@@ -24,21 +24,6 @@ rescue LoadError
24
24
  puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
25
25
  end
26
26
 
27
- require 'spec/rake/spectask'
28
- Spec::Rake::SpecTask.new(:spec) do |spec|
29
- spec.libs << 'lib' << 'spec'
30
- spec.spec_files = FileList['spec/**/*_spec.rb']
31
- end
32
-
33
- Spec::Rake::SpecTask.new(:rcov) do |spec|
34
- spec.libs << 'lib' << 'spec'
35
- spec.pattern = 'spec/**/*_spec.rb'
36
- spec.rcov = true
37
- end
38
-
39
- task :spec => :check_dependencies
40
-
41
- task :default => :spec
42
27
 
43
28
  require 'rake/rdoctask'
44
29
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.21
1
+ 0.0.22
data/bin/bluepill CHANGED
@@ -3,7 +3,14 @@ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
3
  require 'optparse'
4
4
  require 'bluepill'
5
5
 
6
- # defaults
6
+ # Check for root
7
+ unless ::Process.euid == 0
8
+ $stderr.puts "You must run bluepill as root."
9
+ exit(3)
10
+ end
11
+
12
+
13
+ # Default options
7
14
  options = {
8
15
  :log_file => "/var/log/bluepill.log",
9
16
  :base_dir => "/var/bluepill"
@@ -11,14 +18,30 @@ options = {
11
18
 
12
19
  OptionParser.new do |opts|
13
20
  opts.banner = "Usage: bluepill [app] cmd [options]"
14
-
15
- opts.on("--logfile LOGFILE") do |file|
21
+ opts.on('-l', "--logfile LOGFILE", "Path to logfile, defaults to #{options[:log_file]}") do |file|
16
22
  options[:log_file] = file
17
23
  end
18
24
 
19
- opts.on("--base-dir DIR") do |base_dir|
25
+ opts.on('-c', "--base-dir DIR", "Directory to store bluepill socket and pid files, defaults to #{options[:base_dir]}") do |base_dir|
20
26
  options[:base_dir] = base_dir
21
27
  end
28
+
29
+ opts.on_tail('-h','--help', 'Show this message') do
30
+ puts opts
31
+ puts
32
+ puts "Commands:"
33
+ puts " load CONFIG_FILE\t\tLoads new instance of bluepill using the specified config file"
34
+ puts " status\t\t\tLists the status of the proceses for the specified app"
35
+ puts " start TARGET\t\tIssues the start command for the target process or group"
36
+ puts " stop TARGET\t\t\tIssues the stop command for the target process or group"
37
+ puts " restart TARGET\t\tIssues the restart command for the target process or group"
38
+ puts " unmonitor TARGET\t\tStop monitoring target process or group"
39
+ puts " log [TARGET]\t\tShow the log for the specified process or group, defaults to all for app"
40
+ puts " quit\t\t\tStop bluepill"
41
+ puts
42
+ puts "See http://github.com/arya/bluepill for README"
43
+ exit
44
+ end
22
45
  end.parse!
23
46
 
24
47
  APPLICATION_COMMANDS = %w(status start stop restart unmonitor quit log)
@@ -30,15 +53,18 @@ if controller.running_applications.include?(ARGV.first)
30
53
  options[:application] = ARGV.shift
31
54
  elsif APPLICATION_COMMANDS.include?(ARGV.first)
32
55
  if controller.running_applications.length == 1
56
+ # there is only one, let's just use that
33
57
  options[:application] = controller.running_applications.first
34
58
  elsif controller.running_applications.length > 1
35
- $stderr.puts "You must specify an application name. Here's the list of running applications:"
59
+ # There is more than one, tell them the list and exit
60
+ $stderr.puts "You must specify an application name to run that command. Here's the list of running applications:"
36
61
  controller.running_applications.each_with_index do |app, index|
37
62
  $stderr.puts " #{index + 1}. #{app}"
38
63
  end
39
64
  $stderr.puts "Usage: bluepill [app] cmd [options]"
40
65
  exit(1)
41
66
  else
67
+ # There are none running AND they aren't trying to start one
42
68
  $stderr.puts "Error: There are no running bluepill daemons.\nTo start a bluepill daemon, use: bluepill load <config file>"
43
69
  exit(2)
44
70
  end
@@ -48,23 +74,23 @@ options[:command] = ARGV.shift
48
74
 
49
75
  case options[:command]
50
76
  when "load"
51
- file = ARGV.shift
52
- if File.exists?(file)
53
- eval(File.read(file))
77
+ config_file = ARGV.shift
78
+ if File.exists?(config_file)
79
+ eval(File.read(config_file))
54
80
  else
55
81
  $stderr.puts "Can't find file: #{file}"
56
82
  end
57
83
  when "log"
58
- orig_pattern = pattern = ARGV.shift
59
- pattern = controller.send_cmd(options[:application], :grep_pattern, pattern)
84
+ requested_pattern = ARGV.shift
85
+ grep_pattern = controller.send_command_to_application(options[:application], :grep_pattern, requested_pattern)
60
86
 
61
- cmd = "tail -n 100 -f #{options[:log_file]} | grep -E '#{pattern}'"
62
- puts "Tailing log for #{orig_pattern}..."
63
- Kernel.exec(cmd)
87
+ tail = "tail -n 100 -f #{options[:log_file]} | grep -E '#{grep_pattern}'"
88
+ puts "Tailing log for #{requested_pattern}..."
89
+ Kernel.exec(tail)
64
90
 
65
91
  when *APPLICATION_COMMANDS
66
- process_or_group_name = ARGV.shift
67
- puts controller.send_cmd(options[:application], options[:command], process_or_group_name)
92
+ target = ARGV.shift
93
+ puts controller.send_command_to_application(options[:application], options[:command], target)
68
94
 
69
95
  else
70
96
  puts "Unknown command `%s` (or application `%s` has not been loaded yet)" % [options[:command], options[:command]]
data/bluepill.gemspec CHANGED
@@ -1,29 +1,28 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bluepill}
8
- s.version = "0.0.21"
8
+ s.version = "0.0.22"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Arya Asemanfar", "Gary Tsang", "Rohith Ravi"]
12
- s.date = %q{2009-11-16}
12
+ s.date = %q{2009-11-22}
13
13
  s.default_executable = %q{bluepill}
14
14
  s.description = %q{Bluepill keeps your daemons up while taking up as little resources as possible. After all you probably want the resources of your server to be used by whatever daemons you are running rather than the thing that's supposed to make sure they are brought back up, should they die or misbehave.}
15
15
  s.email = %q{entombedvirus@gmail.com}
16
16
  s.executables = ["bluepill"]
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE",
19
- "README.markdown"
19
+ "README.md"
20
20
  ]
21
21
  s.files = [
22
- ".document",
23
- ".gitignore",
24
- "DESIGN.markdown",
22
+ ".gitignore",
23
+ "DESIGN.md",
25
24
  "LICENSE",
26
- "README.markdown",
25
+ "README.md",
27
26
  "Rakefile",
28
27
  "VERSION",
29
28
  "bin/bluepill",
@@ -48,21 +47,13 @@ Gem::Specification.new do |s|
48
47
  "lib/bluepill/trigger.rb",
49
48
  "lib/bluepill/triggers/flapping.rb",
50
49
  "lib/bluepill/util/rotational_array.rb",
51
- "lib/example.rb",
52
- "spec/blue-pill_spec.rb",
53
- "spec/process_spec.rb",
54
- "spec/spec_helper.rb"
50
+ "lib/example.rb"
55
51
  ]
56
52
  s.homepage = %q{http://github.com/arya/bluepill}
57
53
  s.rdoc_options = ["--charset=UTF-8"]
58
54
  s.require_paths = ["lib"]
59
- s.rubygems_version = %q{1.3.5}
55
+ s.rubygems_version = %q{1.3.4}
60
56
  s.summary = %q{A process monitor written in Ruby with stability and minimalism in mind.}
61
- s.test_files = [
62
- "spec/blue-pill_spec.rb",
63
- "spec/process_spec.rb",
64
- "spec/spec_helper.rb"
65
- ]
66
57
 
67
58
  if s.respond_to? :specification_version then
68
59
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -89,4 +80,3 @@ Gem::Specification.new do |s|
89
80
  s.add_dependency(%q<activesupport>, [">= 2.3.4"])
90
81
  end
91
82
  end
92
-
data/lib/bluepill.rb CHANGED
@@ -4,6 +4,7 @@ require 'thread'
4
4
  require 'monitor'
5
5
  require 'syslog'
6
6
  require 'timeout'
7
+ require 'logger'
7
8
 
8
9
  require 'active_support/inflector'
9
10
  require 'active_support/core_ext/hash'
@@ -8,7 +8,7 @@ module Bluepill
8
8
  self.base_dir = options[:base_dir] ||= '/var/bluepill'
9
9
  self.socket_timeout = options[:socket_timeout] ||= 10
10
10
 
11
- self.logger = Bluepill::Logger.new.prefix_with(self.name)
11
+ self.logger = Bluepill::Logger.new(options.slice(:log_file)).prefix_with(self.name)
12
12
 
13
13
  self.groups = Hash.new
14
14
 
@@ -21,8 +21,10 @@ module Bluepill
21
21
  begin
22
22
  start_server
23
23
  rescue StandardError => e
24
- logger.err("Got exception: %s `%s`" % [e.class.name, e.message])
25
- e.backtrace.each {|l| logger.err(l)}
24
+ $stderr.puts "Failed to start bluepill:"
25
+ $stderr.puts "%s `%s`" % [e.class.name, e.message]
26
+ $stderr.puts e.backtrace
27
+ exit(5)
26
28
  end
27
29
  end
28
30
 
@@ -113,6 +115,7 @@ module Bluepill
113
115
  def quit
114
116
  if @server
115
117
  ::Process.kill("TERM", 0)
118
+ "Terminating bluepill[#{::Process.pid}]"
116
119
  else
117
120
  send_to_server("quit")
118
121
  end
@@ -141,13 +144,14 @@ module Bluepill
141
144
  buffer
142
145
  end
143
146
 
144
- private
147
+ private
145
148
 
146
- def listener
147
- Thread.new(self) do |app|
149
+ def start_listener
150
+ @listener_thread.kill if @listener_thread
151
+ @listener_thread = Thread.new(self) do |app|
148
152
  begin
149
153
  loop do
150
- client = socket.accept
154
+ client = app.socket.accept
151
155
  cmd = client.readline.strip
152
156
  response = app.send(*cmd.split(":"))
153
157
  client.write(response)
@@ -160,8 +164,9 @@ private
160
164
  end
161
165
  end
162
166
 
163
- def worker
164
- Thread.new(self) do |app|
167
+ def start_worker
168
+ @worker_thread.kill if @worker_thread
169
+ @worker_thread = Thread.new(self) do |app|
165
170
  loop do
166
171
  begin
167
172
  job = app.work_queue.pop
@@ -197,6 +202,7 @@ private
197
202
  end
198
203
 
199
204
  Daemonize.daemonize
205
+ self.logger.reopen
200
206
 
201
207
  @server = true
202
208
  $0 = "bluepilld: #{self.name}"
@@ -209,8 +215,8 @@ private
209
215
  self.groups.each {|_, group| group.boot! }
210
216
 
211
217
  setup_signal_traps
212
- listener
213
- worker
218
+ start_listener
219
+ start_worker
214
220
  run
215
221
  end
216
222
 
@@ -228,11 +234,17 @@ private
228
234
  def setup_signal_traps
229
235
  terminator = lambda do
230
236
  puts "Terminating..."
237
+ File.unlink(self.socket.path) if self.socket
238
+ File.unlink(self.pid_file) if File.exists?(self.pid_file)
231
239
  ::Kernel.exit
232
240
  end
233
241
 
234
242
  Signal.trap("TERM", &terminator)
235
243
  Signal.trap("INT", &terminator)
244
+
245
+ Signal.trap("HUP") do
246
+ self.logger.reopen
247
+ end
236
248
  end
237
249
 
238
250
  def grep_pattern(query = nil)
@@ -11,24 +11,24 @@ module Bluepill
11
11
  self.pids_dir = File.join(base_dir, 'pids')
12
12
  self.applications = Hash.new
13
13
  setup_dir_structure
14
- cleanup
14
+ cleanup_bluepill_directory
15
15
  end
16
16
 
17
17
  def running_applications
18
18
  Dir[File.join(sockets_dir, "*.sock")].map{|x| File.basename(x, ".sock")}
19
19
  end
20
20
 
21
- def send_cmd(application, command, *args)
21
+ def send_command_to_application(application, command, *args)
22
22
  applications[application] ||= Application.new(application, {:base_dir => base_dir})
23
23
  applications[application].send(command.to_sym, *args.compact)
24
24
  end
25
25
 
26
26
  private
27
27
 
28
- def cleanup
28
+ def cleanup_bluepill_directory
29
29
  self.running_applications.each do |app|
30
30
  pid = pid_for(app)
31
- if !pid || !alive?(pid)
31
+ if !pid || !System.pid_alive?(pid)
32
32
  pid_file = File.join(self.pids_dir, "#{app}.pid")
33
33
  sock_file = File.join(self.sockets_dir, "#{app}.sock")
34
34
  File.unlink(pid_file) if File.exists?(pid_file)
@@ -42,23 +42,10 @@ module Bluepill
42
42
  File.exists?(pid_file) && File.read(pid_file).to_i
43
43
  end
44
44
 
45
- def alive?(pid)
46
- begin
47
- ::Process.kill(0, pid)
48
- true
49
- rescue Errno::ESRCH
50
- false
51
- end
52
- end
53
-
54
45
  def setup_dir_structure
55
46
  [@sockets_dir, @pids_dir].each do |dir|
56
47
  FileUtils.mkdir_p(dir) unless File.exists?(dir)
57
48
  end
58
-
59
- rescue Errno::EACCES
60
- $stderr.puts "Error: You don't have permissions to #{base_dir}\nYou should run bluepill as root."
61
- exit(3)
62
49
  end
63
50
  end
64
51
  end
data/lib/bluepill/dsl.rb CHANGED
@@ -5,7 +5,8 @@ module Bluepill
5
5
 
6
6
  process_proxy = Class.new do
7
7
  attr_reader :attributes, :watches
8
- def initialize
8
+ def initialize(process_name = nil)
9
+ @name = process_name
9
10
  @attributes = {}
10
11
  @watches = {}
11
12
  end
@@ -24,6 +25,14 @@ module Bluepill
24
25
  @watches[name] = options
25
26
  end
26
27
 
28
+ def validate_child_process(child)
29
+ unless child.attributes.has_key?(:stop_command)
30
+ $stderr.puts "Config Error: Invalid child process monitor for #{@name}"
31
+ $stderr.puts "You must specify a stop command to monitor child processes."
32
+ exit(6)
33
+ end
34
+ end
35
+
27
36
  def monitor_children(&child_process_block)
28
37
  child_proxy = self.class.new
29
38
 
@@ -33,6 +42,7 @@ module Bluepill
33
42
  child_proxy.restart_grace_time = @attributes[:restart_grace_time]
34
43
 
35
44
  child_process_block.call(child_proxy)
45
+ validate_child_process(child_proxy)
36
46
 
37
47
  @attributes[:child_process_template] = child_proxy.to_process(nil)
38
48
  # @attributes[:child_process_template].freeze
@@ -55,16 +65,45 @@ module Bluepill
55
65
  app_proxy = Class.new do
56
66
  @@app = app
57
67
  @@process_proxy = process_proxy
68
+ @@process_names = Hash.new # becuase I don't want to require Set just for validations
69
+ attr_accessor :working_dir, :uid, :gid
70
+
71
+ def validate_process(process, process_name)
72
+ if @@process_names.key?(process_name)
73
+ $stderr.puts "Config Error: You have two entries for the process name '#{process_name}'"
74
+ exit(6)
75
+ else
76
+ @@process_names[process_name] = 0
77
+ end
78
+
79
+ [:start_command, :pid_file].each do |required_attr|
80
+ if !process.attributes.key?(required_attr)
81
+ $stderr.puts "Config Error: You must specify a #{required_attr} for '#{process_name}'"
82
+ exit(6)
83
+ end
84
+ end
85
+ end
58
86
 
59
87
  def process(process_name, &process_block)
60
- process_proxy = @@process_proxy.new
88
+ process_proxy = @@process_proxy.new(process_name)
61
89
  process_block.call(process_proxy)
90
+ set_app_wide_attributes(process_proxy)
91
+
92
+ validate_process(process_proxy, process_name)
62
93
 
63
94
  group = process_proxy.attributes.delete(:group)
64
95
  process = process_proxy.to_process(process_name)
65
96
 
66
97
  @@app.add_process(process, group)
67
98
  end
99
+
100
+ def set_app_wide_attributes(process_proxy)
101
+ [:working_dir, :uid, :gid].each do |attribute|
102
+ unless process_proxy.attributes.key?(attribute)
103
+ process_proxy.attributes[attribute] = self.send(attribute)
104
+ end
105
+ end
106
+ end
68
107
  end
69
108
 
70
109
  yield(app_proxy.new)
@@ -1,9 +1,10 @@
1
- module Bluepill
1
+ module Bluepill
2
2
  class Logger
3
3
  LOG_METHODS = [:emerg, :alert, :crit, :err, :warning, :notice, :info, :debug]
4
4
 
5
5
  def initialize(options = {})
6
- @logger = options[:logger] || Syslog.open(options[:identity] || 'bluepilld', Syslog::LOG_PID, Syslog::LOG_LOCAL6)
6
+ @options = options
7
+ @logger = options[:logger] || self.create_logger
7
8
  @prefix = options[:prefix]
8
9
  @prefixes = {}
9
10
  end
@@ -25,5 +26,32 @@ module Bluepill
25
26
  @prefixes[prefix] ||= self.class.new(:logger => self, :prefix => prefix)
26
27
  end
27
28
 
29
+ def reopen
30
+ if @logger.is_a?(self.class)
31
+ @logger.reopen
32
+ else
33
+ @logger = create_logger
34
+ end
35
+ end
36
+
37
+ protected
38
+ def create_logger
39
+ if @options[:log_file]
40
+ LoggerAdapter.new(@options[:log_file])
41
+ else
42
+ Syslog.close if Syslog.opened? # need to explictly close it before reopening it
43
+ Syslog.open(@options[:identity] || 'bluepilld', Syslog::LOG_PID, Syslog::LOG_LOCAL6)
44
+ end
45
+ end
46
+
47
+ class LoggerAdapter < ::Logger
48
+ LOGGER_EQUIVALENTS =
49
+ {:debug => :debug, :err => :error, :warning => :warn, :info => :info, :emerg => :fatal, :alert => :warn, :crit => :fatal, :notice => :info}
50
+
51
+ LOG_METHODS.each do |method|
52
+ next if method == LOGGER_EQUIVALENTS[method]
53
+ alias_method method, LOGGER_EQUIVALENTS[method]
54
+ end
55
+ end
28
56
  end
29
57
  end
@@ -7,7 +7,6 @@ module Bluepill
7
7
  def initialize(name, base_dir)
8
8
  self.name = name
9
9
  self.base_dir = base_dir
10
- @isserver = false
11
10
  end
12
11
 
13
12
  def client
@@ -15,11 +14,10 @@ module Bluepill
15
14
  end
16
15
 
17
16
  def server
18
- @isserver = true
19
17
  begin
20
18
  self.socket = UNIXServer.open(socket_name)
21
19
  rescue Errno::EADDRINUSE
22
- #if sock file has been created. test to see if there is a server
20
+ # if sock file has been created. test to see if there is a server
23
21
  tmp_socket = UNIXSocket.open(socket_name) rescue nil
24
22
  if tmp_socket.nil?
25
23
  cleanup
@@ -31,7 +29,7 @@ module Bluepill
31
29
  end
32
30
 
33
31
  def cleanup
34
- File.delete(socket_name) if @isserver
32
+ File.delete(socket_name)
35
33
  end
36
34
 
37
35
  def socket_name
data/lib/example.rb CHANGED
@@ -60,20 +60,21 @@ Bluepill.application(:sample_app) do |app|
60
60
  # process.checks :always_true, :every => 10
61
61
  end
62
62
  end
63
-
63
+ app.uid = "arya"
64
64
  1.times do |i|
65
65
  app.process("group_process_#{i}") do |process|
66
- process.uid = "rohith"
67
- process.gid = "wheel"
66
+ process.uid = "root"
67
+ # process.gid = "wheel"
68
68
 
69
69
  process.stderr = "/tmp/err.log"
70
70
  process.stdout = "/tmp/err.log"
71
71
 
72
72
 
73
73
  process.group = "grouped"
74
- process.start_command = %Q{cd /tmp && ruby -e '$stderr.puts("hello stderr");$stdout.puts("hello stdout"); $stdout.flush; $stderr.flush; sleep 10'}
74
+ # process.start_command = %Q{cd /tmp && ruby -e '$stderr.puts("hello stderr");$stdout.puts("hello stdout"); $stdout.flush; $stderr.flush; sleep 10'}
75
+ process.start_command = "sleep 10"
75
76
  process.daemonize = true
76
- process.pid_file = "/tmp/noperm/p_#{process.group}_#{i}.pid"
77
+ process.pid_file = "/tmp/p_#{process.group}_#{i}.pid"
77
78
 
78
79
  # process.checks :always_true, :every => 5
79
80
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bluepill
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arya Asemanfar
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-11-16 00:00:00 -08:00
14
+ date: 2009-11-22 00:00:00 -08:00
15
15
  default_executable: bluepill
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -72,13 +72,12 @@ extensions: []
72
72
 
73
73
  extra_rdoc_files:
74
74
  - LICENSE
75
- - README.markdown
75
+ - README.md
76
76
  files:
77
- - .document
78
77
  - .gitignore
79
- - DESIGN.markdown
78
+ - DESIGN.md
80
79
  - LICENSE
81
- - README.markdown
80
+ - README.md
82
81
  - Rakefile
83
82
  - VERSION
84
83
  - bin/bluepill
@@ -104,9 +103,6 @@ files:
104
103
  - lib/bluepill/triggers/flapping.rb
105
104
  - lib/bluepill/util/rotational_array.rb
106
105
  - lib/example.rb
107
- - spec/blue-pill_spec.rb
108
- - spec/process_spec.rb
109
- - spec/spec_helper.rb
110
106
  has_rdoc: true
111
107
  homepage: http://github.com/arya/bluepill
112
108
  licenses: []
@@ -131,11 +127,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
127
  requirements: []
132
128
 
133
129
  rubyforge_project:
134
- rubygems_version: 1.3.5
130
+ rubygems_version: 1.3.4
135
131
  signing_key:
136
132
  specification_version: 3
137
133
  summary: A process monitor written in Ruby with stability and minimalism in mind.
138
- test_files:
139
- - spec/blue-pill_spec.rb
140
- - spec/process_spec.rb
141
- - spec/spec_helper.rb
134
+ test_files: []
135
+
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
@@ -1,7 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "Bluepill" do
4
- it "fails" do
5
- fail "hey buddy, you should probably rename this file and start specing for real"
6
- end
7
- end
data/spec/process_spec.rb DELETED
@@ -1,33 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Bluepill:Process" do
4
- it "should raise exceptions unless properly initialized" do
5
- lambda {
6
- Bluepill::Process.new
7
- }.should raise_error(ArgumentError)
8
- end
9
-
10
- it "should construct a valid object when properly initialized" do
11
- lambda {
12
- Bluepill::Process.new("test_process") do |p|
13
- # The absolute minimum to construct a valid process
14
- p.start_command = "/dev/null"
15
- p.pid_file = "/var/run/test_process.pid"
16
- end
17
- }.should_not raise_error
18
- end
19
-
20
- end
21
-
22
- describe "A Bluepill::Process object" do
23
- before(:each) do
24
- @process = Bluepill::Process.new("test_process") do |p|
25
- p.start_command = "hai"
26
- p.daemonize = true
27
- end
28
- end
29
-
30
- it "should be in the unmonitored state after construction" do
31
- @process.should be_unmonitored
32
- end
33
- end
data/spec/spec_helper.rb DELETED
@@ -1,13 +0,0 @@
1
- require "rubygems"
2
-
3
- $LOAD_PATH.unshift(File.dirname(__FILE__))
4
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
-
6
- require 'bluepill'
7
- require 'spec'
8
- require 'spec/autorun'
9
- require "ruby-debug"
10
-
11
- Spec::Runner.configure do |config|
12
-
13
- end