{"id":13463287,"url":"https://github.com/bluepill-rb/bluepill","last_synced_at":"2025-12-16T15:56:20.661Z","repository":{"id":11066990,"uuid":"13409606","full_name":"bluepill-rb/bluepill","owner":"bluepill-rb","description":"simple process monitoring tool","archived":false,"fork":false,"pushed_at":"2023-08-21T10:15:06.000Z","size":540,"stargazers_count":416,"open_issues_count":24,"forks_count":52,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-10-29T13:50:47.281Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluepill-rb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2013-10-08T09:52:49.000Z","updated_at":"2024-04-15T08:54:29.000Z","dependencies_parsed_at":"2024-01-05T22:00:07.976Z","dependency_job_id":null,"html_url":"https://github.com/bluepill-rb/bluepill","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/bluepill-rb/bluepill","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluepill-rb%2Fbluepill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluepill-rb%2Fbluepill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluepill-rb%2Fbluepill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluepill-rb%2Fbluepill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluepill-rb","download_url":"https://codeload.github.com/bluepill-rb/bluepill/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluepill-rb%2Fbluepill/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27767430,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-16T02:00:10.477Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T13:00:49.878Z","updated_at":"2025-12-16T15:56:20.636Z","avatar_url":"https://github.com/bluepill-rb.png","language":"Ruby","funding_links":[],"categories":["Maintenance \u0026 Monitoring","Ruby","Process Management and Monitoring","Process Monitoring"],"sub_categories":["Server Monitoring"],"readme":"# Bluepill\nBluepill is a simple process monitoring tool written in Ruby.\n\n[![Gem Version](https://badge.fury.io/rb/bluepill.svg)][gem]\n[![Build Status](https://travis-ci.org/bluepill-rb/bluepill.svg?branch=master)][travis]\n[![Dependency Status](https://gemnasium.com/bluepill-rb/bluepill.svg)][gemnasium]\n[![Code Climate](https://codeclimate.com/github/bluepill-rb/bluepill/badges/gpa.svg)][codeclimate]\n[![Coverage Status](https://coveralls.io/repos/bluepill-rb/bluepill/badge.svg?branch=master\u0026service=github)][coveralls]\n\n[gem]: https://rubygems.org/gems/bluepill\n[travis]: https://travis-ci.org/bluepill-rb/bluepill\n[gemnasium]: https://gemnasium.com/bluepill-rb/bluepill\n[codeclimate]: https://codeclimate.com/github/bluepill-rb/bluepill\n[coveralls]: https://coveralls.io/github/bluepill-rb/bluepill?branch=master\n\n## Installation\nIt\u0026apos;s hosted on [rubygems.org][rubygems].\n\n    sudo gem install bluepill\n\nIn 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:\n\n    local6.*          /var/log/bluepill.log\n\nYou\u0026apos;ll also want to add _/var/log/bluepill.log_ to _/etc/logrotate.d/syslog_ so that it gets rotated.\n\nLastly, create the _/var/run/bluepill_ directory for bluepill to store its pid and sock files.\n\n## Usage\n### Config\nBluepill organizes processes into 3 levels: application -\u003e group -\u003e 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.\n\nThe minimum config file looks something like this:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n  end\nend\n```\n\nNote that since we specified a PID file and start command, bluepill assumes the process will daemonize itself. If we wanted bluepill to daemonize it for us, we can do (note we still need to specify a PID file):\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.daemonize = true\n  end\nend\n```\n\nIf you don\u0026apos;t specify a stop command, a TERM signal will be sent by default. Similarly, the default restart action is to issue stop and then start.\n\nNow if we want to do something more meaningful, like actually monitor the process, we do:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.checks :cpu_usage, every: 10.seconds, below: 5, times: 3\n  end\nend\n```\n\nWe added a line that checks every 10 seconds to make sure the cpu usage of this process is below 5 percent; 3 failed checks results in a restart. We can specify a two-element array for the _times_ option to say that it 3 out of 5 failed attempts results in a restart.\n\nTo watch memory usage, we just add one more line:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.checks :cpu_usage, every: 10.seconds, below: 5, times: 3\n    process.checks :mem_usage, every: 10.seconds, below: 100.megabytes, times: [3,5]\n  end\nend\n ```\n\nTo watch the modification time of a file, e.g. a log file to ensure the process is actually working add one more line:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.checks :cpu_usage, every: 10.seconds, below: 5, times: 3\n    process.checks :mem_usage, every: 10.seconds, below: 100.megabytes, times: [3,5]\n    process.checks :file_time, every: 60.seconds, below: 3.minutes, filename: \"/tmp/some_file.log\", times: 2\n  end\nend\n```\n\nTo restart process if it's running too long:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.checks :running_time, every: 10.minutes, below: 24.hours\n  end\nend\n```\n\nWe can tell bluepill to give a process some grace time to start/stop/restart before resuming monitoring:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.start_grace_time = 3.seconds\n    process.stop_grace_time = 5.seconds\n    process.restart_grace_time = 8.seconds\n    process.checks :cpu_usage, every: 10.seconds, below: 5, times: 3\n    process.checks :mem_usage, every: 10.seconds, below: 100.megabytes, times: [3,5]\n  end\nend\n```\n\nWe can group processes by name:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  5.times do |i|\n    app.process(\"process_name_#{i}\") do |process|\n      process.group = \"mongrels\"\n      process.start_command = \"/usr/bin/some_start_command\"\n      process.pid_file = \"/tmp/some_pid_file.pid\"\n    end\n  end\nend\n```\n\nIf you want to run the process as someone other than root:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.uid = \"deploy\"\n    process.gid = \"deploy\"\n    process.checks :cpu_usage, every: 10.seconds, below: 5, times: 3\n    process.checks :mem_usage, every: 10.seconds, below: 100.megabytes, times: [3,5]\n  end\nend\n```\n\nIf you want to include one or more supplementary groups:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.uid = \"deploy\"\n    process.gid = \"deploy\"\n    process.supplementary_groups = ['rvm']\n    process.checks :cpu_usage, every: 10.seconds, below: 5, times: 3\n    process.checks :mem_usage, every: 10.seconds, below: 100.megabytes, times: [3,5]\n  end\nend\n```\n\nYou can also set an app-wide uid/gid:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.uid = \"deploy\"\n  app.gid = \"deploy\"\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n  end\nend\n```\n\nTo track resources of child processes, use `:include_children`:\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.checks :mem_usage, every: 1.seconds, below: 5.megabytes, times: [3,5], include_children: true\n  end\nend\n```\n\nTo check for flapping:\n\n```ruby\nprocess.checks :flapping, times: 2, within: 30.seconds, retry_in: 7.seconds\n```\n\nTo set the working directory to `cd` into when starting the command:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.working_dir = \"/path/to/some_directory\"\n  end\nend\n```\n\nYou can also have an app-wide working directory:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.working_dir = \"/path/to/some_directory\"\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n  end\nend\n```\n\nNote: 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.\n\nBy default, bluepill will send a SIGTERM to your process when stopping.\nTo change the stop command:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.stop_command = \"/user/bin/some_stop_command\"\n  end\nend\n```\n\nIf you'd like to send a signal or signals to your process to stop it:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/some_start_command\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n    process.stop_signals = [:quit, 30.seconds, :term, 5.seconds, :kill]\n  end\nend\n```\n\nWe added a line that will send a SIGQUIT, wait 30 seconds and check to\nsee if the process is still up, send a SIGTERM, wait 5 seconds and check\nto see if the process is still up, and finally send a SIGKILL.\n\nAnd lastly, to monitor child processes:\n\n```ruby\nprocess.monitor_children do |child_process|\n  child_process.checks :cpu_usage, every: 10, below: 5, times: 3\n  child_process.checks :mem_usage, every: 10, below: 100.megabytes, times: [3, 5]\n  child_process.stop_command = \"kill -QUIT {{PID}}\"\nend\n```\n\nNote {{PID}} will be substituted for the pid of process in both the stop and restart commands.\n\n### A Note About Output Redirection\n\nWhile you can specify shell tricks like the following in the `start_command` of a process:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"cd /tmp/some_dir \u0026\u0026 SOME_VAR=1 /usr/bin/some_start_command \u003e /tmp/server.log 2\u003e\u00261\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n  end\nend\n```\n\nWe recommend that you _not_ do that and instead use the config options to capture output from your daemons. Like so:\n\n```ruby\nBluepill.application(\"app_name\") do |app|\n  app.process(\"process_name\") do |process|\n    process.start_command = \"/usr/bin/env SOME_VAR=1 /usr/bin/some_start_command\"\n    process.working_dir = \"/tmp/some_dir\"\n    process.stdout = process.stderr = \"/tmp/server.log\"\n    process.pid_file = \"/tmp/some_pid_file.pid\"\n  end\nend\n```\n\nThe 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.\n\n### CLI\n\n#### Usage\n\n    bluepill [app_name] command [options]\n\nFor the \"load\" command, the _app_name_ is specified in the config file, and\nmust not be provided on the command line.\n\nFor all other commands, the _app_name_ is optional if there is only\none bluepill daemon running. Otherwise, the _app_name_ must be\nprovided, because the command will fail when there are multiple\nbluepill daemons running. The example commands below leaves out the\n_app_name_.\n\n#### Commands\n\nTo start a bluepill daemon and load the config for an application:\n\n    sudo bluepill load /path/to/production.pill\n\nTo act on a process or group for an application:\n\n    sudo bluepill \u003cstart|stop|restart|unmonitor\u003e \u003cprocess_or_group_name\u003e\n\nTo view process statuses for an application:\n\n    sudo bluepill status\n\nTo view the log for a process or group for an application:\n\n    sudo bluepill log \u003cprocess_or_group_name\u003e\n\nTo quit the bluepill daemon for an application:\n\n    sudo bluepill quit\n\n### Logging\nBy default, bluepill uses syslog local6 facility as described in the installation section. But if for any reason you don\u0026apos;t want to use syslog, you can use a log file. You can do this by setting the :log\\_file option in the config:\n\n```ruby\nBluepill.application(\"app_name\", log_file: \"/path/to/bluepill.log\") do |app|\n  # ...\nend\n```\n\nKeep in mind that you still need to set up log rotation (described in the installation section) to keep the log file from growing huge.\n\n### Foreground mode\n\nYou can run bluepill in the foreground:\n\n```ruby\nBluepill.application(\"app_name\", foreground: true) do |app|\n  # ...\nend\n```\n\nNote that You must define only one application per config when using foreground mode.\n\n\nJRuby allows you to run bluepill only in the foreground.\n\n## Links\n\n* Code: [http://github.com/bluepill-rb/bluepill](http://github.com/bluepill-rb/bluepill)\n* Bugs/Features: [http://github.com/bluepill-rb/bluepill/issues](http://github.com/bluepill-rb/bluepill/issues)\n* Mailing List: [http://groups.google.com/group/bluepill-rb](http://groups.google.com/group/bluepill-rb)\n\n[rubygems]: http://rubygems.org/gems/bluepill\n\n## Supported Ruby Versions\nThis library aims to support and is [tested against][travis] the following Ruby\nimplementations:\n\n* Ruby 1.9.3\n* Ruby 2.0.0\n* Ruby 2.1\n* Ruby 2.2\n* JRuby 1.7 (only in the foreground)\n* JRuby 9.0.0.0 (only in the foreground)\n\nIf something doesn't work on one of these interpreters, please open an issue.\n\nThis library may inadvertently work (or seem to work) on other Ruby\nimplementations, however support will only be provided for the versions listed\nabove.\n\nIf you would like this library to support another Ruby version, you may\nvolunteer to be a maintainer. Being a maintainer entails making sure all tests\nrun and pass on that implementation. When something breaks on your\nimplementation, you will be responsible for providing patches in a timely\nfashion. If critical issues for a particular implementation exist at the time\nof a major release, support for that Ruby version may be dropped.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluepill-rb%2Fbluepill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluepill-rb%2Fbluepill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluepill-rb%2Fbluepill/lists"}