We need to create a configuration file for Supervisor. A sample configuration is given in this recipe. In this example, we define the Unix HTTP server socket and a few other parameters. Note the rpcinterface:supervisor section where rpcinterface_factory is defined to communicate with clients.
Using Supervisor, we configure a simple server program in the program: 17_2_multithreaded_multicall_xmlrpc_server.py section by specifying the command and some other parameters.
Listing 7.1a gives the code for a minimal Supervisor configuration, as shown:
[unix_http_server] file=/tmp/supervisor.sock ; (the path to the socket file) chmod=0700 ; socket file mode (default 0700) [supervisord] logfile=/tmp/supervisord.log loglevel=info pidfile=/tmp/supervisord.pid nodaemon=true [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [program:17_2_multithreaded_multicall_xmlrpc_server.py] command=python 17_2_multithreaded_multicall_xmlrpc_server.py ; the program (relative uses PATH, can take args) process_name=%(program_name)s ; process_name expr (default %(program_name)s)
If you create the preceding Supervisor configuration file in your favorite editor, you can run Supervisor by simply calling it.
Now, we can code an XML-RPC client that can act as a Supervisor proxy and give us the information about the running processes.
Listing 7.1b gives the code for querying a local XML-RPC server, as shown:
#!/usr/bin/env python # Python Network Programming Cookbook, Second Edition -- Chapter - 7 # This program is optimized for Python 2.7.12. # Supervisor requires Python 2.x, and does not run on Python 3.x. import supervisor.xmlrpc import xmlrpclib def query_supervisr(sock): transport = supervisor.xmlrpc.SupervisorTransport(None, None, 'unix://%s' %sock) proxy = xmlrpclib.ServerProxy('http://127.0.0.1', transport=transport) print ("Getting info about all running processes
via Supervisord...") print (proxy.supervisor.getAllProcessInfo()) if __name__ == '__main__': query_supervisr(sock='/tmp/supervisor.sock')
If you run the Supervisor daemon, it will show output similar to the following:
$ supervisord 2013-09-27 16:40:56,861 INFO RPC interface 'supervisor' initialized 2013-09-27 16:40:56,861 CRIT Server 'unix_http_server' running without any HTTP authentication checking 2013-09-27 16:40:56,861 INFO supervisord started with pid 27436 2013-09-27 16:40:57,864 INFO spawned: '17_2_multithreaded_multicall_xmlrpc_server.py' with pid 27439 2013-09-27 16:40:58,940 INFO success: 17_2_multithreaded_multicall_xmlrpc_server.py entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
Note that our child process, 17_2_multithreaded_multicall_xmlrpc_server.py, has been launched.
Now, if you run the client code, it will query the XML-RPC server interface of Supervisor and list the running processes, as shown:
$ python 17_1_query_xmlrpc_server.py Getting info about all running processes via Supervisord... [{'now': 1380296807, 'group': '17_2_multithreaded_multicall_xmlrpc_server.py', 'description': 'pid 27439, uptime 0:05:50', 'pid': 27439, 'stderr_logfile': '/tmp/17_2_multithreaded_multicall_xmlrpc_server.py-stderr--- supervisor-i_VmKz.log', 'stop': 0, 'statename': 'RUNNING', 'start': 1380296457, 'state': 20, 'stdout_logfile': '/tmp/17_2_multithreaded_multicall_xmlrpc_server.py-stdout--- supervisor-eMuJqk.log', 'logfile': '/tmp/17_2_multithreaded_multicall_xmlrpc_server.py-stdout--- supervisor-eMuJqk.log', 'exitstatus': 0, 'spawnerr': '', 'name': '17_2_multithreaded_multicall_xmlrpc_server.py'}]