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:

  1. import os, time
  2. from twisted.internet import selectreactor as bestreactor
  3. bestreactor.install()
  4.  
  5. from twisted.internet import reactor
  6.  
  7. def crontask():
  8.     open("/tmp/crontask",'ab+').write(str(time.time())+"\n")
  9.     time.sleep(2)
  10.  
  11. class App:
  12.     pidfile = "/tmp/cron.pid"
  13.  
  14.     def __init__(self):
  15.         twistd.checkPID(self.pidfile)
  16.         # checkPID 后再 daemonize,否则看不到 checkPID 向终端输出的错误报告
  17.         twistd.daemonize()
  18.         # 先 daemonize 再写 pidfile。因为写入的得是 daemonize 后的 PID
  19.         open(self.pidfile,'wb').write(str(os.getpid()))
  20.         reactor.addSystemEventTrigger('before', 'shutdown', self.shuttingDown)
  21.         cron = task.LoopingCall(crontask)
  22.         cron.start(5)
  23.  
  24.     def shuttingDown(self):
  25.         twistd.removePID(self.pidfile)
  26.  
  27. #from twisted.scripts import twistd
  28. from twisted.scripts import _twistd_unix as twistd
  29.  
  30. from twisted.internet import task
  31.  
  32. def main():
  33.     app = App()
  34.     reactor.run()
  35.  
  36. if __name__ == "__main__":
  37.     main()
Topic: 技术