Skip to content

Commit 6de1793

Browse files
committed
feat(告警规则): 添加删除规则模板和元信息的API接口
实现删除告警规则模板及其关联元信息的功能,包括: 1. 添加DELETE /v1/alert-rules/:rule_name接口删除规则模板 2. 添加DELETE /v1/alert-rules-meta/:rule_name接口删除特定元信息 3. 更新相关文档说明删除操作的使用方法
1 parent 705363e commit 6de1793

File tree

4 files changed

+193
-0
lines changed

4 files changed

+193
-0
lines changed

docs/prometheus_adapter/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,60 @@ internal/prometheus_adapter/
193193
}
194194
```
195195

196+
#### 3. 删除规则模板
197+
- 方法与路径:`DELETE /v1/alert-rules/:rule_name`
198+
- 功能:删除指定的告警规则模板及其所有关联的元信息
199+
- 路径参数:
200+
- `rule_name`:规则名称(如 `high_cpu_usage`
201+
- 响应示例:
202+
```json
203+
{
204+
"status": "success",
205+
"message": "Rule 'high_cpu_usage' and 3 associated metas deleted successfully",
206+
"rule_name": "high_cpu_usage",
207+
"deleted_metas": 3
208+
}
209+
```
210+
- 错误响应示例(规则不存在):
211+
```json
212+
{
213+
"error": {
214+
"code": "INVALID_PARAMETER",
215+
"message": "rule 'invalid_rule' not found"
216+
}
217+
}
218+
```
219+
220+
#### 4. 删除规则元信息
221+
- 方法与路径:`DELETE /v1/alert-rules-meta/:rule_name`
222+
- 功能:删除指定规则下的特定元信息(通过 labels 唯一标识)
223+
- 路径参数:
224+
- `rule_name`:规则名称(如 `high_cpu_usage`
225+
- 请求体示例:
226+
```json
227+
{
228+
"labels": "{\"service\":\"storage-service\",\"version\":\"1.0.0\"}"
229+
}
230+
```
231+
- 响应示例:
232+
```json
233+
{
234+
"status": "success",
235+
"message": "Rule meta deleted successfully",
236+
"rule_name": "high_cpu_usage",
237+
"labels": "{\"service\":\"storage-service\",\"version\":\"1.0.0\"}"
238+
}
239+
```
240+
- 错误响应示例(元信息不存在):
241+
```json
242+
{
243+
"error": {
244+
"code": "INVALID_PARAMETER",
245+
"message": "rule meta not found for rule 'high_cpu_usage' with labels '{\"service\":\"invalid-service\"}'"
246+
}
247+
}
248+
```
249+
196250
#### 规则生成机制
197251
- **规则模板与元信息关联**:通过 `alert_name` 字段关联
198252
- `AlertRule.name` = `AlertRuleMeta.alert_name`

internal/prometheus_adapter/api/alert_api.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
func (api *Api) setupAlertRouters(router *fox.Engine) {
1313
router.PUT("/v1/alert-rules/:rule_name", api.UpdateRule)
1414
router.PUT("/v1/alert-rules-meta/:rule_name", api.UpdateRuleMetas)
15+
router.DELETE("/v1/alert-rules/:rule_name", api.DeleteRule)
16+
router.DELETE("/v1/alert-rules-meta/:rule_name", api.DeleteRuleMeta)
1517
}
1618

1719
// UpdateRule 更新单个规则模板
@@ -107,3 +109,71 @@ func (api *Api) UpdateRuleMetas(c *fox.Context) {
107109
"updated_count": updatedCount,
108110
})
109111
}
112+
113+
// DeleteRule 删除单个规则模板及其所有关联的元信息
114+
func (api *Api) DeleteRule(c *fox.Context) {
115+
ruleName := c.Param("rule_name")
116+
if ruleName == "" {
117+
SendErrorResponse(c, http.StatusBadRequest, model.ErrorCodeInvalidParameter,
118+
"Rule name is required", nil)
119+
return
120+
}
121+
122+
// 获取受影响的元信息数量
123+
affectedCount := api.alertService.GetAffectedMetas(ruleName)
124+
125+
err := api.alertService.DeleteRule(ruleName)
126+
if err != nil {
127+
if err.Error() == fmt.Sprintf("rule '%s' not found", ruleName) {
128+
SendErrorResponse(c, http.StatusNotFound, model.ErrorCodeInvalidParameter,
129+
err.Error(), nil)
130+
} else {
131+
SendErrorResponse(c, http.StatusInternalServerError, model.ErrorCodeInternalError,
132+
"Failed to delete rule: "+err.Error(), nil)
133+
}
134+
return
135+
}
136+
137+
c.JSON(http.StatusOK, map[string]interface{}{
138+
"status": "success",
139+
"message": fmt.Sprintf("Rule '%s' and %d associated metas deleted successfully", ruleName, affectedCount),
140+
"rule_name": ruleName,
141+
"deleted_metas": affectedCount,
142+
})
143+
}
144+
145+
// DeleteRuleMeta 删除单个规则元信息
146+
func (api *Api) DeleteRuleMeta(c *fox.Context) {
147+
ruleName := c.Param("rule_name")
148+
if ruleName == "" {
149+
SendErrorResponse(c, http.StatusBadRequest, model.ErrorCodeInvalidParameter,
150+
"Rule name is required", nil)
151+
return
152+
}
153+
154+
var req model.DeleteAlertRuleMetaRequest
155+
if err := c.ShouldBindJSON(&req); err != nil {
156+
SendErrorResponse(c, http.StatusBadRequest, model.ErrorCodeInvalidParameter,
157+
"Invalid request body: "+err.Error(), nil)
158+
return
159+
}
160+
161+
err := api.alertService.DeleteRuleMeta(ruleName, req.Labels)
162+
if err != nil {
163+
if err.Error() == fmt.Sprintf("rule meta not found for rule '%s' with labels '%s'", ruleName, req.Labels) {
164+
SendErrorResponse(c, http.StatusNotFound, model.ErrorCodeInvalidParameter,
165+
err.Error(), nil)
166+
} else {
167+
SendErrorResponse(c, http.StatusInternalServerError, model.ErrorCodeInternalError,
168+
"Failed to delete rule meta: "+err.Error(), nil)
169+
}
170+
return
171+
}
172+
173+
c.JSON(http.StatusOK, map[string]interface{}{
174+
"status": "success",
175+
"message": "Rule meta deleted successfully",
176+
"rule_name": ruleName,
177+
"labels": req.Labels,
178+
})
179+
}

internal/prometheus_adapter/model/api.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,8 @@ type AlertRuleMetaUpdate struct {
6868
Labels string `json:"labels" binding:"required"` // 必填,用于唯一标识
6969
Threshold float64 `json:"threshold"`
7070
}
71+
72+
// DeleteAlertRuleMetaRequest 删除告警规则元信息请求
73+
type DeleteAlertRuleMetaRequest struct {
74+
Labels string `json:"labels" binding:"required"` // 必填,用于唯一标识要删除的元信息
75+
}

internal/prometheus_adapter/service/alert_service.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,70 @@ func (s *AlertService) GetAffectedMetas(ruleName string) int {
264264
return count
265265
}
266266

267+
// DeleteRule 删除单个规则模板及其所有关联的元信息
268+
func (s *AlertService) DeleteRule(ruleName string) error {
269+
// 查找并删除规则模板
270+
ruleFound := false
271+
for i, rule := range s.currentRules {
272+
if rule.Name == ruleName {
273+
// 从切片中删除规则
274+
s.currentRules = append(s.currentRules[:i], s.currentRules[i+1:]...)
275+
ruleFound = true
276+
break
277+
}
278+
}
279+
280+
if !ruleFound {
281+
return fmt.Errorf("rule '%s' not found", ruleName)
282+
}
283+
284+
// 删除所有关联的元信息
285+
deletedMetaCount := 0
286+
newMetas := []model.AlertRuleMeta{}
287+
for _, meta := range s.currentRuleMetas {
288+
if meta.AlertName != ruleName {
289+
newMetas = append(newMetas, meta)
290+
} else {
291+
deletedMetaCount++
292+
}
293+
}
294+
s.currentRuleMetas = newMetas
295+
296+
log.Info().
297+
Str("rule", ruleName).
298+
Int("deleted_metas", deletedMetaCount).
299+
Msg("Rule and associated metas deleted")
300+
301+
// 重新生成并同步
302+
return s.regenerateAndSync()
303+
}
304+
305+
// DeleteRuleMeta 删除单个规则元信息
306+
func (s *AlertService) DeleteRuleMeta(ruleName, labels string) error {
307+
// 查找并删除匹配的元信息
308+
found := false
309+
for i, meta := range s.currentRuleMetas {
310+
if meta.AlertName == ruleName && meta.Labels == labels {
311+
// 从切片中删除元信息
312+
s.currentRuleMetas = append(s.currentRuleMetas[:i], s.currentRuleMetas[i+1:]...)
313+
found = true
314+
break
315+
}
316+
}
317+
318+
if !found {
319+
return fmt.Errorf("rule meta not found for rule '%s' with labels '%s'", ruleName, labels)
320+
}
321+
322+
log.Info().
323+
Str("rule", ruleName).
324+
Str("labels", labels).
325+
Msg("Rule meta deleted")
326+
327+
// 重新生成并同步
328+
return s.regenerateAndSync()
329+
}
330+
267331
// ========== 内部核心方法 ==========
268332

269333
// regenerateAndSync 使用当前内存中的规则和元信息重新生成Prometheus规则并同步

0 commit comments

Comments
 (0)