本文目录导读:

我来为你提供几种不同场景下的任务超时告警脚本方案。
基础Shell脚本方案
通用任务超时监控
#!/bin/bash
# 任务超时告警脚本
# usage: ./timeout_monitor.sh "command" timeout_seconds
COMMAND="$1"
TIMEOUT=${2:-300} # 默认5分钟
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/timeout_alerts.log"
# 执行命令并获取PID
eval "$COMMAND" &
PID=$!
START_TIME=$(date +%s)
# 监控循环
while kill -0 $PID 2>/dev/null; do
CURRENT_TIME=$(date +%s)
ELAPSED=$((CURRENT_TIME - START_TIME))
if [ $ELAPSED -gt $TIMEOUT ]; then
# 超时告警
ALERT_MSG="任务超时告警
时间: $(date)
命令: $COMMAND
PID: $PID
超时时间: ${TIMEOUT}秒
实际运行: ${ELAPSED}秒
主机: $(hostname)"
# 记录日志
echo "$ALERT_MSG" >> "$LOG_FILE"
# 发送邮件告警
echo "$ALERT_MSG" | mail -s "任务超时告警 - $(hostname)" "$ALERT_EMAIL"
# 可选:杀死超时任务
# kill -9 $PID
exit 1
fi
sleep 5
done
# 任务正常完成
echo "任务在超时时间内完成" >> "$LOG_FILE"
带重试机制的脚本
#!/bin/bash
# 带重试的超时监控脚本
RETRY_COUNT=3
RETRY_DELAY=60 # 重试间隔(秒)
TIMEOUT=600 # 单个任务超时(秒)
execute_with_timeout() {
local command="$1"
local timeout=$2
local attempt=1
while [ $attempt -le $RETRY_COUNT ]; do
echo "开始第 $attempt 次执行: $command"
# 在后台执行命令
eval "$command" &
local cmd_pid=$!
# 监控超时
local elapsed=0
while kill -0 $cmd_pid 2>/dev/null; do
if [ $elapsed -ge $timeout ]; then
# 超时处理
send_alert "FAILED" "任务超时" "$command" $attempt
kill -9 $cmd_pid 2>/dev/null
if [ $attempt -lt $RETRY_COUNT ]; then
echo "等待 $RETRY_DELAY 秒后重试..."
sleep $RETRY_DELAY
fi
break
fi
sleep 1
((elapsed++))
done
# 检查是否成功完成
wait $cmd_pid
if [ $? -eq 0 ]; then
echo "任务执行成功"
return 0
fi
((attempt++))
done
send_alert "FAILED" "所有重试失败" "$command" $RETRY_COUNT
return 1
}
send_alert() {
local status=$1
local reason=$2
local command=$3
local attempt=$4
echo "发送告警: $status - $reason"
# 这里实现实际的告警通知(邮件、短信、webhook等)
}
多任务并行监控脚本
#!/bin/bash
# 多任务并行超时监控
declare -A TASKS
TASKS["备份任务"]="backup_script.sh"
TASKS["数据处理"]="data_process.py"
TASKS["报表生成"]="report_gen.sh"
TIMEOUT=300 # 5分钟
ALERT_WEBHOOK="https://hooks.slack.com/services/xxx"
monitor_task() {
local task_name=$1
local command=$2
local timeout=$3
# 执行任务
eval "$command" &
local pid=$!
local start_time=$(date +%s)
while kill -0 $pid 2>/dev/null; do
local current_time=$(date +%s)
local elapsed=$((current_time - start_time))
if [ $elapsed -gt $timeout ]; then
# 超时告警
local message="{\"text\":\"任务超时告警\n任务: $task_name\n超时: ${timeout}s\n实际: ${elapsed}s\"}"
curl -X POST -H 'Content-type: application/json' --data "$message" $ALERT_WEBHOOK
kill -9 $pid 2>/dev/null
return 1
fi
sleep 2
done
wait $pid
local exit_code=$?
if [ $exit_code -eq 0 ]; then
echo "任务 $task_name 完成"
else
echo "任务 $task_name 失败 (退出码: $exit_code)"
fi
return $exit_code
}
# 并行监控所有任务
for task in "${!TASKS[@]}"; do
monitor_task "$task" "${TASKS[$task]}" $TIMEOUT &
done
# 等待所有任务完成
wait
echo "所有任务监控完成"
Python版本(更灵活)
#!/usr/bin/env python3
import subprocess
import time
import threading
import logging
from datetime import datetime
class TaskTimeoutMonitor:
def __init__(self, command, timeout=300, alert_callback=None):
self.command = command
self.timeout = timeout
self.alert_callback = alert_callback
self.process = None
self.start_time = None
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('task_monitor.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def run(self):
"""执行任务并监控超时"""
self.start_time = time.time()
try:
# 启动进程
self.process = subprocess.Popen(
self.command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# 创建超时监控线程
monitor_thread = threading.Thread(target=self._monitor_timeout)
monitor_thread.daemon = True
monitor_thread.start()
# 等待进程完成
stdout, stderr = self.process.communicate()
if self.process.returncode == 0:
self.logger.info(f"任务完成: {self.command}")
return True
else:
self.logger.error(f"任务失败: {stderr.decode()}")
return False
except Exception as e:
self.logger.error(f"执行异常: {str(e)}")
return False
def _monitor_timeout(self):
"""监控超时"""
while self.process and self.process.poll() is None:
elapsed = time.time() - self.start_time
if elapsed > self.timeout:
self._handle_timeout(elapsed)
break
time.sleep(1)
def _handle_timeout(self, elapsed):
"""处理超时"""
alert_info = {
'command': self.command,
'timeout': self.timeout,
'elapsed': elapsed,
'pid': self.process.pid,
'timestamp': datetime.now().isoformat(),
'host': subprocess.getoutput('hostname')
}
self.logger.warning(f"任务超时: {alert_info}")
# 终止进程
self.process.kill()
# 调用告警回调
if self.alert_callback:
self.alert_callback(alert_info)
# 使用示例
def send_alert(alert_info):
"""发送告警(示例)"""
print(f"发送告警: {alert_info}")
# 这里可以集成邮件、短信、企业微信等
if __name__ == "__main__":
monitor = TaskTimeoutMonitor(
command="sleep 400", # 测试命令
timeout=300, # 5分钟超时
alert_callback=send_alert
)
monitor.run()
告警通知函数示例
#!/bin/bash
# 多种告警方式
# 邮件告警
send_email_alert() {
local subject="$1"
local body="$2"
local recipient="admin@company.com"
echo "$body" | mail -s "$subject" "$recipient"
}
# 企业微信/钉钉机器人告警
send_webhook_alert() {
local message="$1"
local webhook_url="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
curl -s -X POST "$webhook_url" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$message\"}}"
}
# 短信告警(使用第三方API)
send_sms_alert() {
local message="$1"
local phone="13800138000"
# 使用阿里云、腾讯云等短信服务
curl -s "https://sms.xxx.com/send" \
-d "phone=$phone&message=$message"
}
# 综合告警
send_alert() {
local level=$1 # INFO, WARNING, CRITICAL
local task_name=$2
local detail=$3
local alert_message="[${level}] 任务超时告警
任务名称: $task_name
详情: $detail
时间: $(date '+%Y-%m-%d %H:%M:%S')
主机: $(hostname)"
# 根据级别选择通知方式
case $level in
"CRITICAL")
send_email_alert "严重告警: $task_name" "$alert_message"
send_sms_alert "$alert_message"
;;
"WARNING")
send_email_alert "警告: $task_name" "$alert_message"
send_webhook_alert "$alert_message"
;;
"INFO")
send_webhook_alert "$alert_message"
;;
esac
}
使用建议
- 设置合理的超时阈值:根据任务历史执行时间分析
- 分级告警:不同的超时级别使用不同的通知方式
- 日志记录:保存详细的执行记录便于排查
- 重试机制:对于临时性问题,加入自动重试
- 资源清理:超时后确保正确清理临时文件和进程
选择适合你场景的方案,建议先从简单的Shell脚本开始,逐步增加功能。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播