bluepill 0.1.2 → 0.1.4
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +820 -0
- data/CONTRIBUTING.md +31 -0
- data/LICENSE +1 -1
- data/README.md +69 -30
- data/bin/bluepill +2 -2
- data/bluepill.gemspec +17 -6
- data/lib/bluepill/application.rb +311 -43
- data/lib/bluepill/condition_watch.rb +105 -10
- data/lib/bluepill/controller.rb +125 -14
- data/lib/bluepill/dsl/app_proxy.rb +103 -4
- data/lib/bluepill/dsl/process_factory.rb +185 -62
- data/lib/bluepill/dsl/process_proxy.rb +132 -14
- data/lib/bluepill/dsl.rb +27 -5
- data/lib/bluepill/group.rb +142 -9
- data/lib/bluepill/logger.rb +122 -7
- data/lib/bluepill/process.rb +582 -211
- data/lib/bluepill/process_commands.rb +262 -0
- data/lib/bluepill/process_conditions/always_true.rb +18 -4
- data/lib/bluepill/process_conditions/cpu_usage.rb +34 -0
- data/lib/bluepill/process_conditions/file_time.rb +40 -4
- data/lib/bluepill/process_conditions/http.rb +81 -23
- data/lib/bluepill/process_conditions/mem_usage.rb +64 -5
- data/lib/bluepill/process_conditions/process_condition.rb +45 -2
- data/lib/bluepill/process_conditions/running_time.rb +36 -1
- data/lib/bluepill/process_conditions/zombie_process.rb +26 -5
- data/lib/bluepill/process_conditions.rb +15 -1
- data/lib/bluepill/process_journal.rb +256 -104
- data/lib/bluepill/process_statistics.rb +33 -3
- data/lib/bluepill/socket.rb +63 -16
- data/lib/bluepill/system/commands.rb +286 -0
- data/lib/bluepill/system.rb +193 -229
- data/lib/bluepill/trigger.rb +111 -15
- data/lib/bluepill/triggers/flapping.rb +86 -5
- data/lib/bluepill/util/rotational_array.rb +25 -2
- data/lib/bluepill/version.rb +71 -19
- data/lib/bluepill.rb +25 -2
- data/sig/bluepill.rbs +926 -0
- data/sig/manifest.yaml +7 -0
- metadata +16 -35
- data/bin/sample_forking_server +0 -66
- data/lib/bluepill/application/client.rb +0 -6
- data/lib/bluepill/application/server.rb +0 -21
data/CONTRIBUTING.md
CHANGED
|
@@ -4,3 +4,34 @@ Contributing
|
|
|
4
4
|
To ease development and troubleshooting, a simple vagrant environment exists [here](https://github.com/iancoffey/chef_bluepill_devel). A "vagrant up" should do the trick.
|
|
5
5
|
|
|
6
6
|
As more OS options are added, this should also simplify the steps necessary to reproduce odd issues.
|
|
7
|
+
|
|
8
|
+
Type checking
|
|
9
|
+
-------------
|
|
10
|
+
|
|
11
|
+
The RBS signatures in `sig/bluepill.rbs` ship with the gem, and CI checks `lib` against them with [Steep](https://github.com/soutaro/steep) in strict mode. Steep needs Ruby 3.3 or newer. To run the check locally:
|
|
12
|
+
|
|
13
|
+
bundle exec rake steep
|
|
14
|
+
|
|
15
|
+
This installs the signatures of the dependencies into `.gem_rbs_collection`, validates the signatures and runs `steep check`. `sig-vendor` has stubs for the dependencies that publish no signatures. Update `sig/bluepill.rbs` when you change a method in `lib`.
|
|
16
|
+
|
|
17
|
+
Mutation testing
|
|
18
|
+
----------------
|
|
19
|
+
|
|
20
|
+
CI runs [mutant](https://github.com/mbj/mutant) on Ruby 4.0, and every mutant must be killed. Mutant needs Ruby 3.3 or newer. To run it on every subject locally:
|
|
21
|
+
|
|
22
|
+
bundle exec rake mutant
|
|
23
|
+
|
|
24
|
+
Or only on the subjects you changed since `master`:
|
|
25
|
+
|
|
26
|
+
bundle exec mutant run --since master
|
|
27
|
+
|
|
28
|
+
CI only mutates the subjects that a push or pull request changes, split into shards that run in parallel. To mutate every subject in CI, run the Mutant workflow from the Actions tab.
|
|
29
|
+
|
|
30
|
+
Performance
|
|
31
|
+
-----------
|
|
32
|
+
|
|
33
|
+
[Duel](https://github.com/sferik/duel-ruby) guards against changes that make bluepill slower. The benchmarks in `duel/` cover what bluepill does every tick: parsing `ps`, finding children, running checks, ticking processes, and logging. Duel needs Ruby 3.4 or newer. To compare your branch with `master`:
|
|
34
|
+
|
|
35
|
+
bundle exec duel
|
|
36
|
+
|
|
37
|
+
A pull request that makes a benchmark slower, allocate more, or leave more objects alive fails the Perf workflow. To check that new benchmarks pass on unchanged code, run `bundle exec duel --force`, and to run some of them, add `--filter "^watch:"`.
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# Bluepill
|
|
2
2
|
Bluepill is a simple process monitoring tool written in Ruby.
|
|
3
3
|
|
|
4
|
+
[](https://github.com/sferik/duel-ruby)
|
|
5
|
+
[][test]
|
|
6
|
+
[][lint]
|
|
7
|
+
[][mutant]
|
|
8
|
+
[][qlty]
|
|
9
|
+
[][coveralls]
|
|
4
10
|
[][gem]
|
|
5
|
-
[][travis]
|
|
6
|
-
[][gemnasium]
|
|
7
|
-
[][codeclimate]
|
|
8
|
-
[][coveralls]
|
|
9
11
|
|
|
10
12
|
[gem]: https://rubygems.org/gems/bluepill
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[
|
|
13
|
+
[test]: https://github.com/bluepill-rb/bluepill/actions/workflows/test.yml
|
|
14
|
+
[lint]: https://github.com/bluepill-rb/bluepill/actions/workflows/lint.yml
|
|
15
|
+
[mutant]: https://github.com/bluepill-rb/bluepill/actions/workflows/mutant.yml
|
|
16
|
+
[qlty]: https://qlty.sh/gh/bluepill-rb/projects/bluepill
|
|
14
17
|
[coveralls]: https://coveralls.io/github/bluepill-rb/bluepill?branch=master
|
|
15
18
|
|
|
16
19
|
## Installation
|
|
@@ -80,7 +83,7 @@ Bluepill.application("app_name") do |app|
|
|
|
80
83
|
process.checks :mem_usage, every: 10.seconds, below: 100.megabytes, times: [3,5]
|
|
81
84
|
end
|
|
82
85
|
end
|
|
83
|
-
|
|
86
|
+
```
|
|
84
87
|
|
|
85
88
|
To watch the modification time of a file, e.g. a log file to ensure the process is actually working add one more line:
|
|
86
89
|
|
|
@@ -225,6 +228,20 @@ end
|
|
|
225
228
|
|
|
226
229
|
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.
|
|
227
230
|
|
|
231
|
+
To run a command before every start, for example to clear a cache:
|
|
232
|
+
|
|
233
|
+
```ruby
|
|
234
|
+
Bluepill.application("app_name") do |app|
|
|
235
|
+
app.process("process_name") do |process|
|
|
236
|
+
process.pre_start_command = "/usr/bin/some_setup_command"
|
|
237
|
+
process.start_command = "/usr/bin/some_start_command"
|
|
238
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Bluepill waits for the `pre_start_command` to finish, and logs a warning if it exits with a non-zero status, but starts the process either way. It runs in the same `working_dir`, with the same `environment`, `uid`, and `gid`, as the process.
|
|
244
|
+
|
|
228
245
|
By default, bluepill will send a SIGTERM to your process when stopping.
|
|
229
246
|
To change the stop command:
|
|
230
247
|
|
|
@@ -264,35 +281,34 @@ process.monitor_children do |child_process|
|
|
|
264
281
|
end
|
|
265
282
|
```
|
|
266
283
|
|
|
267
|
-
Note {{PID}} will be substituted for the pid of process in both the stop and restart commands.
|
|
284
|
+
Note `{{PID}}` will be substituted for the pid of process in both the stop and restart commands.
|
|
268
285
|
|
|
269
|
-
###
|
|
286
|
+
### Commands Don't Run in a Shell
|
|
270
287
|
|
|
271
|
-
|
|
288
|
+
Bluepill splits each command (`start_command`, `pre_start_command`, `stop_command`, and `restart_command`) into words and runs it directly, without a shell. So shell syntax like `cd ... &&`, `VAR=value`, `|`, `>`, `2>&1`, and `*` globs doesn't work.
|
|
272
289
|
|
|
273
|
-
|
|
274
|
-
Bluepill.application("app_name") do |app|
|
|
275
|
-
app.process("process_name") do |process|
|
|
276
|
-
process.start_command = "cd /tmp/some_dir && SOME_VAR=1 /usr/bin/some_start_command > /tmp/server.log 2>&1"
|
|
277
|
-
process.pid_file = "/tmp/some_pid_file.pid"
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
We recommend that you _not_ do that and instead use the config options to capture output from your daemons. Like so:
|
|
290
|
+
Use the config options instead:
|
|
283
291
|
|
|
284
292
|
```ruby
|
|
285
293
|
Bluepill.application("app_name") do |app|
|
|
286
294
|
app.process("process_name") do |process|
|
|
287
|
-
process.start_command = "/usr/bin/
|
|
295
|
+
process.start_command = "/usr/bin/some_start_command"
|
|
288
296
|
process.working_dir = "/tmp/some_dir"
|
|
297
|
+
process.environment = {"SOME_VAR" => "1"}
|
|
289
298
|
process.stdout = process.stderr = "/tmp/server.log"
|
|
290
299
|
process.pid_file = "/tmp/some_pid_file.pid"
|
|
300
|
+
process.daemonize = true
|
|
291
301
|
end
|
|
292
302
|
end
|
|
293
303
|
```
|
|
294
304
|
|
|
295
|
-
|
|
305
|
+
`stdout`, `stderr`, and `stdin` only apply to processes that bluepill daemonizes. A daemonized process starts in `/` unless you set `working_dir`, so use absolute paths or set `working_dir`.
|
|
306
|
+
|
|
307
|
+
If you really need a shell, run one explicitly, and use `exec` so bluepill monitors your server instead of the shell that started it:
|
|
308
|
+
|
|
309
|
+
```ruby
|
|
310
|
+
process.start_command = "sh -c 'exec /usr/bin/some_start_command < /tmp/input'"
|
|
311
|
+
```
|
|
296
312
|
|
|
297
313
|
### CLI
|
|
298
314
|
|
|
@@ -331,6 +347,24 @@ To quit the bluepill daemon for an application:
|
|
|
331
347
|
|
|
332
348
|
sudo bluepill quit
|
|
333
349
|
|
|
350
|
+
#### bpsv
|
|
351
|
+
|
|
352
|
+
`bpsv` runs a bluepill command on the process it's named after, so a
|
|
353
|
+
symlink to it works like an init script. For a process named `unicorn`:
|
|
354
|
+
|
|
355
|
+
sudo ln -s "$(which bpsv)" /usr/local/bin/unicorn
|
|
356
|
+
sudo unicorn restart
|
|
357
|
+
|
|
358
|
+
That runs `bluepill restart unicorn`. Like `bluepill` without an
|
|
359
|
+
_app_name_, it only works when one bluepill daemon is running.
|
|
360
|
+
|
|
361
|
+
### Examples
|
|
362
|
+
|
|
363
|
+
[examples/sample_app.rb](examples/sample_app.rb) monitors a small forking
|
|
364
|
+
echo server, and stops any worker that uses too much memory. Its comments
|
|
365
|
+
show how to run it. [examples/runit.rb](examples/runit.rb) monitors a
|
|
366
|
+
service managed by runit.
|
|
367
|
+
|
|
334
368
|
### Logging
|
|
335
369
|
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:
|
|
336
370
|
|
|
@@ -342,7 +376,8 @@ end
|
|
|
342
376
|
|
|
343
377
|
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.
|
|
344
378
|
|
|
345
|
-
###
|
|
379
|
+
### Foreground mode
|
|
380
|
+
|
|
346
381
|
You can run bluepill in the foreground:
|
|
347
382
|
|
|
348
383
|
```ruby
|
|
@@ -353,6 +388,9 @@ end
|
|
|
353
388
|
|
|
354
389
|
Note that You must define only one application per config when using foreground mode.
|
|
355
390
|
|
|
391
|
+
|
|
392
|
+
JRuby allows you to run bluepill only in the foreground.
|
|
393
|
+
|
|
356
394
|
## Links
|
|
357
395
|
|
|
358
396
|
* Code: [http://github.com/bluepill-rb/bluepill](http://github.com/bluepill-rb/bluepill)
|
|
@@ -362,15 +400,16 @@ Note that You must define only one application per config when using foreground
|
|
|
362
400
|
[rubygems]: http://rubygems.org/gems/bluepill
|
|
363
401
|
|
|
364
402
|
## Supported Ruby Versions
|
|
365
|
-
This library aims to support and is [tested against][
|
|
403
|
+
This library aims to support and is [tested against][ci] the following Ruby
|
|
366
404
|
implementations:
|
|
367
405
|
|
|
368
406
|
* Ruby 1.9.3
|
|
369
|
-
* Ruby 2.0.
|
|
370
|
-
* Ruby
|
|
371
|
-
* Ruby
|
|
372
|
-
* JRuby 1.7
|
|
373
|
-
* JRuby 9.0.
|
|
407
|
+
* Ruby 2.0 through 2.7
|
|
408
|
+
* Ruby 3.0 through 3.4
|
|
409
|
+
* Ruby 4.0
|
|
410
|
+
* JRuby 1.7 (only in the foreground)
|
|
411
|
+
* JRuby 9.0 through 9.4 (only in the foreground)
|
|
412
|
+
* JRuby 10.0 and 10.1 (only in the foreground)
|
|
374
413
|
|
|
375
414
|
If something doesn't work on one of these interpreters, please open an issue.
|
|
376
415
|
|
data/bin/bluepill
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
2
|
require 'optparse'
|
|
3
3
|
require 'bluepill'
|
|
4
4
|
|
|
@@ -72,7 +72,7 @@ if options[:privileged] && ::Process.euid != 0
|
|
|
72
72
|
exit(3)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
APPLICATION_COMMANDS = %w
|
|
75
|
+
APPLICATION_COMMANDS = %w[status start stop restart unmonitor quit log].freeze
|
|
76
76
|
|
|
77
77
|
controller = Bluepill::Controller.new(options.slice(:base_dir, :log_file))
|
|
78
78
|
|
data/bluepill.gemspec
CHANGED
|
@@ -6,21 +6,32 @@ Gem::Specification.new do |spec|
|
|
|
6
6
|
spec.name = 'bluepill'
|
|
7
7
|
spec.version = Bluepill::Version
|
|
8
8
|
spec.platform = Gem::Platform::RUBY
|
|
9
|
-
spec.authors = ['Arya Asemanfar', '
|
|
9
|
+
spec.authors = ['Arya Asemanfar', 'Erik Berlin', 'Rohith Ravi', 'Gary Tsang']
|
|
10
10
|
spec.email = ['entombedvirus@gmail.com']
|
|
11
|
-
spec.homepage = '
|
|
11
|
+
spec.homepage = 'https://github.com/bluepill-rb/bluepill'
|
|
12
12
|
spec.summary = 'A process monitor written in Ruby with stability and minimalism in mind.'
|
|
13
13
|
spec.description = "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."
|
|
14
14
|
spec.license = 'MIT'
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
# RubyGems before 2.0, which Ruby 1.9.3 ships with, has no metadata
|
|
17
|
+
if spec.respond_to?(:metadata=)
|
|
18
|
+
spec.metadata = {
|
|
19
|
+
'source_code_uri' => 'https://github.com/bluepill-rb/bluepill',
|
|
20
|
+
'changelog_uri' => 'https://github.com/bluepill-rb/bluepill/blob/master/CHANGELOG.md',
|
|
21
|
+
'bug_tracker_uri' => 'https://github.com/bluepill-rb/bluepill/issues',
|
|
22
|
+
'rubygems_mfa_required' => 'true',
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
spec.add_dependency 'activesupport', '>= 3.2'
|
|
17
27
|
spec.add_dependency 'blue-daemons', '~> 1.1'
|
|
18
28
|
spec.add_dependency 'state_machine', '~> 1.1'
|
|
19
|
-
spec.add_development_dependency 'bundler', '~> 1.3'
|
|
20
29
|
|
|
21
30
|
spec.required_ruby_version = '>= 1.9.3'
|
|
22
31
|
|
|
23
|
-
|
|
24
|
-
spec.executables =
|
|
32
|
+
# sig has the RBS signatures, and the standard libraries they use in manifest.yaml
|
|
33
|
+
spec.executables = %w[bluepill bpsv]
|
|
34
|
+
spec.files = %w[CHANGELOG.md CONTRIBUTING.md DESIGN.md LICENSE README.md bluepill.gemspec sig/manifest.yaml] +
|
|
35
|
+
spec.executables.collect { |f| "bin/#{f}" } + Dir['lib/**/*.rb'] + Dir['sig/**/*.rbs']
|
|
25
36
|
spec.require_paths = ['lib']
|
|
26
37
|
end
|