angel: Process management and supervision daemon

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

angel is a daemon that runs and monitors other processes. It is similar to djb's daemontools or the Ruby project god.

It's goals are to keep a set of services running, and to facilitate the easy configuration and restart of those services. See the homepage for documentation.

[Skip to Readme]


Versions 0.2, 0.2.1, 0.3, 0.3.1, 0.3.2, 0.3.3, 0.3.4, 0.4.1, 0.4.2, 0.4.3, 0.4.4, 0.5.0, 0.5.1, 0.5.2, 0.5.2, 0.6.0, 0.6.1, 0.6.2
Change log
Dependencies base (>=4.0 && <5), configurator (>=0.1), containers (>=0.3), mtl, old-locale, optparse-applicative, process (>= && <2.0), stm (>=2.0), text (>=0.11), time, transformers, unix (>=2.4), unordered-containers (>=0.1.4) [details]
License BSD-3-Clause
Author Jamie Turner
Maintainer Michael Xavier <>
Category System
Home page
Source repo head: git clone
Uploaded by MichaelXavier at 2015-04-17T02:31:20Z


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Readme for angel-0.5.2

[back to package description]


Build Status

angel is a daemon that runs and monitors other processes. It is similar to djb's daemontools or the Ruby project god.

It's goals are to keep a set of services running, and to facilitate the easy configuration and restart of those services.


The author is a long-time user of daemontools due to its reliability and simplicity; however, daemontools is quirky and follows many unusual conventions.

angel is an attempt to recreate daemontools's capabilities (though not the various bundled utility programs which are still quite useful) in a more intuitive and modern unix style.


angel is driven by a configuration file that contains a list of program specifications to run. angel assumes every program listed in the specification file should be running at all times.

angel starts each program, and optionally sets the program's stdout and stderr to some file(s) which have been opened in append mode (or pipes stdout and stderr to some logger process); at this point, the program is said to be "supervised".

If the program dies for any reason, angel waits a specified number of seconds (default, 5), then restarts the program.

The angel process itself will respond to a HUP signal by re-processing its configuration file, and synchronizing the run states with the new configuration. Specifically:

Safety and Reliability

Because of angel's role in policing the behavior of other daemons, it has been written to be very reliable:


  1. Install the haskell-platform (or somehow, ghc 7.0 + cabal-install)
  2. Run cabal install in the project root (this directory)
  3. Either add the ~/.cabal/bin file to your $PATH or copy the angel executable to /usr/local/bin


Configuration and Usage Example

The angel executable takes a path to an angel configuration file.

angel --help
angel - Process management and supervision daemon


Available options:
  -h,--help                Show this help text
  -v VERBOSITY             Verbosity from 0-2 (default: 2)

angel's configuration system is based on Bryan O'Sullivan's configurator package. A full description of the format can be found here:

A basic configuration file might look like this:

watch-date {
    exec = "watch date"

ls {
    exec = "ls"
    stdout = "/tmp/ls_log"
    stderr = "/tmp/ls_log"
    delay = 7
    termgrace = off

workers {
    directory = "/path/to/worker"
    exec      = "run_worker"
    count     = 30
    pidfile   = "/path/to/"
    env {
      FOO = "BAR"
      BAR = "BAZ"
    termgrace = 10

Each program that should be supervised starts a program-id block:

watch-date {

Then, a series of corresponding configuration commands follow:

Assuming the above configuration was in a file called "example.conf", here's what a shell session might look like:

jamie@choo:~/random/angel$ angel example.conf 
[2010/08/24 15:21:22] {main} Angel started
[2010/08/24 15:21:22] {main} Using config file: example.conf
[2010/08/24 15:21:22] {process-monitor} Must kill=0, must start=2
[2010/08/24 15:21:22] {- program: watch-date -} START
[2010/08/24 15:21:22] {- program: watch-date -} RUNNING
[2010/08/24 15:21:22] {- program: ls -} START
[2010/08/24 15:21:22] {- program: ls -} RUNNING
[2010/08/24 15:21:22] {- program: ls -} ENDED
[2010/08/24 15:21:22] {- program: ls -} WAITING
[2010/08/24 15:21:29] {- program: ls -} RESTART
[2010/08/24 15:21:29] {- program: ls -} START
[2010/08/24 15:21:29] {- program: ls -} RUNNING
[2010/08/24 15:21:29] {- program: ls -} ENDED
[2010/08/24 15:21:29] {- program: ls -} WAITING

.. etc

You can see that when the configuration is parsed, the process-monitor notices that two programs need to be started. A supervisor is started in a lightweight thread for each, and starts logging with the context program: <program-id>. pp watch-date starts up and runs. Since watch is a long-running process it just keeps running in the background.

ls, meanwhile, runs and immediately ends, of course; then, the WAITING state is entered until delay seconds pass. Finally, the RESTART event is triggered and it is started again, ad naseum.

Now, let's see what happens if we modify the config file to look like this:

#watch-date {
#    exec = "watch date"

ls {
    exec = "ls"
    stdout = "/tmp/ls_log"
    stderr = "/tmp/ls_log"
    delay = 7

.. and then send HUP to angel.

[2010/08/24 15:33:59] {config-monitor} HUP caught, reloading config
[2010/08/24 15:33:59] {process-monitor} Must kill=1, must start=0
[2010/08/24 15:33:59] {- program: watch-date -} ENDED
[2010/08/24 15:33:59] {- program: watch-date -} QUIT
[2010/08/24 15:34:03] {- program: ls -} RESTART
[2010/08/24 15:34:03] {- program: ls -} START
[2010/08/24 15:34:03] {- program: ls -} RUNNING
[2010/08/24 15:34:03] {- program: ls -} ENDED
[2010/08/24 15:34:03] {- program: ls -} WAITING

As you can see, the config monitor reloaded on HUP, and then the process monitor marked the watch-date process for killing. TERM was sent to the child process, and then the supervisor loop QUIT because the watch-date program no longer had a config entry.

This also works for when you specify count. Incrementing/decrementing the count will intelligently shut down excess processes and spin new ones up.

Advanced Configuration

The configurator package supports import statements, as well as environment variable expansion. Using collections of configuration files and host-based or service-based environment variables, efficient, templated angel configurations can be had.


If you prefer to stick with haskell tools, use cabal to build the package.

You can run the test suite with

make test


Can I have multiple programs logging to the same file?

Yes, angel dup()s file descriptors and makes effort to safely allow concurrent writes by child programs; you should DEFINITELY make sure your child program is doing stdout/stderr writes in line-buffered mode so this doesn't result in a complete interleaved mess in the log file.

Will angel restart programs for me?

No; the design is just to send your programs TERM, then angel will restart them. angel tries to work in harmony with traditional Unix process management conventions.

How can I take a service down without wiping out its configuration?

Specify a count of 0 for the process. That will kill any running processes but still let you keep it in the config file.




Original Author: Jamie Turner Current Maintainer: Michael Xavier

Thanks to Bump Technologies, Inc. ( for sponsoring some of the work on angel.

And, of course, thanks to all Angel's contributors: