From a8a2a54bea4b9e05371c9cf7b885efa518318a85 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 4 Jul 2021 19:00:02 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=BB=E5=8A=A1=E6=97=A5?= =?UTF-8?q?=E5=BF=97=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=89=8B=E5=8A=A8=E5=81=9C?= =?UTF-8?q?=E6=AD=A2=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cron.ts | 3 +++ back/data/cron.ts | 2 ++ back/services/cron.ts | 47 +++++++++++++++++++++++++++----------- shell/api.sh | 14 +++++++----- shell/task.sh | 53 ++++++++++++++++++++++++++++++++++--------- shell/update.sh | 6 ++--- 6 files changed, 92 insertions(+), 33 deletions(-) diff --git a/back/api/cron.ts b/back/api/cron.ts index 5206c6b6..a4374047 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -232,6 +232,8 @@ export default (app: Router) => { body: Joi.object({ ids: Joi.array().items(Joi.string().required()), status: Joi.string().required(), + pid: Joi.string().optional(), + log_path: Joi.string().optional(), }), }), async (req: Request, res: Response, next: NextFunction) => { @@ -241,6 +243,7 @@ export default (app: Router) => { const data = await cronService.status({ ...req.body, status: parseInt(req.body.status), + pid: parseInt(req.body.pid) || '', }); return res.send({ code: 200, data }); } catch (e) { diff --git a/back/data/cron.ts b/back/data/cron.ts index 0b050355..64b9823f 100644 --- a/back/data/cron.ts +++ b/back/data/cron.ts @@ -10,6 +10,7 @@ export class Crontab { isSystem?: 1 | 0; pid?: number; isDisabled?: 1 | 0; + log_path?: string; constructor(options: Crontab) { this.name = options.name; @@ -25,6 +26,7 @@ export class Crontab { this.isSystem = options.isSystem || 0; this.pid = options.pid; this.isDisabled = options.isDisabled || 0; + this.log_path = options.log_path || ''; } } diff --git a/back/services/cron.ts b/back/services/cron.ts index 8adcfa5a..25cfcfc0 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -87,11 +87,18 @@ export default class CronService { public async status({ ids, status, + pid, + log_path, }: { ids: string[]; status: CrontabStatus; + pid: number; + log_path: string; }) { - this.cronDb.update({ _id: { $in: ids } }, { $set: { status } }); + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { status, pid, log_path } }, + ); } public async remove(ids: string[]) { @@ -158,17 +165,26 @@ export default class CronService { public async stop(ids: string[]) { return new Promise((resolve: any) => { this.cronDb.find({ _id: { $in: ids } }).exec((err, docs: Crontab[]) => { + for (const doc of docs) { + if (doc.pid) { + try { + process.kill(-doc.pid); + } catch (error) { + this.logger.silly(error); + } + } + if (doc.log_path) { + fs.appendFileSync( + `${config.logPath}${doc.log_path}`, + `\n## 执行结束... ${new Date().toLocaleString()} `, + ); + } + } this.cronDb.update( { _id: { $in: ids } }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, ); - const pids = docs - .map((x) => x.pid) - .filter((x) => !!x) - .join('\n'); - exec(`echo - e "${pids}" | xargs kill - 9`, (err) => { - resolve(); - }); + resolve(); }); }); } @@ -194,17 +210,19 @@ export default class CronService { if (cmdStr.endsWith('.js')) { cmdStr = `${cmdStr} now`; } - const cp = exec(cmdStr, (err, stdout, stderr) => { + + const cp = spawn(cmdStr, { shell: true, detached: true }); + this.cronDb.update( + { _id }, + { $set: { status: CrontabStatus.running, pid: cp.pid } }, + ); + cp.on('close', (code) => { this.cronDb.update( { _id }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, ); resolve(); }); - this.cronDb.update( - { _id }, - { $set: { status: CrontabStatus.running, pid: cp.pid } }, - ); }); } @@ -238,6 +256,9 @@ export default class CronService { public async log(_id: string) { const doc = await this.get(_id); + if (doc.log_path) { + return getFileContentByName(`${config.logPath}/${doc.log_path}`); + } const [, commandStr, url] = doc.command.split(' '); let logPath = this.getKey(commandStr); const isQlCommand = doc.command.startsWith('ql '); diff --git a/shell/api.sh b/shell/api.sh index d9bebf94..bf486612 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -148,9 +148,11 @@ get_user_info() { fi } -update_cron_status() { - local ids=$1 - local status=$2 +update_cron() { + local ids="$1" + local status="$2" + local pid="${3:-''}" + local logPath="$4" local currentTimeStamp=$(date +%s) local api=$( curl -s --noproxy "*" "http://localhost:5600/api/crons/status?t=$currentTimeStamp" \ @@ -162,15 +164,15 @@ update_cron_status() { -H "Origin: http://localhost:5700" \ -H "Referer: http://localhost:5700/crontab" \ -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \ - --data-raw "{\"ids\":[$ids],\"status\":\"$status\"}" \ + --data-raw "{\"ids\":[$ids],\"status\":\"$status\",\"pid\":\"$pid\",\"log_path\":\"$logPath\"}" \ --compressed ) code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "更新任务状态成功" + echo -e "更新任务状态成功" | tee -a $log_path else - echo -e "更新任务状态失败(${message})" + echo -e "更新任务状态失败(${message})" | tee -a $log_path fi } diff --git a/shell/task.sh b/shell/task.sh index 70d44bdd..490af7f3 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -76,7 +76,6 @@ run_normal() { local p1=$1 cd $dir_scripts define_program "$p1" - . $file_task_before if [[ $p1 == *.js ]]; then if [[ $# -eq 1 ]]; then random_delay @@ -88,13 +87,16 @@ run_normal() { log_path="$log_dir/$log_time.log" make_dir "$log_dir" - local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | xargs | sed 's/ /","/g') + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path - [[ $id ]] && update_cron_status "\"$id\"" "0" + [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" + . $file_task_before + timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path + . $file_task_after - [[ $id ]] && update_cron_status "\"$id\"" "1" + [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path @@ -113,25 +115,54 @@ run_concurrent() { local array=($(echo $envs | sed 's/&/ /g')) cd $dir_scripts define_program "$p1" + log_time=$(date "+%Y-%m-%d-%H-%M-%S") log_dir_tmp="${p1##*/}" log_dir="$dir_log/${log_dir_tmp%%.*}" + log_path="$log_dir/$log_time.log" make_dir $log_dir - log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") - echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" + + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') + local begin_time=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" + . $file_task_before + echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -a $log_path + + single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") for i in "${!array[@]}"; do export ${p3}=${array[i]} - log_path="$log_dir/${log_time}_$((i+1)).log" - timeout $command_timeout_time $which_program $p1 &>$log_path & + single_log_path="$log_dir/${single_log_time}_$((i+1)).log" + timeout $command_timeout_time $which_program $p1 &>$single_log_path & done + + . $file_task_after + [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" + local end_time=$(date '+%Y-%m-%d %H:%M:%S') + local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path } ## 运行其他命令 run_else() { local log_time=$(date "+%Y-%m-%d-%H-%M-%S") - local log_dir="$dir_log/$1" - local log_path="$log_dir/$log_time.log" + local log_dir_tmp="${1##*/}" + local log_dir="$dir_log/${log_dir_tmp%%.*}" + log_path="$log_dir/$log_time.log" make_dir "$log_dir" - timeout $command_timeout_time "$@" 2>&1 | tee $log_path + + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') + local begin_time=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" + . $file_task_before + + timeout $command_timeout_time "$@" 2>&1 | tee -a $log_path + + . $file_task_after + [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" + local end_time=$(date '+%Y-%m-%d %H:%M:%S') + local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path } ## 命令检测 diff --git a/shell/update.sh b/shell/update.sh index e598a5c9..28443695 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -72,7 +72,7 @@ del_cron() { local ids="" echo -e "开始尝试自动删除失效的定时任务...\n" for cron in $(cat $list_drop); do - local id=$(cat $list_crontab_user | grep -E "$cmd_task $cron" | perl -pe "s|.*ID=(.*) $cmd_task $cron|\1|" | xargs | sed 's/ /","/g' | head -1) + local id=$(cat $list_crontab_user | grep -E "$cmd_task $cron" | perl -pe "s|.*ID=(.*) $cmd_task $cron\.*|\1|" | head -1 | head -1 | awk -F " " '{print $1}') if [[ $ids ]]; then ids="$ids,\"$id\"" else @@ -179,7 +179,7 @@ update_raw() { echo -e "下载 ${raw_file_name} 成功...\n" cd $dir_raw local filename="raw_${raw_file_name}" - local cron_id=$(cat $list_crontab_user | grep -E "$cmd_task $filename" | perl -pe "s|.*ID=(.*) $cmd_task $filename\.*|\1|" | head -1) + local cron_id=$(cat $list_crontab_user | grep -E "$cmd_task $filename" | perl -pe "s|.*ID=(.*) $cmd_task $filename\.*|\1|" | head -1 | head -1 | awk -F " " '{print $1}') cp -f $raw_file_name $dir_scripts/${filename} cron_line=$( perl -ne "{ @@ -376,7 +376,7 @@ gen_list_repo() { filename=$(basename $file) cp -f $file $dir_scripts/${repo}_${filename} echo ${repo}_${filename} >>"$dir_list_tmp/${repo}_scripts.list" - cron_id=$(cat $list_crontab_user | grep -E "$cmd_task ${author}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|" | head -1) + cron_id=$(cat $list_crontab_user | grep -E "$cmd_task ${author}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|" | head -1 | awk -F " " '{print $1}') if [[ $cron_id ]]; then result=$(update_cron_command_api "$cmd_task ${repo}_${filename}:$cron_id") fi