#!/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

python编写agent_python实现Agent守护进程相关推荐

  1. 学习笔记(18):Python网络编程并发编程-守护进程

    立即学习:https://edu.csdn.net/course/play/24458/296429?utm_source=blogtoedu 守护进程(了解) 1.概念:守护进程是主进程在创建子进程 ...

  2. Python并发编程:多进程-守护进程

    一 守护进程 主进程创建子进程,然后将该进程设置成守护自己的进程,守护进程就好比皇帝身边的老太监,皇帝已死老太监就跟着殉葬了. 关于守护进程需要强调两点: 其一:守护进程会在主进程代码执行结束后就终止 ...

  3. python守护进程windows_如何把 python predict程序 做成 windows 守护进程

    展开全部 import os,sys,commands,time def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/n ...

  4. python中的daemon守护进程实现方法

    守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启动,在系统关闭时终止. 守护进程的特性 1.在后台运行 2.与其运行前的环境 ...

  5. linux编写守护进程

    1.实验目的 通过编写一个完整的守护进程,使读者掌握守护进程编写和调试的方法,并且进一步熟悉如何编写多进程 程序. 2.实验内容 在该实验中,读者首先建立起一个守护进程,然后在该守护进程中新建一个子进 ...

  6. python网站开发linux_使用Python编写Linux系统守护进程实例

    守护进程(daemon)是指在UNIX或其他多任务操作系统中在后台执行的电脑程序,并不会接受电脑用户的直接操控.此类程序会被以进程的形式初始化.通常,守护进程没有任何存在的父进程(即PPID=1),且 ...

  7. Linux守护进程设计规范及python实现

    http://blog.csdn.net/mr_jj_lian/article/details/7252222 守护进程 守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待 ...

  8. python3 编写守护进程程序思路

    1. fork子进程,父进程退出 通常,我们执行服务端程序的时候都会通过终端连接到服务器,成功连接后会加载shell环境,终端和shell都是进程,shell进程是终端进程的子进程,通过ps命令可以很 ...

  9. python守护进程_Python实现守护进程

    考虑如下场景:你编写了一个python服务程序,并且在命令行下启动,而你的命令行会话又被终端所控制,python服务成了终端程序的一个子进程.因此如果你关闭了终端,这个命令行程序也会随之关闭. 要使你 ...

  10. 用c语言编写linux守护进程

    2019独角兽企业重金招聘Python工程师标准>>> 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程 ...

最新文章

  1. Android日期对话框NumberPicker的用法教程
  2. recaptcha_与reCAPTCHA的Spring集成
  3. SliceProceduralMesh的使用
  4. Java中的ASCII码与Unicode码
  5. mysql回滚部分记录_MySQL事务部分回滚-回滚到指定保存点
  6. 前端周记20190211-20190215
  7. 学习SQL:INNER JOIN与LEFT JOIN
  8. Excel中的数组函数
  9. P2922 [USACO08DEC]秘密消息Secret Message
  10. 【PS】106个水彩花卉和树叶画笔
  11. 20210125比较常用的vim配置文件及说明
  12. 2022MRCTF-wp
  13. 学习嵌入式的书籍推荐,嵌入式编程入门教程学习大纲
  14. 手机wps怎么设置打印横竖_WPS表格打印预览在哪如何设置横向和纵向打印方式
  15. mongoose 之Shema
  16. 内推一定能找到工作吗?三个问题带你了解内推
  17. 零基础学习嵌入式入门以及项目实战开发【手把手教+国内独家+原创】
  18. Shell脚本循环语句及exit、continue和break用法
  19. Linux的wget命令详解
  20. UI设计都有哪些好用的设计工具

热门文章

  1. SQL Server高可用——日志传送(4-3)——使用
  2. 拉登游戏开发--分布式计算服务机客户机程序设计
  3. 如何给linux安装yum,linux如何安装yum
  4. php导入csv文件,PHP实现CSV文件的导入和导出类
  5. 事务失败返回_分布式事务有这一篇就够了!
  6. PHP 根据 搜索条件/勾选数据 分批次 处理数据
  7. 用 Python 的 selenium扩展 驱动 火狐 谷歌 浏览器
  8. java赋值两个对象数组 clone_有关java对象数组的clone问题
  9. configure: error: gperf is needed
  10. 主机名包含中文导致无法访问MAC虚拟机