Skip to content

Python daemonizer for Unix, Linux and OS X

License

Notifications You must be signed in to change notification settings

cnobile2012/python-daemon

 
 

Repository files navigation

Python Daemonizer Class

License Build Status Test Coverage

License: Creative Commons

Overview

This is a Python class that will daemonize your Python code so it can continue running in the background. It works on Unix and Linux systems. It creates a PID file that is controlled by system file locks so the need to remove a stale pid file is not necessary.

The Daemon class will write to a log file if you set one up. Any code that uses the Daemon class can also write to the same log file making it easy to have a combined log.

The Daemon class has standard start, stop, restart commands plus a foreground mode. This current version no longer supports Python 2. This code may still support OSX but since I don't have a machine that runs OSX I cannot test it.

This code is based on the original version from jejik.com.

Usage

Define a class which inherits from Daemon and has a run() method which is what will be called once the daemonization is completed.

from daemonize import Daemon

class MyDaemon(Daemon):

    def run(self, *args, **kwards):
        # Do stuff

    def stop_callback(self):
        # Do anything you need to do before a signal shuts
        # down your daemon.

A while loop set to True will usually work fine in the run() method or you could use something more sophisticated as mentioned below in the last paragraph under Continuous Execution.

There is also a stop_callback method that can be overridden in your sub-class to the Daemon class. It gives your daemon the ability to perform certain tasks before a shutdown is performed, like closing files etc.

Create a new object of your class, specifying where you want your PID file to exist:

md = MyDaemon('/path/to/pid.pid')
md.start()

There are a lot of arguments that can be used in the constructor of the Daemon class.

Positional Arguments

  • pidfile: Mandatory fullpath including file name of the pid file.

Keyword Arguments

  • stdin: The input data stream, defaults to os.devnull.
  • stdout: The output data stream, defaults to os.devnull.
  • stderr: The error data stream, defaults to os.devnull.
  • base_dir: The absolute or relative path to the directory that will be used after the process is detached from the terminal, defaults to '.' (current working directory).
  • umask: The mask used for any files created by the daemon, defaults to 0o22.
  • verbose: The default logging level. The values 1 = INFO, 2 = DEBUG, 3 = ERROR, and any number (other than 1, 2, 3) = WARNING, defaults to 1.
  • use_gevent: Use gevent to handle the killing of the daemon, defaults to False.
  • logger_name: The logger name used for logging, defaults to '' (the root logger).

Run Actions

  1. start() -- Starts the daemon (creates PID and daemonizes).
  2. stop() -- Stops the daemon (stops the child process and removes the PID).
  3. restart() -- Does a stop() and then start().

To start, restart, and stop the test daemon that is at the end of the daemonize/daemon.py code see below. Just substitute your code for the code below.

$ ps -ajx | grep daemonize/daemon | grep -v grep # No daemon running
$ python daemonize/daemon.py start
$ ps -ajx | grep daemonize/daemon | grep -v grep
PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
   1  425677  425676  425676 ?             -1 S     1000   0:00 python daemonize/daemon.py start
$ python daemonize/daemon.py restart
$ ps -ajx | grep daemonize/daemon | grep -v grep
PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
   1  425823  425822  425822 ?             -1 S     1000   0:00 python daemonize/daemon.py restart
$ python daemonize/daemon.py stop
$ ps -ajx | grep daemonize/daemon | grep -v grep # No daemon running

Foreground

This is useful for debugging because you can start the code without making it a daemon. The running script then depends on the open shell like any normal Python script.

To do this, just call the run() method directly.

md = MyDaemon('/path/to/pid.pid')
md.run()

Continuous Execution

The run() method will be executed just once so if you want the daemon to be doing stuff continuously you may wish to use the [1] sched module to execute code repeatedly [2] example or just use a while True.

Footnotes

[1]http://docs.python.org/library/sched.html
[2]https://github.com/serverdensity/sd-agent/blob/master/agent.py#L339

About

Python daemonizer for Unix, Linux and OS X

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 90.9%
  • Makefile 7.4%
  • Shell 1.7%