每日备份 2026-06-10 12:57:13
This commit is contained in:
1 parent
fda2ccb8c2
commit
3d2e638c6a
244 files changed
+58890
-3
No files matched your search
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
# 2号机: 添加学习任务到青龙任务队列
|
||||
|
||||
QUEUE_FILE="/root/.openclaw/workspace/memory/task_queue.txt"
|
||||
|
||||
usage() {
|
||||
echo "用法: $0 <主题> <类型> [数量] [时间]"
|
||||
echo " 主题: 学习主题关键词"
|
||||
echo " 类型: article(文章) / novel(小说) / stock(股票)"
|
||||
echo " 数量: 默认 3"
|
||||
echo " 时间: 执行时间 (默认: 下一小时整点)"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 '机器学习' article 5"
|
||||
echo " $0 'AAPL' stock 1 '2026-02-07T09:00:00'"
|
||||
}
|
||||
|
||||
# 参数
|
||||
TOPIC="$1"
|
||||
TYPE="${2:-article}"
|
||||
COUNT="${3:-3}"
|
||||
TIME="${4:-}"
|
||||
|
||||
if [ -z "$TOPIC" ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 默认时间: 下一小时整点
|
||||
if [ -z "$TIME" ]; then
|
||||
TIME=$(date -d "+1 hour" '+%Y-%m-%dT%H:00:00')
|
||||
fi
|
||||
|
||||
# 格式验证
|
||||
if ! [[ "$TIME" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$ ]]; then
|
||||
echo "✗ 时间格式错误,应为: YYYY-MM-DDTHH:MM:SS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 添加任务
|
||||
echo "$TIME|$TOPIC|$TYPE|$COUNT" >> "$QUEUE_FILE"
|
||||
|
||||
echo "✅ 任务已添加"
|
||||
echo ""
|
||||
echo "任务队列: $QUEUE_FILE"
|
||||
echo "执行时间: $TIME"
|
||||
echo "主题: $TOPIC"
|
||||
echo "类型: $TYPE"
|
||||
echo "数量: $COUNT"
|
||||
echo ""
|
||||
echo "要查看队列吗? (cat $QUEUE_FILE)"
|
||||
Executable
+212
@@ -0,0 +1,212 @@
|
||||
#!/bin/bash
|
||||
# 1号机学习工作流 v3.0
|
||||
# 完整流程: 搜索 → 学习 → 分析 → 总结 → 内化
|
||||
|
||||
LEARNING_DIR="/root/.openclaw/workspace/memory"
|
||||
BRAVE_API_KEY="BSAPuOacSUCIDGzg53VSPTcMQI_p0_G"
|
||||
DATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
echo "=== 1号机学习任务开始 ==="
|
||||
echo "时间: $DATE"
|
||||
echo ""
|
||||
|
||||
# ========================
|
||||
# Brave 搜索函数
|
||||
# ========================
|
||||
brave_search() {
|
||||
local query="$1"
|
||||
local count="${2:-5}"
|
||||
|
||||
echo "🔍 搜索: $query"
|
||||
|
||||
local response
|
||||
response=$(curl -s -H "X-Subscription-Token: $BRAVE_API_KEY" \
|
||||
"https://api.search.brave.com/res/v1/web/search?q=$(echo "$query" | tr ' ' '+')&count=$count")
|
||||
|
||||
if [ -z "$response" ]; then
|
||||
echo " ✗ 搜索失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 提取 URL
|
||||
local urls
|
||||
urls=$(echo "$response" | grep -oE '"url":"[^"]+"' | sed 's/"url":"//;s/"$//' | head -"$count")
|
||||
|
||||
if [ -z "$urls" ]; then
|
||||
echo " ✗ 未找到结果"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo " ✓ 找到 $(echo "$urls" | wc -l) 个结果"
|
||||
echo "$urls"
|
||||
}
|
||||
|
||||
# ========================
|
||||
# 学习 + 分析函数
|
||||
# ========================
|
||||
learn_and_analyze() {
|
||||
local topic="$1"
|
||||
local category="$2" # article / novel / stock
|
||||
local url="$3"
|
||||
local output_dir="$LEARNING_DIR/$category"
|
||||
|
||||
echo " 📚 学习: $url"
|
||||
|
||||
mkdir -p "$output_dir/completed"
|
||||
|
||||
# 获取内容
|
||||
local content
|
||||
content=$(curl -s "$url" 2>/dev/null)
|
||||
|
||||
if [ -z "$content" ]; then
|
||||
echo " ✗ 获取失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local output_file="$output_dir/completed/$(echo "$url" | md5sum | cut -d' ' -f1).md"
|
||||
|
||||
# 生成分析报告
|
||||
{
|
||||
echo "# $url"
|
||||
echo "主题: $topic"
|
||||
echo "分类: $category"
|
||||
echo "学习时间: $DATE"
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "## 📝 原文内容"
|
||||
echo ""
|
||||
echo "$content"
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "## 🧠 分析总结"
|
||||
echo ""
|
||||
echo "### 核心观点"
|
||||
echo "- "
|
||||
echo ""
|
||||
echo "### 关键要点"
|
||||
echo "- "
|
||||
echo ""
|
||||
echo "### 启发思考"
|
||||
echo "- "
|
||||
echo ""
|
||||
echo "### 与已有知识的关联"
|
||||
echo "- "
|
||||
echo ""
|
||||
echo "### 可应用场景"
|
||||
echo "- "
|
||||
echo ""
|
||||
echo "## 📚 内化笔记"
|
||||
echo ""
|
||||
echo "用自己的话复述:"
|
||||
echo ""
|
||||
echo "---"
|
||||
echo "学习完成: $DATE"
|
||||
} >> "$output_file"
|
||||
|
||||
echo " ✓ 完成: $(basename "$output_file")"
|
||||
}
|
||||
|
||||
# ========================
|
||||
# 股票特殊处理
|
||||
# ========================
|
||||
analyze_stock() {
|
||||
local symbol="$1"
|
||||
local output_dir="$LEARNING_DIR/stocks"
|
||||
|
||||
mkdir -p "$output_dir/completed"
|
||||
|
||||
echo " 📈 分析: $symbol"
|
||||
|
||||
# 获取股票数据
|
||||
local api_data
|
||||
api_data=$(curl -s "https://query1.finance.yahoo.com/v8/finance/chart/$symbol?interval=1d&range=1mo" 2>/dev/null)
|
||||
|
||||
local close_price
|
||||
close_price=$(echo "$api_data" | grep -oE '"close":\[[0-9.]+\]' | grep -oE '[0-9.]+' | tail -1)
|
||||
|
||||
local output_file="$output_dir/completed/${symbol}_$(date '+%Y%m%d').md"
|
||||
|
||||
{
|
||||
echo "# 股票分析: $symbol"
|
||||
echo "分析时间: $DATE"
|
||||
echo ""
|
||||
echo "## 📊 数据概览"
|
||||
echo "- 当前价格: ${close_price:-N/A}"
|
||||
echo ""
|
||||
echo "## 🧠 技术分析"
|
||||
echo ""
|
||||
echo "### 趋势判断"
|
||||
echo "- 短期: 待分析"
|
||||
echo "- 中期: 待分析"
|
||||
echo ""
|
||||
echo "### 核心要点"
|
||||
echo "- 行业:"
|
||||
echo "- 财务:"
|
||||
echo ""
|
||||
echo "### 操作建议"
|
||||
echo "- 买入:"
|
||||
echo "- 卖出:"
|
||||
echo ""
|
||||
echo "---"
|
||||
echo "分析完成: $DATE"
|
||||
} >> "$output_file"
|
||||
|
||||
echo " ✓ 完成: $output_file"
|
||||
}
|
||||
|
||||
# ========================
|
||||
# 主流程
|
||||
# ========================
|
||||
main() {
|
||||
local topic="$1"
|
||||
local category="$2" # article / novel / stock
|
||||
local count="${3:-5}"
|
||||
|
||||
if [ -z "$topic" ]; then
|
||||
echo "用法: $0 <主题> <类型> [数量]"
|
||||
echo " 类型: article(文章) / novel(小说) / stock(股票)"
|
||||
echo " 示例: $0 '机器学习' article 5"
|
||||
echo " 示例: $0 'AAPL' stock 1"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "🎯 目标: $topic"
|
||||
echo "📂 类型: $category}"
|
||||
echo ""
|
||||
|
||||
# 执行搜索
|
||||
local urls
|
||||
urls=$(brave_search "$topic" "$count")
|
||||
|
||||
if [ -z "$urls" ]; then
|
||||
echo "✗ 搜索失败,退出"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== 开始学习 ==="
|
||||
|
||||
# 学习每个结果
|
||||
local success=0
|
||||
local total=0
|
||||
while IFS= read -r url; do
|
||||
if [ -n "$url" ]; then
|
||||
total=$((total + 1))
|
||||
if [ "$category" = "stock" ]; then
|
||||
analyze_stock "$topic"
|
||||
else
|
||||
learn_and_analyze "$topic" "$category" "$url"
|
||||
fi
|
||||
success=$((success + 1))
|
||||
fi
|
||||
done <<< "$urls"
|
||||
|
||||
echo ""
|
||||
echo "=== 学习完成 ==="
|
||||
echo "成功: $success/$total"
|
||||
echo "结果: $LEARNING_DIR/$category/completed/"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Executable
+394
@@ -0,0 +1,394 @@
|
||||
#!/bin/bash
|
||||
# OpenClaw Dog 守护程序 - 优化重试版
|
||||
# 功能:监控 Gateway 状态,自动修复故障
|
||||
# 特性:智能重试机制(指数退避 + 错误类型适配)
|
||||
|
||||
# ==================== 配置 ====================
|
||||
LOG_DIR="/root/.openclaw/logs"
|
||||
STATUS_FILE="$LOG_DIR/guardian_status.json"
|
||||
METRICS_FILE="$LOG_DIR/guardian_metrics.json"
|
||||
BACKUP_DIR="/root/.openclaw/backup"
|
||||
CONFIG_FILE="/root/.openclaw/openclaw.json"
|
||||
LOG_FILE="$LOG_DIR/guardian.log"
|
||||
PID_FILE="$LOG_DIR/guardian.pid"
|
||||
|
||||
GATEWAY_PORT=18789
|
||||
GATEWAY_PROCESS="openclaw.*gateway"
|
||||
|
||||
# 锁清理配置
|
||||
SESSION_LOCK_DIR="/root/.openclaw/agents/main/sessions"
|
||||
LOCK_CLEAN_MIN=10
|
||||
|
||||
# 检查配置
|
||||
FAILURE_THRESHOLD=3
|
||||
MAX_RETRIES=3 # 增加重试次数
|
||||
INITIAL_RETRY_DELAY=10 # 初始重试延迟(秒)
|
||||
MAX_RETRY_DELAY=120 # 最大重试延迟(秒)
|
||||
BACKOFF_FACTOR=2 # 指数退避因子
|
||||
|
||||
FAILURE_THRESHOLD=3
|
||||
STARTUP_WAIT=30
|
||||
MAX_BACKUPS=10
|
||||
|
||||
# ==================== 智能重试函数 ====================
|
||||
|
||||
# 计算下一次重试延迟(指数退避)
|
||||
calculate_retry_delay() {
|
||||
local attempt=$1
|
||||
local delay=$INITIAL_RETRY_DELAY
|
||||
|
||||
# 指数退避: delay = initial * (factor ^ (attempt-1))
|
||||
for i in $(seq 2 $attempt); do
|
||||
delay=$((delay * BACKOFF_FACTOR))
|
||||
done
|
||||
|
||||
# 不超过最大延迟
|
||||
[ $delay -gt $MAX_RETRY_DELAY ] && delay=$MAX_RETRY_DELAY
|
||||
|
||||
echo $delay
|
||||
}
|
||||
|
||||
# 根据错误类型获取建议的重试延迟
|
||||
get_error_based_delay() {
|
||||
local error_msg=$1
|
||||
|
||||
# 网络错误 - 较短延迟
|
||||
if echo "$error_msg" | grep -qi "network\|connection\|timeout"; then
|
||||
echo 15
|
||||
# 权限错误 - 中等延迟
|
||||
elif echo "$error_msg" | grep -qi "permission\|denied\|auth"; then
|
||||
echo 30
|
||||
# 资源不足 - 较长延迟
|
||||
elif echo "$error_msg" | grep -qi "memory\|cpu\|resource"; then
|
||||
echo 60
|
||||
# 默认使用指数退避
|
||||
else
|
||||
echo 0 # 使用默认指数退避
|
||||
fi
|
||||
}
|
||||
|
||||
# 智能重试函数
|
||||
smart_retry() {
|
||||
local max_attempts=$1
|
||||
local attempt=1
|
||||
local success=0
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
# 执行检查
|
||||
if check_gateway; then
|
||||
success=1
|
||||
break
|
||||
fi
|
||||
|
||||
# 获取错误信息
|
||||
local error_msg=$(check_gateway 2>&1)
|
||||
|
||||
# 计算延迟
|
||||
local delay
|
||||
local specific_delay=$(get_error_based_delay "$error_msg")
|
||||
|
||||
if [ $specific_delay -gt 0 ]; then
|
||||
delay=$specific_delay
|
||||
else
|
||||
delay=$(calculate_retry_delay $attempt)
|
||||
fi
|
||||
|
||||
log "RETRY" "Attempt $attempt/$max_attempts failed, waiting ${delay}s..."
|
||||
sleep $delay
|
||||
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
|
||||
return $success
|
||||
}
|
||||
|
||||
# ==================== 会话锁清理 ====================
|
||||
|
||||
clean_stale_locks() {
|
||||
local cleaned=0
|
||||
local now=$(date +%s)
|
||||
|
||||
find "$SESSION_LOCK_DIR" -name "*.lock" -type f 2>/dev/null | while read lockfile; do
|
||||
local age=$(($(date +%s) - $(stat -c %Y "$lockfile" 2>/dev/null || echo 0)))
|
||||
local age_min=$((age / 60))
|
||||
|
||||
if [ $age_min -gt $LOCK_CLEAN_MIN ]; then
|
||||
local pid=$(grep -o '"pid":[0-9]*' "$lockfile" 2>/dev/null | cut -d':' -f2)
|
||||
|
||||
if [ -n "$pid" ]; then
|
||||
if ! ps -p "$pid" > /dev/null 2>&1; then
|
||||
rm -f "$lockfile"
|
||||
log "CLEAN" "Removed stale lock: $(basename $lockfile) (age: ${age_min}min)"
|
||||
cleaned=$((cleaned + 1))
|
||||
fi
|
||||
else
|
||||
rm -f "$lockfile"
|
||||
cleaned=$((cleaned + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[ $cleaned -gt 0 ] && log "CLEAN" "Cleaned $cleaned stale locks"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ==================== 并发函数 ====================
|
||||
|
||||
check_single_instance() {
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local old_pid=$(cat "$PID_FILE" 2>/dev/null)
|
||||
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
echo $$ > "$PID_FILE"
|
||||
return 0
|
||||
}
|
||||
|
||||
cleanup_pid() {
|
||||
rm -f "$PID_FILE"
|
||||
}
|
||||
|
||||
# ==================== 日志 ====================
|
||||
log() {
|
||||
local level=$1
|
||||
shift
|
||||
local msg="$@"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] [$level] $msg" >> "$LOG_FILE"
|
||||
echo "[$timestamp] [$level] $msg"
|
||||
}
|
||||
|
||||
log_header() {
|
||||
log "=================================================="
|
||||
log " OpenClaw Dog - Gateway Guardian (Smart Retry)"
|
||||
log "=================================================="
|
||||
}
|
||||
|
||||
log_status() {
|
||||
log " Gateway: $1 | Fail: $2/$3 | Retry: $4/$5"
|
||||
}
|
||||
|
||||
log_summary() {
|
||||
local runs=$1 rate=$2 fails=$3 restarts=$4
|
||||
log "--------------------------------------------------"
|
||||
log " STATS: Runs=$runs | Success=$rate% | Fail=$fails | Restart=$restarts"
|
||||
log "--------------------------------------------------"
|
||||
}
|
||||
|
||||
# ==================== 核心函数 ====================
|
||||
get_timestamp_ms() { date +%s%3N; }
|
||||
get_elapsed_ms() { echo $(($(date +%s%3N) - $1)); }
|
||||
get_system_load() { uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ','; }
|
||||
get_gateway_pid() { pgrep -f "$GATEWAY_PROCESS" | head -1; }
|
||||
|
||||
check_port() { ss -tlnp 2>/dev/null | grep -q ":$GATEWAY_PORT"; }
|
||||
|
||||
check_http() {
|
||||
curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "http://127.0.0.1:$GATEWAY_PORT/" 2>/dev/null
|
||||
}
|
||||
|
||||
check_gateway() {
|
||||
local issues=0
|
||||
[ -z "$(get_gateway_pid)" ] && ((issues++))
|
||||
check_port || ((issues++))
|
||||
[ "$(check_http)" != "200" ] && ((issues++))
|
||||
return $issues
|
||||
}
|
||||
|
||||
# ==================== 状态管理 ====================
|
||||
read_status() { [ -f "$STATUS_FILE" ] && cat "$STATUS_FILE" || echo '{"failure_count":0,"retry_count":0}'; }
|
||||
get_value() { echo "$1" | grep -o "\"$2\":[0-9]*" | cut -d':' -f2; }
|
||||
|
||||
save_status() {
|
||||
cat > "$STATUS_FILE" << EOF
|
||||
{
|
||||
"failure_count": $1,
|
||||
"retry_count": $2,
|
||||
"last_check": "$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
record_metrics() {
|
||||
local time=$1 result=$2
|
||||
local runs=1 fails=0 restarts=0
|
||||
|
||||
if [ -f "$METRICS_FILE" ]; then
|
||||
runs=$(($(grep -o '"total_runs":[0-9]*' "$METRICS_FILE" | cut -d':' -f2) + 1))
|
||||
fails=$(grep -o '"total_failures":[0-9]*' "$METRICS_FILE" | cut -d':' -f2)
|
||||
restarts=$(grep -o '"total_restarts":[0-9]*' "$METRICS_FILE" | cut -d':' -f2)
|
||||
[ -z "$fails" ] && fails=0
|
||||
[ -z "$restarts" ] && restarts=0
|
||||
[ "$result" != "success" ] && fails=$((fails + 1))
|
||||
[ "$result" == "restarted" ] && restarts=$((restarts + 1))
|
||||
fi
|
||||
|
||||
local rate=$((100 - (fails * 100 / runs)))
|
||||
|
||||
cat > "$METRICS_FILE" << EOF
|
||||
{
|
||||
"total_runs": $runs,
|
||||
"total_failures": $fails,
|
||||
"total_restarts": $restarts,
|
||||
"success_rate": $rate,
|
||||
"avg_execution_ms": $time,
|
||||
"last_run": "$(date '+%Y-%m-%d %H:%M:%S')",
|
||||
"last_result": "$result"
|
||||
}
|
||||
EOF
|
||||
echo "$runs,$rate,$fails,$restarts"
|
||||
}
|
||||
|
||||
# ==================== 维修模块 ====================
|
||||
backup_config() {
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
local bf="${BACKUP_DIR}/openclaw_$(date '+%Y%m%d_%H%M%S').json"
|
||||
[ -f "$CONFIG_FILE" ] && cp "$CONFIG_FILE" "$bf" && log "REPAIR" "Backup: $(basename $bf)"
|
||||
echo "$bf"
|
||||
}
|
||||
|
||||
list_backups() { ls -t "${BACKUP_DIR}"/openclaw_*.json 2>/dev/null; }
|
||||
|
||||
restore_config() {
|
||||
[ -f "$1" ] && cp "$1" "$CONFIG_FILE" && log "REPAIR" "Restored: $(basename $1)"
|
||||
}
|
||||
|
||||
restart_gateway() {
|
||||
log "REPAIR" "Restarting Gateway..."
|
||||
systemctl --user restart openclaw-gateway.service
|
||||
}
|
||||
|
||||
repair_gateway() {
|
||||
log "REPAIR" "=== ENTER REPAIR MODE ==="
|
||||
|
||||
local current=$(backup_config)
|
||||
local backups=$(list_backups)
|
||||
local count=$(echo "$backups" | wc -l)
|
||||
log "REPAIR" "Found $count backups"
|
||||
|
||||
local attempt=1 success=0
|
||||
for backup in $backups; do
|
||||
[ $attempt -gt $MAX_BACKUPS ] && break
|
||||
log "REPAIR" "Try #$attempt: $(basename $backup)"
|
||||
restore_config "$backup"
|
||||
restart_gateway
|
||||
sleep 10
|
||||
if check_gateway; then
|
||||
success=1
|
||||
break
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
|
||||
if [ $success -eq 1 ]; then
|
||||
log "REPAIR" "SUCCESS: Gateway recovered"
|
||||
return 0
|
||||
else
|
||||
log "REPAIR" "FAILED: Restore original"
|
||||
restore_config "$current"
|
||||
restart_gateway
|
||||
log "REPAIR" "!!! REPAIR COMPLETELY FAILED !!!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ==================== 主程序 ====================
|
||||
main() {
|
||||
if ! check_single_instance; then
|
||||
log "WARN" "Another instance is running, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap cleanup_pid EXIT
|
||||
|
||||
# 先清理过期会话锁
|
||||
log "CLEAN" "=== Session Lock Cleanup ==="
|
||||
clean_stale_locks
|
||||
|
||||
local start=$(get_timestamp_ms)
|
||||
|
||||
log_header
|
||||
|
||||
local status=$(read_status)
|
||||
local failure=$(get_value "$status" "failure_count")
|
||||
local retry=$(get_value "$status" "retry_count")
|
||||
[ -z "$failure" ] && failure=0
|
||||
[ -z "$retry" ] && retry=0
|
||||
|
||||
log_status "CHECK" "$failure" "$FAILURE_THRESHOLD" "$retry" "$MAX_RETRIES"
|
||||
log " Load: $(get_system_load)"
|
||||
|
||||
check_gateway
|
||||
issues=$?
|
||||
local elapsed=$(get_elapsed_ms $start)
|
||||
|
||||
if [ $issues -eq 0 ]; then
|
||||
[ $failure -gt 0 ] && log " [OK] Gateway recovered" || log " [OK] Gateway healthy"
|
||||
|
||||
local m=$(record_metrics $elapsed "success")
|
||||
local runs=$(echo $m | cut -d',' -f1)
|
||||
local rate=$(echo $m | cut -d',' -f2)
|
||||
local fails=$(echo $m | cut -d',' -f3)
|
||||
local restarts=$(echo $m | cut -d',' -f4)
|
||||
|
||||
log_summary $runs $rate $fails $restarts
|
||||
log " Time: ${elapsed}ms"
|
||||
save_status 0 0
|
||||
exit 0
|
||||
else
|
||||
failure=$((failure + 1))
|
||||
|
||||
if [ $failure -lt $FAILURE_THRESHOLD ]; then
|
||||
save_status $failure $retry
|
||||
log " [WARN] Check failed, need $((FAILURE_THRESHOLD - failure)) more"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log " [ERROR] $FAILURE_THRESHOLD consecutive failures"
|
||||
|
||||
# 使用智能重试
|
||||
retry=0
|
||||
while [ $retry -lt $MAX_RETRIES ]; do
|
||||
retry=$((retry + 1))
|
||||
|
||||
if [ $retry -eq 1 ]; then
|
||||
log " [RETRY] Smart Retry #1 (initial delay: ${INITIAL_RETRY_DELAY}s)"
|
||||
else
|
||||
local delay=$(calculate_retry_delay $retry)
|
||||
log " [RETRY] Smart Retry #$retry (backoff delay: ${delay}s)"
|
||||
fi
|
||||
|
||||
restart_gateway
|
||||
sleep $STARTUP_WAIT
|
||||
|
||||
if check_gateway; then
|
||||
log " [OK] Gateway recovered after smart retry"
|
||||
|
||||
local m=$(record_metrics $elapsed "restarted")
|
||||
local runs=$(echo $m | cut -d',' -f1)
|
||||
local rate=$(echo $m | cut -d',' -f2)
|
||||
local fails=$(echo $m | cut -d',' -f3)
|
||||
local restarts=$(echo $m | cut -d',' -f4)
|
||||
log_summary $runs $rate $fails $restarts
|
||||
save_status 0 0
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
# 维修
|
||||
log " [ERROR] All smart retries failed, entering repair..."
|
||||
|
||||
if repair_gateway; then
|
||||
record_metrics $elapsed "repaired"
|
||||
save_status 0 0
|
||||
exit 0
|
||||
else
|
||||
record_metrics $elapsed "failed"
|
||||
save_status $FAILURE_THRESHOLD $MAX_RETRIES
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
main
|
||||
Executable
+121
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
# 1号机任务检查脚本
|
||||
# 定时检查任务队列,自动执行学习任务
|
||||
|
||||
TASK_QUEUE="/root/.openclaw/workspace/memory/task_queue.txt"
|
||||
LEARN_SCRIPT="/root/.openclaw/tools/learn-workflow.sh"
|
||||
REPORT_DIR="/root/.openclaw/workspace/memory/reports"
|
||||
LOG_FILE="/root/.openclaw/workspace/memory/task.log"
|
||||
DATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
mkdir -p "$REPORT_DIR"
|
||||
|
||||
echo "=== 任务检查: $DATE ===" >> "$LOG_FILE"
|
||||
|
||||
# 检查任务队列是否存在
|
||||
if [ ! -f "$TASK_QUEUE" ]; then
|
||||
echo "队列文件不存在" >> "$LOG_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 当前时间戳
|
||||
NOW=$(date +%s)
|
||||
|
||||
# 读取并执行到期任务
|
||||
TEMP_FILE=$(mktemp)
|
||||
COMPLETED_FILE=$(mktemp)
|
||||
REPORT_FILE="$REPORT_DIR/$(date '+%Y%m%d_%H%M%S').report"
|
||||
|
||||
# 开始报告
|
||||
{
|
||||
echo "任务执行报告"
|
||||
echo "时间: $DATE"
|
||||
echo "================"
|
||||
} > "$REPORT_FILE"
|
||||
|
||||
# 读取并执行到期任务
|
||||
while IFS= read -r line; do
|
||||
# 跳过注释和空行
|
||||
[[ "$line" =~ ^#.*$ ]] && continue
|
||||
[[ -z "$line" ]] && continue
|
||||
|
||||
# 解析: 时间|主题|类型|数量
|
||||
TIMESTAMP=$(echo "$line" | cut -d'|' -f1)
|
||||
TOPIC=$(echo "$line" | cut -d'|' -f2)
|
||||
TYPE=$(echo "$line" | cut -d'|' -f3)
|
||||
COUNT=$(echo "$line" | cut -d'|' -f4)
|
||||
|
||||
# 转换时间为秒
|
||||
TASK_SECONDS=$(date -d "$TIMESTAMP" +%s 2>/dev/null)
|
||||
if [ -z "$TASK_SECONDS" ]; then
|
||||
echo " ⚠️ 无效时间格式: $TIMESTAMP"
|
||||
echo "[跳过] $TIMESTAMP | $TOPIC | 无效时间格式" >> "$REPORT_FILE"
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查是否到期
|
||||
if [ "$TASK_SECONDS" -le "$NOW" ]; then
|
||||
echo "执行: $TOPIC ($TYPE) x$COUNT" >> "$LOG_FILE"
|
||||
echo "- 任务: $TOPIC" >> "$REPORT_FILE"
|
||||
echo " 类型: $TYPE" >> "$REPORT_FILE"
|
||||
echo " 数量: $COUNT" >> "$REPORT_FILE"
|
||||
echo " 状态: " >> "$REPORT_FILE"
|
||||
|
||||
# 执行学习任务
|
||||
TASK_LOG=$(mktemp)
|
||||
if "$LEARN_SCRIPT" "$TOPIC" "$TYPE" "$COUNT" >> "$TASK_LOG" 2>&1; then
|
||||
echo " ✓ 完成: $TOPIC" >> "$LOG_FILE"
|
||||
echo " 完成" >> "$REPORT_FILE"
|
||||
# 记录到已完成
|
||||
echo "$line" >> "$COMPLETED_FILE"
|
||||
else
|
||||
echo " ✗ 失败: $TOPIC" >> "$LOG_FILE"
|
||||
echo " 失败 (保留重试)" >> "$REPORT_FILE"
|
||||
# 保留到下一轮
|
||||
echo "$line" >> "$TEMP_FILE"
|
||||
fi
|
||||
|
||||
# 追加任务日志
|
||||
echo " 日志:" >> "$REPORT_FILE"
|
||||
sed 's/^/ /' "$TASK_LOG" >> "$REPORT_FILE"
|
||||
rm -f "$TASK_LOG"
|
||||
else
|
||||
# 未到期,保留
|
||||
echo "$line" >> "$TEMP_FILE"
|
||||
fi
|
||||
done < "$TASK_QUEUE"
|
||||
|
||||
# 结束报告
|
||||
{
|
||||
echo "================"
|
||||
echo "完成: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
} >> "$REPORT_FILE"
|
||||
|
||||
# 更新任务队列
|
||||
if [ -f "$COMPLETED_FILE" ]; then
|
||||
# 添加已完成标记
|
||||
echo "" >> "$COMPLETED_FILE"
|
||||
echo "# 完成于: $DATE" >> "$COMPLETED_FILE"
|
||||
cat "$COMPLETED_FILE" >> "$TASK_QUEUE.completed"
|
||||
fi
|
||||
|
||||
if [ -f "$TEMP_FILE" ] && [ -s "$TEMP_FILE" ]; then
|
||||
mv "$TEMP_FILE" "$TASK_QUEUE"
|
||||
else
|
||||
rm -f "$TASK_QUEUE"
|
||||
fi
|
||||
|
||||
# 清理
|
||||
rm -f "$COMPLETED_FILE"
|
||||
|
||||
# 清理旧报告 (保留最近3天)
|
||||
find "$REPORT_DIR" -name "*.report" -mtime +3 -delete
|
||||
|
||||
echo "检查完成: $(date '+%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE"
|
||||
echo "" >> "$LOG_FILE"
|
||||
|
||||
# 显示报告摘要
|
||||
if [ -f "$REPORT_FILE" ]; then
|
||||
LINES=$(wc -l < "$REPORT_FILE")
|
||||
echo "报告: $REPORT_FILE ($LINES 行)"
|
||||
fi
|
||||
Reference in new issue
Block a user