0

Shell脚本curl重定向告警企业微信配置:3个实战脚本让网站问题秒级推送到企业微信

2026.06.05 | youres | 24次围观

为什么需要curl重定向+企业微信告警

单次curl手动检查重定向,适合调试阶段。但线上网站需要持续监控

  • 重定向链突然变长(被劫持或配置错误)
  • HTTPS跳转失效,用户访问到HTTP页面
  • 短链UTM参数在重定向中丢失,影响流量归因
  • CDN层配置变更导致重定向行为异常

企业微信机器人推送的优势:零邮件延迟、支持Markdown格式、可@指定负责人、与企业微信审批/工单流转无缝衔接

前置准备:curl重定向检测原理

核心用两个curl内置变量:

num_redirects  → 重定向次数
url_effective  → 最终到达的URL
time_redirect  → 重定向阶段耗时(秒)

配合-w格式化输出,一行命令拿到全部重定向诊断数据:

curl -o /dev/null -s -w "num=%{num_redirects},url=%{url_effective},time=%{time_redirect}\n" "https://example.com"

实战一:基础版——curl检测重定向+企业微信文本消息推送

企业微信机器人Webhook获取

在企业微信群 → 右上角「…」→ 「群机器人」→ 「添加机器人」→ 复制Webhook地址。

基础告警脚本

#!/bin/bash
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY"
TEST_URL="https://www.youres.cn"
MAX_REDIRECTS=3
MAX_TIME=2.0

RESULT=$(curl -o /dev/null -s -L \
  -w "num=%{num_redirects}|url=%{url_effective}|time=%{time_redirect}|code=%{http_code}" \
  -m 10 "$TEST_URL")

num=$(echo "$RESULT" | grep -o 'num=[0-9]*' | cut -d= -f2)
url=$(echo "$RESULT" | grep -o 'url=[^|]*' | cut -d= -f2)
time=$(echo "$RESULT" | grep -o 'time=[0-9.]*' | cut -d= -f2)
code=$(echo "$RESULT" | grep -o 'code=[0-9]*' | cut -d= -f2)

alert=0; msg=""
[ "$num" -gt "$MAX_REDIRECTS" ] && alert=1 && msg="${msg}重定向次数异常: ${num}次\n"
time_int=$(echo "$time" | awk '{printf "%d", $1 * 1000}')
[ "$time_int" -gt "$(echo $MAX_TIME | awk '{printf "%d", $1 * 1000}')" ] && alert=1 && msg="${msg}重定向耗时超限: ${time}s\n"
[ "$code" != "200" ] && alert=1 && msg="${msg}HTTP状态码异常: ${code}\n"

if [ "$alert" -eq 1 ]; then
  curl -s -X POST "$WEBHOOK" -H 'Content-Type: application/json' \
    -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"警报 重定向告警\nURL: ${TEST_URL}\n${msg}最终地址: ${url}\"}}"
  echo "告警已推送"
else
  echo "正常: 重定向${num}次,耗时${time}s,状态码${code}"
fi

使用方法:chmod +x script.sh && ./script.sh

实战二:进阶版——Markdown格式推送,信息更清晰

企业微信机器人支持Markdown消息类型,可以加粗、换行、引用,告警信息更直观。

#!/bin/bash
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY"
TEST_URL="$1"
MAX_REDIRECTS=3; MAX_TIME=2.0
[ -z "$TEST_URL" ] && { echo "用法: $0 <URL>"; exit 1; }

RESULT=$(curl -o /dev/null -s -L \
  -w "num=%{num_redirects}|url=%{url_effective}|time=%{time_redirect}|code=%{http_code}" \
  -m 10 "$TEST_URL" 2>/dev/null)

num=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^num=' | cut -d= -f2)
url=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^url=' | cut -d= -f2)
time=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^time=' | cut -d= -f2)
code=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^code=' | cut -d= -f2)

alert=0; facts=""
[ "$num" -gt "$MAX_REDIRECTS" ] && alert=1 && facts="${facts}> **重定向次数异常**: ${num}次\n"
time_ms=$(echo "$time" | awk '{printf "%.0f", $1 * 1000}')
max_ms=$(echo $MAX_TIME | awk '{printf "%.0f", $1 * 1000}')
[ "$time_ms" -gt "$max_ms" ] && alert=1 && facts="${facts}> **重定向耗时异常**: ${time_ms}ms\n"
[ "$code" != "200" ] && alert=1 && facts="${facts}> **HTTP状态码异常**: ${code}\n"

