~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import with_statement
import logging
import logging.handlers
import daemon
import daemon.pidlockfile
import sys
logger = logging.getLogger("DaemonLog")
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s
- %(message)s")
handler = logging.FileHandler("log.file")
logger.addHandler(handler)
pid = daemon.pidlockfile.TimeoutPIDLockFile("/var/run/daemontest.pid",
10)
with daemon.DaemonContext(pidfile=pid, gid=0, uid=0,
stdout=sys.stdout, stderr=sys.stderr):
logger.info("POO")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I get the following traceback:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[seans_imac:~/Downloads] halfitalian% Traceback (most recent call
last):
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/logging/__init__.py", line 753, in emit
self.flush()
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/logging/__init__.py", line 731, in flush
self.stream.flush()
IOError: [Errno 9] Bad file descriptor
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/logging/__init__.py", line 1355, in shutdown
h.close()
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/logging/__init__.py", line 784, in close
self.stream.close()
IOError: [Errno 9] Bad file descriptor
Error in sys.exitfunc:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/logging/__init__.py", line 1355, in shutdown
h.close()
File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/logging/__init__.py", line 784, in close
self.stream.close()
IOError: [Errno 9] Bad file descriptor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Any advice? Also, I left in the call to TimeoutPIDLockfile() as well,
because the library's documentation is pretty sparse, and I want to
know if I'm using it properly.
Thanks in advance.
~Sean
Got it! The DaemonContext closes all open file descriptors, including
the one inside the logging handler. I got it to work by passing the
logger's file handle in with the "preserve_files" option.
~Sean
Beautiful.
If anyone would like to write a new user's guide for ‘python-daemon’ (in
reStructuredText format), I'd appreciate it.
If you want to take advantage of distributed VCS, the Bazaar repository
for the project is online; here's how to get a branch:
$ bzr version
Bazaar (bzr) 2.0.2
[…]
$ bzr branch http://bzr.debian.org/bzr/python-daemon/python-daemon.devel/
$ cd python-daemon.devel/
Then you can hack away and commit, and use ‘bzr send’ to send your
changes to me.
--
\ “Think for yourselves and let others enjoy the privilege to do |
`\ so too.” —Voltaire, _Essay On Tolerance_ |
_o__) |
Ben Finney
> I'm finally getting around to trying out the python-daemon module and
> have hit a wall. I'm trying to set up logging inside of the "with
> daemon.DaemonContext" block. But when I try to use a logger inside
> the block it throws an error:
Specifically, it's throwing an error because a logger set up *outside*
the context is no longer open *inside* the context.
[…]
> handler = logging.FileHandler("log.file")
> logger.addHandler(handler)
>
> pid = daemon.pidlockfile.TimeoutPIDLockFile("/var/run/daemontest.pid",
> 10)
>
> with daemon.DaemonContext(pidfile=pid, gid=0, uid=0,
> stdout=sys.stdout, stderr=sys.stderr):
> logger.info("POO")
Here, the daemon.DaemonContext has not been told to preserve the file
descriptor that was opened by ‘handler’; so that file descriptor gets
closed along with all the others when the DaemonContext opens.
Also, there's no point binding the ‘stdout’ and ‘stderr’ options to the
system streams as you've done: as the documentation specifies, becoming
a daemon process involves detaching from the controlling terminal, so
those streams will no longer be connected to anything.
If you want specific file descriptors to remain open, you need to tell
the DaemonContext which ones they are via the ‘files_preserve’ option:
#! /usr/bin/python
# -*- coding: utf-8; -*-
from __future__ import with_statement
import logging
import daemon
import daemon.pidlockfile
import sys
logger = logging.getLogger("DaemonLog")
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.FileHandler("log.file")
logger.addHandler(handler)
pid = daemon.pidlockfile.TimeoutPIDLockFile(
"/tmp/dizazzo-daemontest.pid", 10)
daemon_context = daemon.DaemonContext(
pidfile=pid,
files_preserve=[handler.stream])
with daemon_context:
logger.info("POO")
Thanks for this question; it's now in the FAQ document for the next
version.
> Any advice? Also, I left in the call to TimeoutPIDLockfile() as well,
> because the library's documentation is pretty sparse, and I want to
> know if I'm using it properly.
Improvements to the documentation would be welcome, certainly.
--
\ “We now have access to so much information that we can find |
`\ support for any prejudice or opinion.” —David Suzuki, 2008-06-27 |
_o__) |
Ben Finney