33
|
1 ‘python-daemon’ Frequently Asked Questions
|
|
2 ##########################################
|
|
3
|
|
4 :Author: Ben Finney <ben+python@benfinney.id.au>
|
|
5 :Updated: 2015-01-10
|
|
6
|
|
7 .. contents::
|
|
8 ..
|
|
9 1 General
|
|
10 1.1 What is the purpose of the ‘python-daemon’ library?
|
|
11 1.2 How can I run a service communicating with a separate daemon process?
|
|
12 2 Security
|
|
13 2.1 Why is the umask set to 0 by default?
|
|
14 3 File descriptors
|
|
15 3.1 Why does the output stop after opening the daemon context?
|
|
16 3.2 How can I preserve a ‘logging’ handler's file descriptor?
|
|
17
|
|
18 General
|
|
19 =======
|
|
20
|
|
21 What is the purpose of the ‘python-daemon’ library?
|
|
22 ---------------------------------------------------
|
|
23
|
|
24 The ‘python-daemon’ library has a deliberately narrow focus: that of
|
|
25 being a reference implementation for `PEP 3143`_, “Standard daemon
|
|
26 process library”.
|
|
27
|
|
28 .. _`PEP 3143`: http://www.python.org/dev/peps/pep-3143
|
|
29
|
|
30 How can I run a service communicating with a separate daemon process?
|
|
31 ---------------------------------------------------------------------
|
|
32
|
|
33 As specified in `PEP 3143`_, the ‘python-daemon’ library is
|
|
34 specifically focussed on the goal of having the *current running
|
|
35 program* become a well-behaved Unix daemon process. This leaves open
|
|
36 the question of how this program is started, or about multiple
|
|
37 programs interacting. As detailed in PEP 3143:
|
|
38
|
|
39 A daemon is not a service
|
|
40
|
|
41 There is a related concept in many systems, called a “service”. A
|
|
42 service differs from the model in this PEP, in that rather than
|
|
43 having the *current* program continue to run as a daemon process,
|
|
44 a service starts an *additional* process to run in the background,
|
|
45 and the current process communicates with that additional process
|
|
46 via some defined channels.
|
|
47
|
|
48 The Unix-style daemon model in this PEP can be used, among other
|
|
49 things, to implement the background-process part of a service; but
|
|
50 this PEP does not address the other aspects of setting up and
|
|
51 managing a service.
|
|
52
|
|
53 A possible starting point for such a “service” model of execution is
|
|
54 in a `message from 2009-01-30`_ to the ``python-ideas`` forum.
|
|
55
|
|
56 .. _`message from 2009-01-30`: http://mail.python.org/pipermail/python-ideas/2009-January/002606.html
|
|
57
|
|
58
|
|
59 Security
|
|
60 ========
|
|
61
|
|
62 Why is the umask set to 0 by default?
|
|
63 -------------------------------------
|
|
64
|
|
65 A daemon should not rely on the parent process's umask value, which is
|
|
66 beyond its control and may prevent creating a file with the required
|
|
67 access mode. So when the daemon context opens, the umask is set to an
|
|
68 explicit known value.
|
|
69
|
|
70 If the conventional value of 0 is too open, consider setting a value
|
|
71 such as 0o022, 0o027, 0o077, or another specific value. Otherwise,
|
|
72 ensure the daemon creates every file with an explicit access mode for
|
|
73 the purpose.
|
|
74
|
|
75
|
|
76 File descriptors
|
|
77 ================
|
|
78
|
|
79 Why does the output stop after opening the daemon context?
|
|
80 ----------------------------------------------------------
|
|
81
|
|
82 The specified behaviour in `PEP 3143`_ includes the requirement to
|
|
83 detach the process from the controlling terminal (to allow the process
|
|
84 to continue to run as a daemon), and to close all file descriptors not
|
|
85 known to be safe once detached (to ensure any files that continue to
|
|
86 be used are under the control of the daemon process).
|
|
87
|
|
88 If you want the process to generate output via the system streams
|
|
89 ‘sys.stdout’ and ‘sys.stderr’, set the ‘DaemonContext’'s ‘stdout’
|
|
90 and/or ‘stderr’ options to a file-like object (e.g. the ‘stream’
|
|
91 attribute of a ‘logging.Handler’ instance). If these objects have file
|
|
92 descriptors, they will be preserved when the daemon context opens.
|
|
93
|
|
94 How can I preserve a ‘logging’ handler's file descriptor?
|
|
95 ---------------------------------------------------------
|
|
96
|
|
97 The ‘DaemonContext.open’ method conforms to `PEP 3143`_ by closing all
|
|
98 open file descriptors, but excluding those files specified in the
|
|
99 ‘files_preserve’ option. This option is a list of files or file
|
|
100 descriptors.
|
|
101
|
|
102 The Python standard library ‘logging’ module provides log handlers
|
|
103 that write to streams, including to files via the ‘StreamHandler’
|
|
104 class and its sub-classes. The documentation (both the online `logging
|
|
105 module documentation`_ and the docstrings for the code) makes no
|
|
106 mention of a way to get at the stream associated with a handler
|
|
107 object.
|
|
108
|
|
109 However, looking at the source code for ‘StreamHandler’, in Python 2.5
|
|
110 as ``/usr/lib/python2.5/logging/__init__.py``, shows a ‘stream’
|
|
111 attribute that is bound to the stream object. The attribute is not
|
|
112 marked private (i.e. it is not named with a leading underscore), so we
|
|
113 can presume it is part of the public API.
|
|
114
|
|
115 That attribute can then be used to specify that a logging handler's
|
|
116 file descriptor should, when the ‘DaemonContext’ opens, be excluded
|
|
117 from closure::
|
|
118
|
|
119 import logging
|
|
120 import daemon
|
|
121
|
|
122 # any subclass of StreamHandler should provide the ‘stream’ attribute.
|
|
123 lh = logging.handlers.TimedRotatingFileHandler(
|
|
124 "/var/log/foo.log",
|
|
125 # …
|
|
126 )
|
|
127
|
|
128 # … do some logging and other activity …
|
|
129
|
|
130 daemon_context = daemon.DaemonContext()
|
|
131 daemon_context.files_preserve = [lh.stream]
|
|
132
|
|
133 daemon_context.open()
|
|
134
|
|
135 # … continue as a daemon process …
|
|
136
|
|
137 .. _`logging module documentation`: http://docs.python.org/library/logging
|
|
138
|
|
139
|
|
140 ..
|
|
141 This is free software: you may copy, modify, and/or distribute this work
|
|
142 under the terms of the Apache License version 2.0 as published by the
|
|
143 Apache Software Foundation.
|
|
144 No warranty expressed or implied. See the file ‘LICENSE.ASF-2’ for details.
|
|
145
|
|
146 ..
|
|
147 Local variables:
|
|
148 coding: utf-8
|
|
149 mode: text
|
|
150 mode: rst
|
|
151 time-stamp-format: "%:y-%02m-%02d"
|
|
152 time-stamp-start: "^:Updated:[ ]+"
|
|
153 time-stamp-end: "$"
|
|
154 time-stamp-line-limit: 20
|
|
155 End:
|
|
156 vim: fileencoding=utf-8 filetype=rst :
|