if [ "$alert" -eq 1 ]; then
  facts_escaped=$(echo -e "$facts" | sed 's/"/\\"/g')
  curl -s -X POST "$WEBHOOK" -H 'Content-Type: application/json' \
    -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"## 警报 网站重定向告警\n**检测URL**: ${TEST_URL}\n${facts_escaped}\"}}"
  echo "Markdown告警已推送"
else
  echo "正常: ${num}次跳转,${time_ms}ms,状态码${code}"
fi

实战三:生产版——多URL批量检测+告警抑制+日志记录

生产环境需要解决三个问题:批量检测、告警抑制(避免刷屏)、日志记录。

#!/bin/bash
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY"
URL_FILE="./url_list.txt"
LOG_FILE="./redirect_check.log"
STATE_DIR="./state"
MAX_REDIRECTS=3; MAX_TIME=2.0

mkdir -p "$STATE_DIR"; touch "$LOG_FILE"

while IFS= read -r TEST_URL || [ -n "$TEST_URL" ]; do
  [[ -z "$TEST_URL" || "$TEST_URL" =~ ^# ]] && continue
  state_file="${STATE_DIR}/$(echo -n "$TEST_URL" | md5sum | cut -d' ' -f1).state"

  RESULT=$(curl -o /dev/null -s -L \
    -w "num=%{num_redirects}|url=%{url_effective}|time=%{time_redirect}|code=%{http_code}" \
    -m 10 "$TEST_URL" 2>/dev/null)

  num=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^num=' | cut -d= -f2)
  url=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^url=' | cut -d= -f2)
  time=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^time=' | cut -d= -f2)
  code=$(echo "$RESULT" | sed 's/|/\n/g' | grep '^code=' | cut -d= -f2)
  time_ms=$(echo "$time" | awk '{printf "%.0f", $1 * 1000}')
  max_ms=$(echo $MAX_TIME | awk '{printf "%.0f", $1 * 1000}')

  timestamp=$(date '+%Y-%m-%d %H:%M:%S')
  log_line="${timestamp} | ${TEST_URL} | num=${num} | time=${time_ms}ms | code=${code}"
  alert=0; facts=""
  [ "$num" -gt "$MAX_REDIRECTS" ] && alert=1 && facts="${facts}> **重定向次数异常**: ${num}次\n"
  [ "$time_ms" -gt "$max_ms" ] && alert=1 && facts="${facts}> **重定向耗时异常**: ${time_ms}ms\n"
  [ "$code" != "200" ] && alert=1 && facts="${facts}> **HTTP状态码异常**: ${code}\n"

  if [ "$alert" -eq 1 ]; then
    if [ -f "$state_file" ]; then
      last_alert_time=$(cat "$state_file")
      [ $(( $(date +%s) - last_alert_time )) -lt 1800 ] && echo "${log_line} | SUPPRESSED" >> "$LOG_FILE" && continue
    fi
    date +%s > "$state_file"
    echo "${log_line} | ALERT" >> "$LOG_FILE"
    facts_escaped=$(echo -e "$facts" | sed 's/"/\\"/g')
    curl -s -X POST "$WEBHOOK" -H 'Content-Type: application/json' \
      -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"## 警报 网站重定向告警\n**检测URL**: ${TEST_URL}\n${facts_escaped}\"}}"
    echo "告警已推送: ${TEST_URL}"
  else
    rm -f "$state_file"
    echo "${log_line} | OK" >> "$LOG_FILE"
  fi
done < "$URL_FILE"
echo "批量检测完成,日志: ${LOG_FILE}"

url_list.txt 每行一个URL,以 # 开头的行视为注释。

加入 crontab 每5分钟执行:*/5 * * * * /path/to/script.sh

三个方案对比与选型建议

方案适用场景告警格式批量检测告警抑制
基础版单URL快速验证文本
进阶版单URL + 清晰展示Markdown
生产版多URL持续监控Markdown

选型建议:本地调试用基础版或进阶版;生产环境部署务必用生产版,告警抑制能避免企业微信群被同一条告警刷屏。

常见问题排查

Q1:企业微信机器人推送失败,返回errcode 93000?
Webhook URL中的key参数错误,或机器人已被删除。到企业微信群重新添加机器人获取新Webhook地址。

Q2:curl检测重定向次数为0,但实际有跳转?
未加-L参数。curl默认不跟随重定向,-L(或--location)才是跟随跳转的开关。

Q3:生产版告警抑制时间如何调整?
脚本中1800是30分钟(单位秒)。按需修改这个数值即可。

Q4:如何监控短链的UTM参数是否在重定向中丢失?
在curl命令中加入-w输出url_effective,然后在脚本中判断最终URL是否还包含utm_source=等参数。

相关文章

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论