Contribute on GitHub

svsh

Take control of your supervisor

svsh Get Started
latest version: 1.2.0

About

svsh is a command line shell for process supervision suites of the daemontools family. Currently, it supports daemontools, perp, s6 and runit. It provides a unified interface allowing easy inspection and manipulation of services (i.e. processes) managed by these supervisors.

svsh is not a supervisor in itself, but an external tool for interacting with existing process supervision suites. If you are unfamiliar with these suites, here's the gist: they manage a set of processes, making sure they are all up, and attempt to bring them up if they ever go down. Some of them are designed to run as a system's init process, i.e. process 1, thus providing an alternative to System V, systemd and others. They all provide a set of command line utilities that allow to launch processes in certain ways (such as with resouce limits), and to manipulate them once running. They are considered a "family", since they provide mostly the same utilities, and their configuration is mostly compatible. They are different from other inits and supervisors (like supervisord), not only in this structure, but in other key respects. An excellent overview of supervision suites and differences from traditional supervisors are posted on the s6 website.

With svsh, it is easy to get a complete view of your processes and their statuses. You can bring processes up, down, send them signals and view their output in real time. You don't need to remember the particular syntax of the control tools provided by your suite. Instead, you get a natural syntax that's easy to remember. Why execute perpctl -b /services q nginx when you can just type restart nginx?

svsh is written in Perl and currently targets UNIX-like operating systems that use procfs.

Install

svsh releases are hosted in CPAN and can be installed like any other Perl module.

with cpanm:

$ cpanm -S Svsh

with the cpan shell:

$ cpan Svsh

building manually:

Download the tarball, extract it, and build with:

$ perl Makefile.PL
$ make && make test
$ sudo make install

Use

svsh is ready to rock right out of the box. No configuration or changes to your service directories are needed. Simply point it to your base directory (the directory from which your supervisor is running), and you instantly get a usable shell:

$ svsh --suite runit --basedir /etc/services

Once started, you get a list of all managed services, including their statuses, uptime or downtime durations, and process IDs.

         process |     status | duration |   pid 
         haproxy |         up |     126s | 28444 
           nginx |       down |      12s |     -
        worker-1 |         up |     126s | 28438 
        worker-2 |         up |     126s | 28443 
        worker-3 |         up |      55s | 28437 

svsh>

Commands

The following commands are then available:

status Prints an updated list of service statuses.
start Starts a list of services, if they are not already up.
svsh> start nginx haproxy
stop Stops a list of services, if they are not already down. They will not be restarted.
svsh> stop nginx
restart Restarts a list of services. Most supervisors implement this with a QUIT signal.
svsh> restart worker*
signal Sends a UNIX signal to a list of services. Not all signals are supported by all supervisors.
svsh> signal hup nginx
fg Moves a service to the foreground, so that its output is followed on screen.
svsh> fg worker-2
toggle Toggles an svsh option. See list of options.
svsh> toggle collapse

The following commands are implemented by some supervisors:

rescan / update Causes the supervisor to rescan the base directory for new or removed services.
terminate / shutdown Terminates the supervisor and all services.

Log Inspection

All of the supported supervision suites do not enforce a logging scheme on managed services. While all of them provide a logging tool (daemontools provides multilog, perp provides tinylog and sissylog; s6 provides s6-log; runit provides svlogd), none of them enforce their usage. It is actually not uncommon among users of these suites to use a logging tool provided by one suite for services managed by another one. This means it is hard for an external program such as svsh to determine where log files are stored, if at all.

Currently, svsh will attempt to find the log file of a service by checking the pid of the associated log process, and if (and only if) that process is one of the supported loggers (multilog, tinylog, s6-log or svlogd), it will try to find the file descriptor used by that process under /proc/<pid>/fd. As long as your services are being logged by one of these tools, svsh should be able to tail their log files when the fg command is used.

History and Auto-Completion

svsh

svsh provides bash-like history so you can use your up arrow key to cycle back through past commands, or use Ctrl+R to search your history. The history file is saved under ~/.svsh_history.

Also, autocompletion is provided for all commands. Tap the tab key at any moment while typing in commands and arguments, and svsh will attempt to autocomplete your current word, or display a list if multiple options are available.

For this to work best, it is recommended to install Term::ReadLine::Gnu.

Wildcards

svsh makes it easy to manipulate multiple services at once. Wildcards are supported by the start, stop, restart and signal commands. If, for example, you have several services whose names start with "worker", you can stop them all by executing stop worker*. Wildcards are also supported at the beginning of the name, so signal term *d will send a TERM signal to all services whose names end with "d".

    svsh> status
       process |     status | duration |   pid 
      worker-1 |         up |    9813s | 25984
      worker-2 |         up |    9813s | 25976
      worker-3 |         up |    4393s | 2990

    svsh> stop worker*

    svsh> status
       process |     status | duration |   pid 
      worker-1 |       down |       2s |     -
      worker-2 |       down |       2s |     -
      worker-3 |       down |       2s |     -

Collapse

Often times you would like to run a certain service with X number of identical processes. None of the supervision suites have any mechanism to allow this (none that I know of at least), apart from creating identical copies of a service directory for every process needed. While svsh can't help you with that, it provides a nice feature for collapsing these identical services in the output of the status command to just one line. This can be very useful with lots of multi-process services.

Currently, svsh determines multi-process services if their names are postfixed with a dash and a number. For example, if you have a service called "worker" that you need 3 processes of which to run, you can create "worker-1", "worker-2" and "worker-3" service directories. If the collapse option is on, svsh will collapse all of these into just one line, under the name status.

    svsh> status
       process |     status | duration |   pid 
      worker-1 |         up |    9813s | 25984
      worker-2 |         up |    9813s | 25976
      worker-3 |         up |    4393s | 2990

    svsh> toggle collapse
       process |     status | duration |   pid 
        worker |       3 up |    9850s |     -