Supervisor
Supervisor is a client/server system that allows users to monitor and control a number of processes on UNIX-like operating systems. The Python package installs the `supervisord` server, `supervisorctl` client, and utilities. It also enables programmatic interaction with `supervisord` via its XML-RPC interface. The current stable version is 4.3.0, with releases occurring a few times a year for maintenance and feature updates.
Warnings
- breaking Supervisor 4.0.0 introduced several breaking changes for programmatic interaction via XML-RPC. This includes changes to return types (e.g., booleans instead of integers) and the removal/renaming of some API methods like `getSupervisorState` (use `getState`) and `clearAllLogFiles`.
- gotcha Installing the `supervisor` package via `pip` only installs the `supervisord` server, `supervisorctl` client, and associated Python modules. It does not automatically configure, start, or manage `supervisord` as a system service. Users often mistakenly expect `pip install` to immediately launch a daemon.
- gotcha Incorrect permissions or paths in the `supervisord.conf` file can lead to `supervisord` failing to start, manage processes, or listen for connections. Common issues include `log_file` paths, `pid_file` locations, and permissions for the `unix_http_server` socket or `inet_http_server` ports.
Install
-
pip install supervisor
Imports
- childutils
from supervisor import childutils
- ServerProxy
from xmlrpc.client import ServerProxy
Quickstart
import xmlrpc.client
import os
# NOTE: This assumes a 'supervisord' instance is running
# and its XML-RPC interface is accessible, e.g., on port 9001.
# You might need to configure supervisord.conf for this.
# Example: [inet_http_server]
# port=*:9001
# username=user
# password=123
rpc_url = os.environ.get('SUPERVISOR_RPC_URL', 'http://localhost:9001/RPC2')
rpc_username = os.environ.get('SUPERVISOR_RPC_USERNAME', '')
rpc_password = os.environ.get('SUPERVISOR_RPC_PASSWORD', '')
if rpc_username and rpc_password:
# Add credentials to the URL if specified
auth_url = rpc_url.replace('http://', f'http://{rpc_username}:{rpc_password}@')
proxy = xmlrpc.client.ServerProxy(auth_url)
else:
proxy = xmlrpc.client.ServerProxy(rpc_url)
try:
# Get basic information about processes
all_processes = proxy.supervisor.getAllProcessInfo()
print(f"Found {len(all_processes)} supervised processes:")
for p in all_processes:
print(f" - Name: {p['name']}, State: {p['statename']}, PID: {p['pid']}")
# Example: Check API version
api_version = proxy.supervisor.getAPIVersion()
print(f"Supervisor API Version: {api_version}")
# Example: Stop a process (replace 'my_program' with an actual process name)
# try:
# print(f"Attempting to stop 'my_program': {proxy.supervisor.stopProcess('my_program')}")
# except xmlrpc.client.Fault as e:
# print(f"Error stopping process: {e}")
except ConnectionRefusedError:
print(f"ERROR: Connection refused. Is supervisord running and its RPC interface listening on {rpc_url}?", flush=True)
except xmlrpc.client.Fault as e:
print(f"ERROR: XML-RPC Fault: {e}", flush=True)
except Exception as e:
print(f"An unexpected error occurred: {e}", flush=True)