python-daemon: 實現python後臺程式的工具
阿新 • • 發佈:2018-12-10
簡介
python-daemon實現Unix守護程序。 參考: 瞭解更多
該庫實現了PEP 3143“標準守護程序庫”的良好行為守護程序規範。
DaemonContext例項儲存程式的行為和配置的程序環境。
快速入門
import time # 資料學習交流群 QQ 519970686 # with daemon.DaemonContext(): f = open("/tmp/test.log",'w') while True: f.write(''' Library to implement a well-behaved Unix daemon process. This library implements the well-behaved daemon specification of PEP 3143, “Standard daemon process library”. A well-behaved Unix daemon process is tricky to get right, but the required steps are much the same for every daemon program. A DaemonContext instance holds the behaviour and configured process environment for the program; use the instance as a context manager to enter a daemon state. ''') f.write("{0}\n".format(time.ctime(time.time()))) time.sleep(1)
執行:
$ python3 daemon1.py $ tail -f /tmp/test.log This library implements the well-behaved daemon specification of PEP 3143, “Standard daemon process library”. A well-behaved Unix daemon process is tricky to get right, but the required steps are much the same for every daemon program. A DaemonContext instance holds the behaviour and configured process environment for the program; use the instance as a context manager to enter a daemon state. Thu Feb 8 14:21:43 2018 $ ps afx | grep -i daemon1 8646 pts/2 S+ 0:00 | \_ grep --color=auto -i daemon1 8640 ? S 0:00 \_ python3 daemon1.py $ kill -9 8640
要想停止上述程序,可以通過ps查詢到程序號,然後kill。
注意上述程式碼在python2沒有任何問題,不過在python需要修改庫檔案runner.py開啟檔案的方式。
# vi /usr/local/lib/python3.5/dist-packages/daemon/runner.py # 118 -120 self.daemon_context = DaemonContext() self.daemon_context.stdin = open(app.stdin_path, 'wb+',buffering=0) self.daemon_context.stdout = open(app.stdout_path, 'wb+',buffering=0) self.daemon_context.stderr = open( app.stderr_path, 'wb+', buffering=0)
更實用的例子
import time
import logging
import logging.handlers
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 = '/tmp/foo.pid'
self.pidfile_timeout = 5
def run(self):
logs = logging.getLogger('MyLogger')
logs.setLevel(logging.DEBUG)
fh = logging.handlers.RotatingFileHandler(
'/tmp/test.log',maxBytes=10000000,backupCount=5)
fh.setLevel(logging.DEBUG)
formatter = logging.Formatter(u'%(asctime)s [%(levelname)s] %(message)s')
fh.setFormatter(formatter)
logs.addHandler(fh)
while True:
for i in range(10):
logs.info("Beginning Scan {0}! \n".format(i))
time.sleep(1)
app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()
執行:
$ python2 daemon2.py
usage: daemon2.py start|stop|restart
$ python3 daemon2.py start
[email protected]:~/code/python-chinese-library/libraries/daemon$
[email protected]:~/code/python-chinese-library/libraries/daemon$ Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/lockfile/pidlockfile.py", line 77, in acquire
write_pid_to_pidfile(self.path)
File "/usr/local/lib/python3.5/dist-packages/lockfile/pidlockfile.py", line 161, in write_pid_to_pidfile
pidfile_fd = os.open(pidfile_path, open_flags, open_mode)
FileExistsError: [Errno 17] File exists: '/tmp/foo.pid'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "daemon2.py", line 39, in <module>
daemon_runner.do_action()
File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 274, in do_action
func(self)
File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 182, in _start
self.daemon_context.open()
File "/usr/local/lib/python3.5/dist-packages/daemon/daemon.py", line 389, in open
self.pidfile.__enter__()
File "/usr/local/lib/python3.5/dist-packages/lockfile/__init__.py", line 197, in __enter__
self.acquire()
File "/usr/local/lib/python3.5/dist-packages/daemon/pidfile.py", line 60, in acquire
super(TimeoutPIDLockFile, self).acquire(timeout, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/lockfile/pidlockfile.py", line 85, in acquire
self.path)
lockfile.LockTimeout: Timeout waiting to acquire lock for /tmp/foo.pid
[email protected]:~/code/python-chinese-library/libraries/daemon$ python3 daemon2.py stop
Terminating on signal 15
[email protected]:~/code/python-chinese-library/libraries/daemon$ python3 daemon2.py stop
Traceback (most recent call last):
File "daemon2.py", line 39, in <module>
daemon_runner.do_action()
File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 274, in do_action
func(self)
File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 224, in _stop
raise error
daemon.runner.DaemonRunnerStopFailureError: PID file '/tmp/foo.pid' not locked
注意上面的錯誤是重複啟動或者停止時程序並不存在導致的。