采集任务的监控与报警:Prometheus + Grafana实践
采集任务的监控与报警,核心并不是把所有日志和异常都推送出来,而是让团队能够及时知道任务是否正常运行、数据是否按时到达,以及失败后应该由谁处理。本文以 Prometheus + Grafana + Alertmanager 为基础,搭建一套适合网页采集、接口同步、数据入库和定时调度任务的可观测方案。
文章中的示例默认采集程序可以暴露 Prometheus 指标,并且任务由独立 Worker 或调度器执行。实际落地时,还需要结合任务规模、数据敏感程度、告警渠道和团队值班制度进行调整。
🎯 一、先定义采集任务真正需要监控什么
很多团队一开始只监控进程存活状态,但进程存活并不等于采集链路健康。程序可能仍在运行,却因为目标站点改版、代理失效、解析规则过期或数据库连接异常而持续产生空数据。
建议从四个维度设计指标:任务是否执行、任务是否成功、数据是否新鲜、系统是否有积压。这四个维度能够覆盖从调度、抓取、解析到入库的大多数故障。
1. 任务执行与成功率
执行次数可以反映调度器是否正常触发,成功次数和失败次数则用于计算任务成功率。对于短时间内连续失败的任务,应优先报警,因为它通常意味着目标站点变化、认证失效或依赖服务异常。
2. 延迟、数据新鲜度与积压
任务耗时适合使用直方图统计,这样可以观察平均值之外的 P95 或 P99 延迟。数据新鲜度则要记录最近一次成功采集时间,避免“任务成功但数据已经几个小时没有更新”的假健康状态。
如果采集任务采用消息队列,还应监控队列长度、最老消息年龄和消费速率。积压持续增加通常比单次任务失败更值得关注,因为它会逐步扩大数据延迟。
📊 二、设计稳定且低基数的指标标签
Prometheus 通过标签区分时间序列,但标签组合过多会造成基数爆炸。因此,标签应该选择固定且有限的维度,例如任务名称、目标站点、环境和结果状态。
不要把 URL、文章标题、用户 ID、完整异常信息或随机请求 ID 放进标签中,这些值数量不可控,容易导致 Prometheus 内存增长和查询变慢。详细错误信息应写入日志,再通过 trace_id 或任务 ID进行关联。
常见指标命名可以遵循“对象_动作_单位”的思路,例如任务执行总数、任务执行耗时和当前队列数量。计数器使用总量,速率交给 PromQL 计算;当前状态则使用 Gauge 表示。
一个 Python 采集器埋点示例
from prometheus_client import Counter, Gauge, Histogram
import time
task_total = Counter(
"collector_task_total",
"Total collector task executions",
["job", "site", "status"]
)
task_duration = Histogram(
"collector_task_duration_seconds",
"Collector task duration",
["job", "site"],
buckets=(1, 5, 10, 30, 60, 120, 300)
)
last_success = Gauge(
"collector_task_last_success_timestamp",
"Unix timestamp of the last successful task",
["job", "site"]
)
def run_task(job, site):
started = time.time()
try:
fetch_and_store(job, site)
task_total.labels(job, site, "success").inc()
last_success.labels(job, site).set(time.time())
except Exception:
task_total.labels(job, site, "failed").inc()
raise
finally:
task_duration.labels(job, site).observe(time.time() - started)
示例中失败状态只有 success 和 failed 两种,避免把异常类型无限细分。若确实需要区分错误原因,可以预先定义有限集合,例如 timeout、blocked、parse_error 和 storage_error。
🔧 三、配置 Prometheus 抓取采集指标
Prometheus 应定期访问采集服务的指标接口。抓取间隔不宜盲目设置得过短,任务周期较长时可以使用 15 至 30 秒的监控间隔,并确保应用的指标接口足够轻量。
生产环境建议通过服务发现、容器标签或静态配置管理目标地址,同时限制指标接口的访问来源。不要把包含敏感业务信息的日志内容直接暴露到指标接口中。
global:
scrape_interval: 30s
evaluation_interval: 30s
scrape_configs:
- job_name: "collector-workers"
scrape_timeout: 10s
metrics_path: /metrics
static_configs:
- targets:
- "collector-worker-1:8000"
- "collector-worker-2:8000"
labels:
env: "production"
service: "collector"
需要注意,scrape_timeout 必须小于 scrape_interval,否则目标服务响应稍慢时会造成大量抓取失败。Prometheus 本身也应该监控,重点关注目标是否在线、抓取是否成功以及规则评估是否延迟。
🚨 四、用 PromQL 编写可执行的报警规则
报警规则必须具备明确的触发条件、持续时间和处理方向。不要只写“任务异常”,而应说明哪个任务、哪个站点、持续多久以及建议检查什么。
以下规则覆盖目标下线、失败率升高、任务耗时变慢和数据长时间未更新等典型场景。for 时间用于过滤瞬时抖动,避免一次网络超时就触发人工告警。
groups:
- name: collector-alerts
rules:
- alert: CollectorTargetDown
expr: up{job="collector-workers"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "采集服务不可用"
description: "实例 {{ $labels.instance }} 已连续 5 分钟无法抓取指标"
- alert: CollectorFailureRateHigh
expr: |
sum by (job, site) (rate(collector_task_total{status="failed"}[10m]))
/
sum by (job, site) (rate(collector_task_total[10m]))
> 0.2
for: 10m
labels:
severity: warning
annotations:
summary: "采集失败率过高"
description: "任务 {{ $labels.job }} 在站点 {{ $labels.site }} 的失败率超过 20%"
- alert: CollectorLatencyP95High
expr: |
histogram_quantile(
0.95,
sum by (le, job, site) (
rate(collector_task_duration_seconds_bucket[10m])
)
) > 120
for: 10m
labels:
severity: warning
annotations:
summary: "采集耗时过高"
description: "任务 {{ $labels.job }} 在 {{ $labels.site }} 的 P95 延迟超过 120 秒"
- alert: CollectorDataStale
expr: time() - collector_task_last_success_timestamp > 3600
for: 15m
labels:
severity: critical
annotations:
summary: "采集数据长时间未更新"
description: "任务 {{ $labels.job }} 在 {{ $labels.site }} 已超过 1 小时没有成功记录"
失败率计算时要确认分母不会为零,低频任务还应结合任务调度周期设计规则。对于每天只运行一次的任务,使用固定的时间窗口可能不合适,更适合比较最近成功时间和预期截止时间。
电报精准找群黑科技提示:
由于 Telegram 官方搜索对中文支持极差,很多优质的推广、技术和资源群组隐藏极深。如果你正在寻找相关的活跃社群,强烈推荐使用本站首页的 TTSO - Telegram 智能搜索 Bot。作为目前最好用的电报综合搜索导航,只需输入关键词,即可秒级触达数十万个精选 TG 中文群组、资源频道。一键直达,帮你节省 90% 的找群时间!
📈 五、Grafana 仪表盘应该如何布局
Grafana 首页应优先回答“现在是否健康”,而不是堆满所有指标。第一行可以放任务成功率、最近成功时间、当前失败任务数和队列积压量,第二行展示各站点的执行次数、P95 延迟和失败原因。
建议创建 job、site、env 三个变量,让值班人员能够快速筛选单个任务或站点。图表的时间范围可以默认设置为最近 6 小时,同时保留 24 小时和 7 天视图,用于区分短时故障与趋势性退化。
颜色应表达风险而不是装饰:绿色代表达到目标,黄色代表接近阈值,红色代表需要处理。面板标题要包含单位和统计口径,例如“采集 P95 延迟(秒)”,避免误读。
把监控图表和排障动作连接起来
每个关键面板都应能跳转到日志、任务详情或发布记录。这样当失败率升高时,工程师可以沿着“指标—日志—任务输入—外部站点”的路径排查,而不是在多个系统之间重复搜索。
📨 六、Alertmanager 负责降噪和通知分流
Prometheus 负责判断是否触发规则,Alertmanager 则负责分组、静默、抑制和通知。建议按 severity、team 和 service 路由,让严重故障进入电话或即时通讯,普通波动进入群聊或邮件。
同一站点的多个任务同时失败时,应通过 group_by 合并通知,避免短时间内发送几十条相似消息。维护窗口可以配置 silence,依赖故障则使用 inhibition,防止下游任务报警淹没根因。
route:
receiver: "collector-default"
group_by: ["alertname", "site", "severity"]
group_wait: 30s
group_interval: 10m
repeat_interval: 4h
routes:
- matchers:
- severity="critical"
receiver: "oncall-critical"
- matchers:
- severity="warning"
receiver: "collector-chat"
inhibit_rules:
- source_matchers:
- severity="critical"
target_matchers:
- severity="warning"
equal: ["job", "site"]
一条高质量告警至少应包含摘要、影响范围、当前值、持续时间和排查入口。告警不是监控系统的终点,团队还需要为高频故障维护简短的处理手册。
🧪 七、上线前后的验证与治理
上线前应主动模拟网络超时、目标站点返回异常、解析字段缺失、数据库不可用和 Worker 停止等故障,确认指标、规则和通知链路都能按预期工作。不要等到真实事故发生后,才发现告警没有接收人。
上线后可以每周检查告警数量、误报比例、未确认告警和恢复时间。如果某条规则长期无人处理,通常说明阈值不合理、通知渠道不对,或者它根本不具备明确的行动价值。
还要定期控制时间序列数量,检查标签是否出现异常增长,并为 Prometheus 数据配置保留周期和备份策略。涉及账号、代理、Cookie 或业务数据时,应限制访问权限并避免写入公开日志。
❓ 常见问题解答(FAQ)
Q1:采集任务只监控进程存活是否足够?
不够。进程可能处于运行状态,但任务已经卡死、持续返回空数据或无法写入数据库,因此还需要监控成功率、最近成功时间、数据量和任务延迟。
Q2:为什么不建议把每个 URL 作为 Prometheus 标签?
URL 数量通常没有稳定上限,会产生大量高基数时间序列,增加内存和存储压力。可以按站点、业务类型或固定路由进行聚合,具体 URL 则保留在日志或追踪系统中。
Q3:低频采集任务如何设置报警?
不要直接套用 5 分钟窗口的失败率规则,应记录最近一次成功时间,并与任务计划周期比较。例如任务每 6 小时运行一次,可以在超过计划时间加缓冲后触发数据陈旧报警。
Q4:Grafana 和 Prometheus 的职责有什么区别?
Prometheus 负责抓取、存储和计算时间序列指标,Grafana 负责查询、可视化和仪表盘展示。真正的消息分组、静默和多渠道通知通常由 Alertmanager 完成。
总结:一套可靠的采集监控体系,应从业务结果出发,把任务执行、采集质量、数据新鲜度和基础设施状态统一起来。通过合理埋点、低基数标签、可验证的 PromQL 规则和有行动指向的告警,Prometheus 与 Grafana 才能真正帮助团队减少故障发现时间,而不是制造更多噪音。

