Lech Karol Pawłaszek wrote:
> Hello.
>
> I'm trying to make a daemon and I want to log to a file its activity.
> I'm using logging module with a configuration file for it (loaded via
> fileConfig()).
>
> And now I want to read logging config file before daemonize the program
> because the file might not be accessible after daemonization. OTOH while
> daemonizing I am closing all opened file descriptors - including those
> opened for logging.
>
> What is the best approach to handle such situation? Should I close all
> FD before daemonizing or just forget it? Any other hints?
>
> Kind regards,
>
I use this, YMMV:
import os
import sys
import socket
#WORKDIR = "/"
def gen_name():
return sys.argv[0] + '.' + socket.gethostname() + '.' + str(os.getpid())
def daemonize(log_stdout=False, out_name=None, log_stderr=False, err_name=None):
"""
Turn current process into a daemon
"""
pid = os.fork()
if (pid == 0):
## os.chdir (workdir)
os.setsid()
maxfd = os.sysconf("SC_OPEN_MAX")
for fd in range(0, maxfd):
try:
os.close(fd)
except OSError: # ERROR (ignore)
pass
# Redirect the standard file descriptors to /dev/null.
os.open("/dev/null", os.O_RDONLY) # standard input (0)
os.open("/dev/null", os.O_RDWR) # standard output (1)
os.open("/dev/null", os.O_RDWR) # standard error (2)
if (not out_name):
out_name = gen_name() + '.out'
if (not err_name):
err_name = gen_name() + '.err'
if (log_stdout):
sys.stdout = logger (out_name)
if (log_stderr):
sys.stderr = logger (err_name)
else:
print "forked pid", pid
sys.exit (0)
import atexit
class logger (object):
def __init__ (self, name):
self.name = name # final file name
self.f = open (self.name, 'w')
atexit.register (self.__del__)
def write (self, stuff):
self.f.write (stuff)
def close (self):
self.f.close()
def flush (self):
self.f.flush()
def reopen (self):
self.f.flush()
self.f.close()
os.rename (self.name, self.name + '.old')
self.f = open (self.name, 'w')
def __del__ (self):
try:
os.remove (self.name + '.old')
except:
pass
#install handler
import signal
def handler (signum, frame):
print >> sys.stderr, "bye bye"
daemonize (log_stderr=True)
signal.signal (signal.SIGUSR1, handler)
if (__name__ == '__main__'):
## daemonize (log_stdout=True, out_name='main.out', log_stderr=True, err_name='main.err', err_maxbytes=100)
daemonize (log_stdout=True, log_stderr=True)
print "hello, this is stdout"
print "hello, this is also stdout"
print >> sys.stderr, "hello, this is stderr"
sys.stderr.reopen()
print >> sys.stderr, "stderr has been reopened"
--
http://mail.python.org/mailman/listinfo/python-list