twisted 简单的 daemonize,以及 cron 功能的实现

年前系统监控脚本已经写好了,同事实现了检查 resin 状态和 https 用户口令校验,出状况则短信通知... 春节期间一直没有收到报警短信 :)

但还是比较粗糙,比如脚本是要依赖 nohup 启动的,想起以前写 echo server 的时候曾考察过 daemonize ,于是把代码抄来试试

结果发现直接 copy 过来的东东在 twisted 2.5 下不能运行。追踪了一下,发现是不知道从什么版本开始完善了对 win32 平台的支持,它将原来 twistd 的东西又封装了一遍。现在把 "from twisted.scripts import twistd" 这行改成 "from twisted.scripts import _twistd_unix as twistd" 就好了。

另外貌似 twisted 并不推荐这种直接初始化 App() 的方法,而是用 twistd 程序来启动 app,回头需要再学习学习..

顺便又了解一下怎么实现一个简单的 cron,发现可以用 twisted.internet.task 封装的 LoopingCall 来完成,核心应该算是一个叫 callLater 的东东。

Sample:

import os, time
from twisted.internet import selectreactor as bestreactor
bestreactor.install()
 
from twisted.internet import reactor
 
def crontask():
    open("/tmp/crontask",'ab+').write(str(time.time())+"\n")
    time.sleep(2)
 
class App:
    pidfile = "/tmp/cron.pid"
 
    def __init__(self):
        twistd.checkPID(self.pidfile)
        # checkPID 后再 daemonize,否则看不到 checkPID 向终端输出的错误报告
        twistd.daemonize()
        # 先 daemonize 再写 pidfile。因为写入的得是 daemonize 后的 PID
        open(self.pidfile,'wb').write(str(os.getpid()))
        reactor.addSystemEventTrigger('before', 'shutdown', self.shuttingDown)
        cron = task.LoopingCall(crontask)
        cron.start(5)
 
    def shuttingDown(self):
        twistd.removePID(self.pidfile)
 
#from twisted.scripts import twistd
from twisted.scripts import _twistd_unix as twistd
 
from twisted.internet import task
 
def main():
    app = App()
    reactor.run()
 
if __name__ == "__main__":
    main()