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