博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python实现Agent守护进程
阅读量:5462 次
发布时间:2019-06-15

本文共 7799 字,大约阅读时间需要 25 分钟。

#!/usr/bin/env python # -*- coding: utf-8 -*- # @CreateTime    : 2018/3/6 # @Author        : ***小君哥*** # @File          : agent.py # @Software      : agent # @since         : 0.0.1 # @Desc          : Agent # @license       : Copyright (c) 2018, Inc. All rights reserved. # @Contact       : zard@sz-chunyi.com import os import sys import time import atexit import signal import psutil import logging.config sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.path.pardir)) #配置项和写log的方法,根据自己需要修改 config = Config() logging.config.fileConfig(config.logging_conf) logger = logging.getLogger("agent") class Agent:     def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null',home_dir='/', umask=022, verbose=1):         self.pidfile = pidfile         self.stdin = stdin         self.stdout = stdout         self.stderr = stderr         self.home_dir = home_dir         self.verbose = verbose  # 调试开关         self.umask = umask         self.daemon_alive = True     def init_agent(self):         try:             pid = os.fork()             if pid > 0:                 sys.exit(0)         except OSError as e:             logger.error("fork #1 failed: {} ({})".format(e.errno, e.strerror))             sys.stderr.write("fork #1 failed: {} ({})".format(e.errno, e.strerror))             sys.exit(1)         # decouple from parent environment         os.chdir(self.home_dir)         os.setsid()         os.umask(self.umask)         # do second fork         try:             pid = os.fork()             if pid > 0:                 os._exit(0)         except OSError as e:             logger.error("fork #2 failed: {} ({})".format(e.errno, e.strerror))             sys.stderr.write("fork #2 failed: {} ({})".format(e.errno, e.strerror))             sys.exit(1)         # redirect standard file descriptors         sys.stdout.flush()         sys.stderr.flush()         si = file(self.stdin, 'r')         so = file(self.stdout, 'a+')         if self.stderr:             se = file(self.stderr, 'a+', 0)         else:             se = so         os.dup2(si.fileno(), sys.stdin.fileno())         os.dup2(so.fileno(), sys.stdout.fileno())         os.dup2(se.fileno(), sys.stderr.fileno())         def sig_handler(signum, frame):             self.daemon_alive = False         signal.signal(signal.SIGTERM, sig_handler)         signal.signal(signal.SIGINT, sig_handler)         # write pidfile         atexit.register(self.delpid)         pid = str(os.getpid())         logger.info("write pid : {} to pidfile : {}".format(pid, self.pidfile))         file(self.pidfile, 'w+').write('%s\n' % pid)     # delete pid     def delpid(self):         if os.path.exists(self.pidfile):             os.remove(self.pidfile)         logger.info("do pid : {} os remove({})".format(str(os.getpid()), self.pidfile))     # start agent     def start(self):         # Check for a pidfile to see if the agnet already runs         try:             pf = file(self.pidfile, 'r')             pid = int(pf.read().strip())             pf.close()         except IOError:             pid = None         try:             if pid:                 message = "pidfile {} already exist. agent is running."                 sys.stdout.write(message.format(self.pidfile))                 sys.exit(0)             # Start the agent             self.init_agent()             self.run()         except Exception as ex:             logger.debug(ex)     def stop(self):         # stop the agent from the pidfile         try:             pf = open(self.pidfile, 'r')             pid = int(pf.read().strip())             pf.close()         except IOError:             pid = None         if not pid:             message = "pidfile {} does not exist. agnet is not running."             sys.stdout.write(message.format(self.pidfile))             if os.path.exists(self.pidfile):                 os.remove(self.pidfile)             return  # not an error in a restart         # Try killing the agent process         try:             nbocc = 0             while 1:                 logger.info("try to kill process: {}".format(str(pid)))                 os.kill(pid, signal.SIGTERM)                 time.sleep(0.1)                 nbocc = nbocc + 1                 if nbocc % 5 == 0:                     os.kill(pid, signal.SIGHUP)         except OSError as e:             err = str(e)             if err.find("No such process") > 0:                 if os.path.exists(self.pidfile):                     os.remove(self.pidfile)                     logger.info("pid : {} delete pidfile : {}".format(str(os.getpid()), self.pidfile))             else:                 print(str(err))                 sys.exit(1)     #restart agent     def restart(self):         self.stop()         self.start()     #status check     def status(self):         try:             pf = open(self.pidfile, 'r')             pid = int(pf.read().strip())             pf.close()         except IOError:             pid = None             sys.exit(2)         except SystemExit:             pid = None             sys.exit()         if psutil.pid_exists(pid):             print("process is running, pid is %s" % str(pid))             sys.exit(0)         else:             print("no such process running")             sys.exit(2)     #agent run     def run(self):         """         You should override this method when you subclass agent. It will be called after the process has been         InitAgent by start() or restart().         """
class SysUnitAgnet(Agent):     def __init__(self, pidfile):         Agent.__init__(self, pidfile)     def run(self):      #这里重载run函数实现你的具体操作         #if (psutil.__version__ < "1.2.1"):         #    logger.error("ERROR : update your psutil to a earlier version (> 1.2.1)")         #    print("ERROR : update your psutil to a earlier version (> 1.2.1)")         #    sys.exit(2)         #sys.stdout.flush()         #hostname = socket.getfqdn()         #hostip = socket.gethostbyname(hostname)         #logger.info("hostname is {}, ip is {}".format(hostname, hostip))         # my program do things
if __name__ == '__main__':   #创建pid文件和log文件,确保文件存在,不存在就创建     util.ensure_dir(config.sys_agent_pfile)     util.ensure_dir(config.agent_log_fname)   #实例化一个agent     sysagent = SysUnitAgnet(config.sys_agent_pfile)     if len(sys.argv) == 3:         if 'sys' == sys.argv[1]:             if 'start' == sys.argv[2]:                 sysagent.start()             elif 'stop' == sys.argv[2]:                 sysagent.stop()             elif 'status' == sys.argv[2]:                 sysagent.status()             elif 'restart' == sys.argv[2]:                 sysagent.restart()             else:                 print("Unknown command")                 sys.exit(2)         elif 'all' == sys.argv[1]:             if 'start' == sys.argv[2]:                 tsy = Thread(target=sysagent.start)                 #多个agnet实例时可以依次添加                 for t in [tsy]:                     t.start()             elif 'stop' == sys.argv[2]:                 tsy = Thread(target=sysagent.stop)                 for t in [tsy]:                     t.start()             elif 'status' == sys.argv[2]:                 tsy = Thread(target=sysagent.status)                 for t in [tsy]:                     t.start()             elif 'restart' == sys.argv[2]:                 tsy = Thread(target=sysagent.restart)                 for t in [tsy]:                     t.start()             else:                 print("Unknown command")                 sys.exit(2)         else:             print("Unknown command")             sys.exit(2)     else:         print("usage: %s %s start|stop|restart|status" % (sys.argv[0],'sys|swift|task|all'))         sys.exit(2) 保存后在命令行执行:python *.py sys start

转载于:https://www.cnblogs.com/chmyee/p/9205102.html

你可能感兴趣的文章
快速傅里叶变换模块(fft)
查看>>
随机数模块(random)
查看>>
杂项功能(排序/插值/图像/金融相关)
查看>>
pandas核心
查看>>
线性回归
查看>>
机器学习学习索引
查看>>
多项式回归
查看>>
Python-字符串
查看>>
MySQL8.0安装以及介绍(二进制)
查看>>
MySQL权限系统
查看>>
Python-集合
查看>>
转:标签中的href如何调用js
查看>>
CrawlSpiders简介
查看>>
面向对象编程
查看>>
django-rest-framework 视图的使用规则 总结分享
查看>>
drf 访问文档出现错误'AutoSchema' object has no attribute 'get_link'
查看>>
django-rest-framwork 错误信息整理
查看>>
第一讲 评估类模型之层次分析法
查看>>
评估类模型之优劣解距离法Topsis模型
查看>>
MNIST 数据集介绍
查看>>