行业资讯
为 Prometheus 告警规则增加 UI 管理能力
为 Prometheus 告警规则增加 UI 管理能力在现代云原生架构中Prometheus 作为核心监控系统其告警规则配置通常依赖 YAML 文件管理。这种方式虽然灵活但缺乏可视化界面容易导致配置错误且难以实现动态管理。本文将循序渐进地探讨如何为 Prometheus 告警规则增加 UI 管理能力从基础概念到高级实现完整展示构建过程。## 1. 基础概念Prometheus 告警规则与 UI 需求### 1.1 Prometheus 告警规则的本质Prometheus 告警规则通过 YAML 文件定义格式如下yamlgroups:- name: example rules: - alert: HighCpuUsage expr: node_cpu_seconds_total{modeuser} 0.8 for: 5m labels: severity: critical annotations: summary: CPU usage high### 1.2 为什么需要 UI 管理-易用性无需直接编辑 YAML 文件-动态性实时添加、修改、删除规则-可视化预览规则效果避免语法错误-审计记录规则变更历史## 2. 基础实现构建简单 UI 与后端### 2.1 后端 API 设计我们使用 Python Flask 实现一个简单的 REST API用于管理告警规则python# backend/app.pyfrom flask import Flask, jsonify, requestimport yamlapp Flask(__name__)RULES_FILE alerts.yamldef load_rules(): 从文件加载告警规则 with open(RULES_FILE, r) as f: return yaml.safe_load(f)def save_rules(data): 保存告警规则到文件 with open(RULES_FILE, w) as f: yaml.dump(data, f)app.route(/rules, methods[GET])def get_rules(): 获取所有告警规则 rules load_rules() return jsonify(rules)app.route(/rules, methods[POST])def add_rule(): 添加新告警规则 new_rule request.json rules load_rules() rules[groups][0][rules].append(new_rule) save_rules(rules) return jsonify({status: success, rule: new_rule})app.route(/rules/int:rule_id, methods[DELETE])def delete_rule(rule_id): 删除指定告警规则 rules load_rules() if rule_id len(rules[groups][0][rules]): del rules[groups][0][rules][rule_id] save_rules(rules) return jsonify({status: deleted}) return jsonify({status: error, message: Rule not found}), 404if __name__ __main__: app.run(debugTrue)### 2.2 前端 UI 基础使用 HTML JavaScript 构建简单界面html!-- frontend/index.html --!DOCTYPE htmlhtmlhead titlePrometheus 告警规则管理/title style body { font-family: Arial; margin: 20px; } .rule-card { border: 1px solid #ddd; padding: 10px; margin: 10px 0; } button { margin: 5px; } /style/headbody h1告警规则列表/h1 div idrules-container/div h2添加新规则/h2 form idadd-rule-form input typetext idalert-name placeholder告警名称 required input typetext idexpr placeholder表达式 (如: node_cpu 0.8) required button typesubmit添加规则/button /form script const apiBase http://localhost:5000; async function loadRules() { const response await fetch(${apiBase}/rules); const data await response.json(); const container document.getElementById(rules-container); container.innerHTML ; data.groups[0].rules.forEach((rule, index) { const card document.createElement(div); card.className rule-card; card.innerHTML h3${rule.alert}/h3 p表达式: ${rule.expr}/p p持续时间: ${rule.for || N/A}/p button onclickdeleteRule(${index})删除/button ; container.appendChild(card); }); } async function deleteRule(index) { await fetch(${apiBase}/rules/${index}, { method: DELETE }); loadRules(); } document.getElementById(add-rule-form).addEventListener(submit, async (e) { e.preventDefault(); const name document.getElementById(alert-name).value; const expr document.getElementById(expr).value; await fetch(${apiBase}/rules, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ alert: name, expr: expr, for: 5m, labels: { severity: warning }, annotations: { summary: ${name} triggered } }) }); loadRules(); }); loadRules(); /script/body/html## 3. 进阶实现完整的 CRUD 与验证### 3.1 增强后端功能增加规则验证和更新功能python# backend/advanced_app.pyfrom flask import Flask, jsonify, requestimport yamlimport refrom datetime import datetimeapp Flask(__name__)RULES_FILE alerts.yamldef validate_rule(rule): 验证告警规则格式 required_fields [alert, expr] for field in required_fields: if field not in rule: return False, f缺少必填字段: {field} # 简单表达式验证 if not rule[expr].strip(): return False, 表达式不能为空 return True, app.route(/rules/int:rule_id, methods[PUT])def update_rule(rule_id): 更新指定规则 updated_rule request.json valid, msg validate_rule(updated_rule) if not valid: return jsonify({status: error, message: msg}), 400 rules load_rules() if rule_id len(rules[groups][0][rules]): rules[groups][0][rules][rule_id] updated_rule save_rules(rules) return jsonify({status: updated, rule: updated_rule}) return jsonify({status: error, message: Rule not found}), 404app.route(/rules/history, methods[GET])def get_history(): 获取规则变更历史简化版 try: with open(history.log, r) as f: history f.readlines() return jsonify({history: history[-50:]}) # 返回最近50条 except FileNotFoundError: return jsonify({history: []})### 3.2 前端增强添加编辑和历史功能javascript// advanced_frontend.js (片段)async function updateRule(index) { const name prompt(输入新告警名称:); const expr prompt(输入新表达式:); if (name expr) { const response await fetch(${apiBase}/rules/${index}, { method: PUT, headers: { Content-Type: application/json }, body: JSON.stringify({ alert: name, expr: expr, for: 5m, labels: { severity: warning }, annotations: { summary: ${name} triggered } }) }); if (response.ok) { loadRules(); loadHistory(); } else { alert(更新失败); } }}## 4. 高级实现集成 Prometheus 热加载### 4.1 自动重载配置高级版本需要自动通知 Prometheus 重新加载规则python# advanced_backend.py (片段)import requestsPROMETHEUS_URL http://localhost:9090def reload_prometheus(): 触发 Prometheus 热加载 try: response requests.post(f{PROMETHEUS_URL}/-/reload) return response.status_code 200 except requests.exceptions.RequestException as e: print(f重载失败: {e}) return Falseapp.route(/rules, methods[POST])def add_rule_with_reload(): 添加规则并重载 new_rule request.json valid, msg validate_rule(new_rule) if not valid: return jsonify({status: error, message: msg}), 400 rules load_rules() rules[groups][0][rules].append(new_rule) save_rules(rules) # 记录变更 with open(history.log, a) as f: f.write(f{datetime.now()}: 添加规则 {new_rule[alert]}\n) # 触发重载 if reload_prometheus(): return jsonify({status: success, reloaded: True}) else: return jsonify({status: success, reloaded: False, warning: 请手动重载})### 4.2 高级 UI批量操作与预览javascript// advanced_ui.js (片段)async function batchDelete() { const rules document.querySelectorAll(.rule-card input[typecheckbox]:checked); const ids Array.from(rules).map(cb parseInt(cb.dataset.id)); for (const id of ids) { await fetch(${apiBase}/rules/${id}, { method: DELETE }); } loadRules();}async function previewRule(expr) { // 调用 Prometheus API 预览 const response await fetch(http://localhost:9090/api/v1/query?query${encodeURIComponent(expr)}); const data await response.json(); if (data.status success) { alert(查询结果: ${JSON.stringify(data.data.result)}); } else { alert(表达式无效); }}## 5. 总结通过本文我们从 Prometheus 告警规则的基础概念出发逐步构建了完整的 UI 管理能力1.基础阶段我们理解了告警规则的 YAML 结构并构建了简单的 Flask 后端和 HTML 前端实现了规则的读取和添加功能。2.进阶阶段增加了规则验证、更新功能和变更历史记录提高了系统的健壮性和可用性。3.高级阶段集成了 Prometheus 热加载机制实现了配置变更的自动生效并添加了批量操作和表达式预览功能。这种 UI 管理方式不仅降低了运维成本还让团队能够更灵活地调整告警策略。在实际生产环境中还可以添加用户认证、权限管理、规则分组、告警模板等功能构建更完善的告警管理平台。核心思想是保持 Prometheus 原生配置格式的同时通过中间层实现动态管理和可视化操作。
郑州网站建设
网页设计
企业官网