python-daemon Frequently Asked Questions
:Author: Ben Finney :Updated: 2010-04-10
.. contents:: .. 1 General 1.1 What is the purpose of the ‘python-daemon’ library? 1.2 How can I run a service communicating with a separate daemon process? 2 File descriptors 2.1 Why does the output stop after opening the daemon context? 2.2 How can I preserve a ‘logging’ handler's file descriptor?
What is the purpose of the ‘python-daemon’ library?
The ‘python-daemon’ library has a deliberately narrow focus: that of
being a reference implementation for
PEP 3143_, “Standard daemon
PEP 3143: http://www.python.org/dev/peps/pep-3143
How can I run a service communicating with a separate daemon process?
As specified in
PEP 3143_, the ‘python-daemon’ library is
specifically focussed on the goal of having the current running
program become a well-behaved Unix daemon process. This leaves open
the question of how this program is started, or about multiple
programs interacting. As detailed in PEP 3143:
A daemon is not a service There is a related concept in many systems, called a “service”. A service differs from the model in this PEP, in that rather than having the *current* program continue to run as a daemon process, a service starts an *additional* process to run in the background, and the current process communicates with that additional process via some defined channels. The Unix-style daemon model in this PEP can be used, among other things, to implement the background-process part of a service; but this PEP does not address the other aspects of setting up and managing a service.
A possible starting point for such a “service” model of execution is
message from 2009-01-30_ to the
message from 2009-01-30: http://mail.python.org/pipermail/python-ideas/2009-January/002606.html
Why does the output stop after opening the daemon context?
The specified behaviour in
PEP 3143_ includes the requirement to
detach the process from the controlling terminal (to allow the process
to continue to run as a daemon), and to close all file descriptors not
known to be safe once detached (to ansure any files that continue to
be used are under the control of the daemon process).
If you want the process to generate output via the system streams ‘sys.stdout’ and ‘sys.stderr’, set the ‘DaemonContext’'s ‘stdout’ and/or ‘stderr’ options to a file-like object (e.g. the ‘stream’ attribute of a ‘logging.Handler’ instance). If these objects have file descriptors, they will be preserved when the daemon context opens.
How can I preserve a ‘logging’ handler's file descriptor?
The ‘DaemonContext.open’ method conforms to
PEP 3143_ by closing all
open file descriptors, but excluding those files specified in the
‘files_preserve’ option. This option is a list of files or file
The Python standard library ‘logging’ module provides log handlers
that write to streams, including to files via the ‘StreamHandler’
class and its sub-classes. The documentation (both the online
module documentation_ and the docstrings for the code) makes no
mention of a way to get at the stream associated with a handler
However, looking at the source code for ‘StreamHandler’, in Python 2.5
/usr/lib/python2.5/logging/__init__.py, shows a ‘stream’
attribute that is bound to the stream object. The attribute is not
marked private (i.e. it is not named with a leading underscore), so we
can presume it is part of the public API.
That attribute can then be used to specify that a logging handler's file descriptor should, when the ‘DaemonContext’ opens, be excluded from closure::
import logging import daemon # any subclass of StreamHandler should provide the ‘stream’ attribute. lh = logging.handlers.TimedRotatingFileHandler( "/var/log/foo.log", # … ) # … do some logging and other activity … daemon_context = daemon.DaemonContext() daemon_context.files_preserve = [lh.stream] daemon_context.open() # … continue as a daemon process …
logging module documentation: http://docs.python.org/library/logging
.. Local variables: mode: rst coding: utf-8 time-stamp-format: "%:y-%02m-%02d" time-stamp-start: "^:Updated:[ ]+" time-stamp-end: "$" time-stamp-line-limit: 20 End: vim: filetype=rst fileencoding=utf-8 :