| @@ -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) | |||
| @@ -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": "用户已被禁用", | |||
| @@ -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", | |||
| @@ -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) { | |||
| @@ -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 | |||
| @@ -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占比(单位:%)'); | |||