在一些情况下,为了保证业务的正常执行,某些服务必须在指定的时间内执行,比如备份的服务等,可能只能在晚上执行,超过一定时间,就必须停止,不能影响正常业务。
# -*- coding: utf-8 -*-
import os
import time
import sys
import datetime
import traceback
import tempfile
import subprocess
import shlex
import logging
COMMAND_PID_ROOT_PATH = os.path.join(tempfile.gettempdir(),"command_pids")
def get_log(file_name):
LOG_DIR = "/var/log/test/" #正式通讯服务端日志目录
if os.name != "posix":
LOG_DIR = os.path.split(os.path.abspath(os.path.dirname(__file__)))[0]
if not os.path.exists(LOG_DIR):
os.mkdir(LOG_DIR)
path = os.path.join(LOG_DIR,file_name)
logger = logging.getLogger()
hdlr = logging.FileHandler(path)
formatter = logging.Formatter('%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.NOTSET)
return logger
logger = get_log("guard_process.log")
TIMEOUT_COUNT = 5*60 #设置默认超时时间,单位秒
u"""
调用方式:
flock -xn /tmp/test.lock -c 'python /var/www/guard_process.py "python /var/www/test/test2.py ok" 1800'
"""
if __name__ == "__main__":
args = shlex.split(sys.argv[1])
if len(sys.argv) >=3: #超时时间也可以传递进来
TIMEOUT_COUNT = int(sys.argv[2])
child = subprocess.Popen(args)
start_time = time.time()
while True:
is_end = child.poll()
end_time = time.time()
if is_end == 0: #子进程正常结束
logger.info(
"args='{args}' normal end pid='{pid}'".format(
args=args,
pid=child.pid,
)
)
break
elif (end_time - start_time)>TIMEOUT_COUNT: #超时
logger.info(
"args='{args}' timeout kill child pid='{pid}'".format(
args=args,
pid=child.pid,
)
)
child.kill()
break
else:
time.sleep(3)
logger.info("args='{args}' ending".format(args = args))