Skip to content

Python:daemon

PEP-3143

PEP-3143에서 Richard Stevens의 Unix Network Programming를 인용하여 unix daemon의 조건을 다음과 같이 언급하고 있다.

  • 열려있는 모든 File descriptor를 닫는다.
  • 현재 작업 디렉토리를 변경한다
  • 파일 생성시 마스크를 재설정한다
  • 백그라운드로 실행된다
  • 프로세스 그룹에서 분리한다
  • 터미널의 I/O 시그널을 무시한다
  • 제어 터미널과 분리한다
  • 다음과 같은 상황을 올바르게 다룰수 있다
  • System V init 프로세스에 의해 시작된다.
    • SIGTERM 시그널에 의해 종료된다
    • 자식 프로세스는 SIGCLD 시그널을 발생시킨다

How to install

$ sudo apt-get install python-daemon

Example

# To kick off the script, run the following from the python directory:
#   PYTHONPATH=`pwd` python testdaemon.py start

#standard python libs
import logging
import time

#third party libs
from daemon import runner

class App():

    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/var/run/testdaemon/testdaemon.pid'
        self.pidfile_timeout = 5

    def run(self):
        while True:
            #Main code goes here ...
            #Note that logger level needs to be set to logging.DEBUG before this shows up in the logs
            logger.debug("Debug message")
            logger.info("Info message")
            logger.warn("Warning message")
            logger.error("Error message")
            time.sleep(10)

app = App()
logger = logging.getLogger("DaemonLog")
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.FileHandler("/var/log/testdaemon/testdaemon.log")
handler.setFormatter(formatter)
logger.addHandler(handler)

daemon_runner = runner.DaemonRunner(app)
#This ensures that the logger file handle does not get closed during daemonization
daemon_runner.daemon_context.files_preserve=[handler.stream]
daemon_runner.do_action()

/etc/init.d/testdaemon:

#! /bin/bash
# Copyright (c) 1996-2012 My Company.
# All rights reserved.
#
# Author: Bob Bobson, 2012
#
# Please send feedback to [email protected]
#
# /etc/init.d/testdaemon
#
### BEGIN INIT INFO
# Provides: testdaemon
# Required-Start: 
# Should-Start: 
# Required-Stop: 
# Should-Stop:
# Default-Start:  3 5
# Default-Stop:   0 1 2 6
# Short-Description: Test daemon process
# Description:    Runs up the test daemon process
### END INIT INFO

# Activate the python virtual environment
    . /path_to_virtualenv/activate

case "$1" in
  start)
    echo "Starting server"
    # Start the daemon 
    python /usr/share/testdaemon/testdaemon.py start
    ;;
  stop)
    echo "Stopping server"
    # Stop the daemon
    python /usr/share/testdaemon/testdaemon.py stop
    ;;
  restart)
    echo "Restarting server"
    python /usr/share/testdaemon/testdaemon.py restart
    ;;
  *)
    # Refuse to do other stuff
    echo "Usage: /etc/init.d/testdaemon.sh {start|stop|restart}"
    exit 1
    ;;
esac

exit 0

See also

Favorite site

Other implementation