为什么需要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辅助作者原创,未经许可,转载请保留原文链接。

发表评论