Python daemon management library

The PDM library is intended for aiding in inspecting and managing Python programs that run as daemons, without any other user interface for doing so. It allows client programs to connect to the daemon process in order to interact with it in various ways. At this point, it provides two main interfaces: A read-eval-print loop that can be used to interactively run code inside the daemon process; and a programmatic interface intended to be used to construct ad-hoc user-interfaces that can extract information from the daemon process, be notified of events occurring in it, and invoke code defined for that purpose. The latter was loosely inspired by Java's JMX.

The PDM protocol itself is unsecured, and is thus primarily intended to be used over Unix sockets, in order to use their built-in authorization. It can run over TCP as well, however, so it should be just as usable on Windows, but for obvious reasons, that should not be done outside a debugging environment. Though, the base protocol is rather flexible, so if one wanted to, authentication and authorization could probably be added with relative ease.

PDM comes with a simple program called pdm-repl, which can be used to connect to any process with a running PDM listener and run arbitrary Python code inside it using the built-in REPL.

Documentation

The documentation is maintained as Python docstrings. There is an online version of these as generated by Epydoc here.

Code samples

Some functionality for the programmatic interface is available in all daemon processes that import PDM. For example, the current runtime and CPU time used by a daemon process could be fetched with the following code:

import sys, pdm.cli
client = pdm.cli.perfclient("/path/to/server/socket")
realtime = client.find("pdm.perf.sysres/realtime")
cputime = client.find("pdm.perf.sysres/cputime")
sys.stdout.write("Real time: %s, CPU time: %s\n" % (realtime.readattr(), cputime.readattr()))

Ashd's ashd-wsgi program also exposes some statistics and events over PDM, if told to. The following code can be used to fetch the number of requests that have returned various HTTP status codes inside it:

import pprint, pdm.cli
client = pdm.cli.perfclient("/path/to/server/socket")
reqstat = client.find("ashd.perf.statistics/req")
pprint.pprint(reqstat.readattr())

The following code can be used to print simple information each time it finishes processing a request:

import sys, pdm.cli, ashd.perf

inflight = {}
def printinfo(start, fin):
    if fin.aborted:
        sys.stdout.write("%s %s; aborted in %s\n" % (start.method, start.uri, fin.time - start.time))
    else:
        sys.stdout.write("%s %s; finished in %s seconds with %s\n" % (start.method, start.uri, fin.time - start.time, fin.status))
def callback(event):
    if isinstance(event, ashd.perf.reqstart):
        inflight[event.id] = event
    elif isinstance(event, ashd.perf.reqfinish):
        if event.id not in inflight:
            return
        start = inflight[event.id]
        del inflight[event.id]
        printinfo(start, event)

client = pdm.cli.perfclient("/path/to/server/socket")
client.find("ashd.perf.requests").subscribe(callback)
try:
    while True:
        client.dispatch()
except KeyboardInterrupt: pass

Setting up a server process to listen for PDM connections is extremely simple:

import pdm.srv
pdm.srv.listen("/path/to/server/socket")

Download

The latest release of PDM is 0.2. Get the Python 2 version here, or the Python 3 version here.

Alternatively, the latest source is always available through Git at <git://git.dolda2000.com/pdm>, also viewable through Gitweb.

Valid XHTML 1.1! Valid CSS! This site attempts not to be broken.
Author: Fredrik Tolf <fredrik@dolda2000.com>
Last changed: Fri Sep 27 07:57:21 2013