Supervisor: The Key to Reliable and Efficient Process Management
Tags: tutorial, linux
Published: 2023-02-10 19:56:52

Advanced web applications are not just based on processing HTTP requests. Various processes are often carried out in the background to speed up the response time, such as consuming messages from queues. In this post, I will present the basic capabilities of the tool which is used to keep these processes alive and to restart them if they stop working.

# What is Supervisor?

In a nutshell, Supervisor is a tool for controlling processes. It works on most operating systems, except for Windows, which shouldn't be a problem for most web applications. It is easy to configure and has been developed for many years.

It is ideal for situations where we want to ensure that a particular process is always running. An example might be the aforementioned message queue consumer. The processes are started again almost immediately after they are stopped.

Another notable feature of the Supervisor is the ability to specify the number of processes of a particular program that are to be started simultaneously. This allows us to increase the speed of data processing.

## Installation

Installation on Ubuntu is simple and can be done with the following command:

```shell
apt-get install supervisor
```

## Configuration

Processes are defined by creating configuration files with the `.conf` extension in the `/etc/supervisor/conf.d/` directory.

What the configuration file contains? An example content of a configuration file is as follows:

```
[program:a-long-running-process]
process_name= %(program_name)s_%(process_num)02d
command= php bin/console run:consumer
autostart=true
autorestart=true
stderr_logfile=/var/www/html/logs/consumer-long-running-process.err.log
stdout_logfile=/var/www/html/logs/consumer-long-running-process.out.log
numprocs=2
startsecs=0
priority=100
```

`process_name` - determines the name of the process - in this case, the concatenation of the process name and process number.

`command` - command we want it to run.

`autostart` - indicates that the command will be run as soon as the supervisor is started. Set to `true` by default.

`autorestart` - this option determines what is to happen to the process when it is completed. It takes the following values:
  - `true` - the process will always be started after termination
  - `false` - the process will not be started after termination
  - `unexpected` - the process will be started if it terminates with an unexpected error.

The default value is set to unexpected.

`stderr_logfile` and `stdout_logfile` are the paths to the files where the logs will be saved.

`numprocs` - defines how many instances of a given program are to be run by the Supervisor. The default value is 1. If the value is different, it is necessary to add the value `%(process_num)` to the `process_name` parameter.

`priority` - lower priorities cause programs to be run before other programs, and to finish last. The default value is `999`.

`startsecs` - defines the number of seconds that the programme must run before it is considered to have started successfully. If you set this value to 0, the program does not need to run for the specified time. The default value is 1.

## Commands

There are multiple commands which can be used to maintain the Supervisor and its running processes. Some of them, which should be sufficient for basic usage, are:

```
service supervisor restart
```
Restarts the supervisor without taking into account the configuration changes

---

```
service supervisor start
```
Starts all processes

---

```
service supervisor stop
```
Stops all processes

---

```
supervisorctl status all
```
Shows status of all processes

---

```
supervisorctl restart [name]
```
Restarts the process without loading a new configuration

---

```
supervisorctl start [name]
```
Starts a particular process

---

```
supervisorctl reread
```
Loads new configurations without restarting the process

---

```
supervisorctl update
```
Restarts processes which configuration has been changed

## Example Usage

To show you the practical usage of this tool I'm going to create a simple PHP script which prints process name and a current date in a new line every 1 second.
The script looks like below:

```php
// /app/myscript.php
<?php 

while(true) {
    echo \sprintf(
        "[%s] %s\n",
        $argv[1] ?? 'Default process name',
        date('H:i:s')
    );
    sleep(1);
}
```

Next, let's start the Supervisor:

```shell
service supervisor start

Output: 
  Starting supervisor: supervisord.
```

After that we have to create a configuration file for our PHP script

```shell
nano /etc/supervisor/conf.d/myscript.conf
```

In the configuration file, we have to specify the details for our program:

```
[program:myscript]
process_name= %(program_name)s_%(process_num)02d
command=php /app/myscript.php %(program_name)s_%(process_num)02d
numprocs=2
startsecs=10
autostart=true
autorestart=true
stdout_logfile=/var/log/myscript_stdout.log
stderr_logfile=/var/log/myscript_stderr.log
```

Next, Supervisor has to be reloaded to apply the changes:

```shell
supervisorctl reload

Output: 
  Restarted supervisord
```

Now we can check the status of running processes:

```shell
supervisorctl status all

Output:
    myscript:myscript_00             RUNNING   pid 267, uptime 0:00:19
    myscript:myscript_01             RUNNING   pid 266, uptime 0:00:19
```

Finally, we can check if the script is working properly - there should be two lines added every second, as we run two instances of the program:

```
tail -f /var/log/myscript_stdout.log

Output:
    [myscript_00] 16:07:28
    [myscript_01] 16:07:28
    [myscript_00] 16:07:29
    [myscript_01] 16:07:29
```

That's it! Our PHP script is now being managed by Supervisor, and it will automatically start whenever the server restarts.