diff --git a/backend/prome/query.go b/backend/prome/query.go index 1367dd88..ef6dca9a 100644 --- a/backend/prome/query.go +++ b/backend/prome/query.go @@ -253,14 +253,37 @@ func (pd *PromeDataSource) QueryData(inputs vos.DataQueryParam) []*vos.DataQuery oneResp.Ident = ident // TODO 去掉point num pNum := len(m.Points) - for _, p := range m.Points { + interval := int64(resolution / time.Second) + pNumExpect := int((inputs.End - inputs.Start) / interval) + + remotePIndex := 0 + for i := 0; i <= pNumExpect; i++ { + + // 先准备好null的point + tsLocal := inputs.Start + interval*int64(i) tmpP := &vos.Point{ - // 毫秒时间时间戳转 秒时间戳 - Timestamp: p.T / 1e3, - Value: vos.JsonFloat(p.V), + Timestamp: tsLocal, + Value: vos.JsonFloat(math.NaN()), + } + //说明points数组还没越界 + //去m.Points获取一个 + if remotePIndex < pNum { + pointOne := m.Points[remotePIndex] + tsRemote := pointOne.T / 1e3 + // 判断时间戳 ,前后相差1秒认为时间戳对齐了 + if math.Abs(float64(tsRemote-tsLocal)) <= 1 { + tmpP.Timestamp = tsRemote + tmpP.Value = vos.JsonFloat(pointOne.V) + // 说明远端的这个索引的值已经被pop了,移动索引 + remotePIndex++ + } + } + oneResp.Values = append(oneResp.Values, tmpP) + } + for _, x := range m.Metric { if x.Name == LABEL_NAME { continue @@ -269,7 +292,7 @@ func (pd *PromeDataSource) QueryData(inputs vos.DataQueryParam) []*vos.DataQuery } tagStr = strings.TrimRight(tagStr, ",") oneResp.Tags = tagStr - oneResp.Resolution = int64(resolution / time.Second) + oneResp.Resolution = interval oneResp.PNum = pNum respD = append(respD, oneResp) diff --git a/config/i18n.go b/config/i18n.go index 4a9582b1..a08ca3ca 100644 --- a/config/i18n.go +++ b/config/i18n.go @@ -46,6 +46,7 @@ var ( "No such alert rule": "告警规则不存在", "No such alert rule group": "告警规则分组不存在", "No such alert event": "告警事件不存在", + "Alert rule %s already exists": "告警规则(%s)已存在", "No such collect rule": "采集规则不存在", "Decoded metric description empty": "导入的指标释义列表为空", "User disabled": "用户已被禁用", diff --git a/http/router_alert_rule.go b/http/router_alert_rule.go index c34e052f..f9ea810c 100644 --- a/http/router_alert_rule.go +++ b/http/router_alert_rule.go @@ -47,7 +47,7 @@ func alertRuleAdd(c *gin.Context) { bind(c, &f) me := loginUser(c).MustPerm("alert_rule_create") - + var ids []int64 for _, alertRule := range f { arg := AlertRuleGroup(alertRule.GroupId) alertRuleWritePermCheck(arg, me) @@ -74,9 +74,10 @@ func alertRuleAdd(c *gin.Context) { UpdateBy: me.Username, } dangerous(ar.Add()) + ids = append(ids, ar.Id) } - renderMessage(c, nil) + renderData(c, ids, nil) } func alertRulePut(c *gin.Context) { @@ -88,8 +89,18 @@ func alertRulePut(c *gin.Context) { arg := AlertRuleGroup(ar.GroupId) alertRuleWritePermCheck(arg, me) + if ar.Name != f.Name { + num, err := models.AlertRuleCount("group_id=? and name=? and id<>?", ar.GroupId, f.Name, ar.Id) + dangerous(err) + + if num > 0 { + bomb(200, "Alert rule %s already exists", f.Name) + } + } + ar.Name = f.Name ar.Note = f.Note + ar.Type = f.Type ar.Status = f.Status ar.AlertDuration = f.AlertDuration ar.Expression = f.Expression @@ -111,6 +122,7 @@ func alertRulePut(c *gin.Context) { renderMessage(c, ar.Update( "name", "note", + "type", "status", "alert_duration", "expression", diff --git a/http/router_user_group.go b/http/router_user_group.go index d366e547..108ca3ea 100644 --- a/http/router_user_group.go +++ b/http/router_user_group.go @@ -55,7 +55,7 @@ func userGroupAdd(c *gin.Context) { // 顺便把创建者也作为团队的一员,失败了也没关系,用户会重新添加成员 models.UserGroupMemberAdd(ug.Id, me.Id) - renderMessage(c, nil) + renderData(c, ug.Id, nil) } func userGroupPut(c *gin.Context) { diff --git a/models/alert_rule.go b/models/alert_rule.go index 0b95d5eb..5ce113e9 100644 --- a/models/alert_rule.go +++ b/models/alert_rule.go @@ -262,6 +262,15 @@ func (ar *AlertRule) Add() error { return err } + num, err := AlertRuleCount("group_id=? and name=?", ar.GroupId, ar.Name) + if err != nil { + return err + } + + if num > 0 { + return _e("Alert rule %s already exists", ar.Name) + } + now := time.Now().Unix() ar.CreateAt = now ar.UpdateAt = now diff --git a/sql/n9e.sql b/sql/n9e.sql index ff658a04..b1997b3d 100644 --- a/sql/n9e.sql +++ b/sql/n9e.sql @@ -340,7 +340,7 @@ insert into metric_description(metric, description) values('system_disk_read_tim insert into metric_description(metric, description) values('system_disk_bytes_total', '磁盘某分区总量(单位:byte)'); insert into metric_description(metric, description) values('system_disk_bytes_used', '磁盘某分区用量大小(单位:byte)'); insert into metric_description(metric, description) values('system_disk_write_time', '设备写操作耗时(单位:ms)'); -insert into metric_description(metric, description) values('system_disk_write_time_percent', ''); +insert into metric_description(metric, description) values('system_disk_write_time_percent', '写入磁盘时间百分比(单位:%)'); insert into metric_description(metric, description) values('system_files_allocated', '系统已分配文件句柄数'); insert into metric_description(metric, description) values('system_files_left', '系统未分配文件句柄数'); insert into metric_description(metric, description) values('system_files_used_percent', '系统使用文件句柄占已分配百分比(单位:%)'); @@ -382,7 +382,7 @@ insert into metric_description(metric, description) values('system_mem_free', ' insert into metric_description(metric, description) values('system_mem_used', '已用内存大小(单位:*byte*)'); insert into metric_description(metric, description) values('system_swap_cached', '用作缓存的交换空间'); insert into metric_description(metric, description) values('system_swap_free', '空闲swap大小(单位:*byte*)'); -insert into metric_description(metric, description) values('system_swap_pct_free', '空闲swap占比'); +insert into metric_description(metric, description) values('system_swap_free_percent', '空闲swap占比'); insert into metric_description(metric, description) values('system_swap_total', 'swap总大小(单位:*byte*)'); insert into metric_description(metric, description) values('system_swap_used', '已用swap大小(单位:*byte*)'); insert into metric_description(metric, description) values('system_swap_used_percent', '已用swap占比(单位:%)');