在一些情況下,爲了保證業務的正常執行,某些服務必須在指定的時間內執行,比如備份的服務等,可能只能在晚上執行,超過一定時間,就必須停止,不能影響正常業務。
# -*- 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))