feat: alert rule api fill users and groups (#723)
This commit is contained in:
parent
4585519943
commit
6440645c5a
|
@ -0,0 +1,41 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/didi/nightingale/v5/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserGroupMap struct {
|
||||||
|
sync.RWMutex
|
||||||
|
Data map[int64]*models.UserGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
var UserGroupCache = &UserGroupMap{Data: make(map[int64]*models.UserGroup)}
|
||||||
|
|
||||||
|
func (s *UserGroupMap) GetBy(id int64) *models.UserGroup {
|
||||||
|
s.RLock()
|
||||||
|
defer s.RUnlock()
|
||||||
|
|
||||||
|
return s.Data[id]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UserGroupMap) GetByIds(ids []int64) []*models.UserGroup {
|
||||||
|
s.RLock()
|
||||||
|
defer s.RUnlock()
|
||||||
|
var userGroups []*models.UserGroup
|
||||||
|
for _, id := range ids {
|
||||||
|
if s.Data[id] == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
userGroups = append(userGroups, s.Data[id])
|
||||||
|
}
|
||||||
|
|
||||||
|
return userGroups
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UserGroupMap) SetAll(userGroups map[int64]*models.UserGroup) {
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
|
s.Data = userGroups
|
||||||
|
}
|
|
@ -3,16 +3,21 @@ package http
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"github.com/didi/nightingale/v5/cache"
|
||||||
"github.com/didi/nightingale/v5/config"
|
"github.com/didi/nightingale/v5/config"
|
||||||
"github.com/didi/nightingale/v5/models"
|
"github.com/didi/nightingale/v5/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func alertRuleGet(c *gin.Context) {
|
func alertRuleGet(c *gin.Context) {
|
||||||
renderData(c, AlertRule(urlParamInt64(c, "id")), nil)
|
alertRule := AlertRule(urlParamInt64(c, "id"))
|
||||||
|
alertRuleFillUserAndGroups(alertRule)
|
||||||
|
renderData(c, alertRule, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type alertRuleForm struct {
|
type alertRuleForm struct {
|
||||||
|
@ -163,3 +168,22 @@ func alertRuleDel(c *gin.Context) {
|
||||||
func notifyChannelsGet(c *gin.Context) {
|
func notifyChannelsGet(c *gin.Context) {
|
||||||
renderData(c, config.Config.NotifyChannels, nil)
|
renderData(c, config.Config.NotifyChannels, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func alertRuleFillUserAndGroups(alertRule *models.AlertRule) {
|
||||||
|
uidStrs := strings.Fields(alertRule.NotifyUsers)
|
||||||
|
var uids []int64
|
||||||
|
for _, uidStr := range uidStrs {
|
||||||
|
uid, _ := strconv.ParseInt(uidStr, 10, 64)
|
||||||
|
uids = append(uids, uid)
|
||||||
|
}
|
||||||
|
alertRule.NotifyUsersDetail = cache.UserCache.GetByIds(uids)
|
||||||
|
|
||||||
|
gidStrs := strings.Fields(alertRule.NotifyGroups)
|
||||||
|
var gids []int64
|
||||||
|
for _, gidStr := range gidStrs {
|
||||||
|
gid, _ := strconv.ParseInt(gidStr, 10, 64)
|
||||||
|
gids = append(gids, gid)
|
||||||
|
}
|
||||||
|
|
||||||
|
alertRule.NotifyGroupsDetail = cache.UserGroupCache.GetByIds(gids)
|
||||||
|
}
|
||||||
|
|
|
@ -68,6 +68,10 @@ func alertRuleGroupGet(c *gin.Context) {
|
||||||
|
|
||||||
func alertRuleOfGroupGet(c *gin.Context) {
|
func alertRuleOfGroupGet(c *gin.Context) {
|
||||||
ars, err := models.AlertRulesOfGroup(urlParamInt64(c, "id"))
|
ars, err := models.AlertRulesOfGroup(urlParamInt64(c, "id"))
|
||||||
|
for i := range ars {
|
||||||
|
alertRuleFillUserAndGroups(&ars[i])
|
||||||
|
}
|
||||||
|
|
||||||
renderData(c, ars, err)
|
renderData(c, ars, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
main.go
1
main.go
|
@ -71,6 +71,7 @@ func main() {
|
||||||
|
|
||||||
timer.SyncResourceTags()
|
timer.SyncResourceTags()
|
||||||
timer.SyncUsers()
|
timer.SyncUsers()
|
||||||
|
timer.SyncUserGroups()
|
||||||
timer.SyncUserGroupMember()
|
timer.SyncUserGroupMember()
|
||||||
timer.SyncClasspathReses()
|
timer.SyncClasspathReses()
|
||||||
timer.SyncCollectRules()
|
timer.SyncCollectRules()
|
||||||
|
|
|
@ -19,32 +19,34 @@ const ALERT_RULE_ACTIVE = 0
|
||||||
const ALERT_RULE_DISABLED = 1
|
const ALERT_RULE_DISABLED = 1
|
||||||
|
|
||||||
type AlertRule struct {
|
type AlertRule struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
GroupId int64 `json:"group_id"`
|
GroupId int64 `json:"group_id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Type int `json:"type"` // 0: nightingale, 1: prometheus
|
Type int `json:"type"` // 0: nightingale, 1: prometheus
|
||||||
Expression json.RawMessage `json:"expression"`
|
Expression json.RawMessage `json:"expression"`
|
||||||
Status int `json:"status"` // 0: active, 1: disabled
|
Status int `json:"status"` // 0: active, 1: disabled
|
||||||
AppendTags string `json:"append_tags"`
|
AppendTags string `json:"append_tags"`
|
||||||
EnableStime string `json:"enable_stime"`
|
EnableStime string `json:"enable_stime"`
|
||||||
EnableEtime string `json:"enable_etime"`
|
EnableEtime string `json:"enable_etime"`
|
||||||
EnableDaysOfWeek string `json:"enable_days_of_week"`
|
EnableDaysOfWeek string `json:"enable_days_of_week"`
|
||||||
RecoveryNotify int `json:"recovery_notify"`
|
RecoveryNotify int `json:"recovery_notify"`
|
||||||
Priority int `json:"priority"`
|
Priority int `json:"priority"`
|
||||||
NotifyChannels string `json:"notify_channels"`
|
NotifyChannels string `json:"notify_channels"`
|
||||||
NotifyGroups string `json:"notify_groups"`
|
NotifyGroups string `json:"notify_groups"`
|
||||||
NotifyUsers string `json:"notify_users"`
|
NotifyUsers string `json:"notify_users"`
|
||||||
Callbacks string `json:"callbacks"`
|
Callbacks string `json:"callbacks"`
|
||||||
RunbookUrl string `json:"runbook_url"`
|
RunbookUrl string `json:"runbook_url"`
|
||||||
Note string `json:"note"`
|
Note string `json:"note"`
|
||||||
CreateAt int64 `json:"create_at"`
|
CreateAt int64 `json:"create_at"`
|
||||||
CreateBy string `json:"create_by"`
|
CreateBy string `json:"create_by"`
|
||||||
UpdateAt int64 `json:"update_at"`
|
UpdateAt int64 `json:"update_at"`
|
||||||
UpdateBy string `json:"update_by"`
|
UpdateBy string `json:"update_by"`
|
||||||
AlertDuration int `json:"alert_duration"` // 告警统计周期,PULL模型会当做P8S的for时间
|
AlertDuration int `json:"alert_duration"` // 告警统计周期,PULL模型会当做P8S的for时间
|
||||||
PushExpr PushExpression `xorm:"-" json:"-"`
|
PushExpr PushExpression `xorm:"-" json:"-"`
|
||||||
PullExpr PullExpression `xorm:"-" json:"-"`
|
PullExpr PullExpression `xorm:"-" json:"-"`
|
||||||
FirstMetric string `xorm:"-" json:"-"` // Exps里可能有多个metric,只取第一个,给后续制作map使用
|
FirstMetric string `xorm:"-" json:"-"` // Exps里可能有多个metric,只取第一个,给后续制作map使用
|
||||||
|
NotifyUsersDetail []*User `xorm:"-" json:"notify_users_detail"`
|
||||||
|
NotifyGroupsDetail []*UserGroup `xorm:"-" json:"notify_groups_detail"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PushExpression struct {
|
type PushExpression struct {
|
||||||
|
|
|
@ -204,3 +204,19 @@ func (ug *UserGroup) Del() error {
|
||||||
|
|
||||||
return session.Commit()
|
return session.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UserGroupGetAll() ([]UserGroup, error) {
|
||||||
|
var userGroups []UserGroup
|
||||||
|
|
||||||
|
err := DB.Find(&userGroups)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("mysql.error: select user_group fail: %v", err)
|
||||||
|
return userGroups, internalServerError
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(userGroups) == 0 {
|
||||||
|
return []UserGroup{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return userGroups, nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package timer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/didi/nightingale/v5/cache"
|
||||||
|
"github.com/didi/nightingale/v5/models"
|
||||||
|
|
||||||
|
"github.com/toolkits/pkg/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
// user_group_id->user_group 将数据库中的用户信息缓存在内存里,
|
||||||
|
// 在生成告警事件的时候,根据用户ID快速找到用户的详情
|
||||||
|
func SyncUserGroups() {
|
||||||
|
err := syncUserGroups()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("timer: sync users fail:", err)
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
go loopSyncUserGroups()
|
||||||
|
}
|
||||||
|
|
||||||
|
func loopSyncUserGroups() {
|
||||||
|
randtime := rand.Intn(9000)
|
||||||
|
fmt.Printf("timer: sync users: random sleep %dms\n", randtime)
|
||||||
|
time.Sleep(time.Duration(randtime) * time.Millisecond)
|
||||||
|
|
||||||
|
for {
|
||||||
|
time.Sleep(time.Second * time.Duration(9))
|
||||||
|
err := syncUserGroups()
|
||||||
|
if err != nil {
|
||||||
|
logger.Warning("timer: sync users fail:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func syncUserGroups() error {
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
userGroups, err := models.UserGroupGetAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userGroupsMap := make(map[int64]*models.UserGroup)
|
||||||
|
for i := range userGroups {
|
||||||
|
userGroupsMap[userGroups[i].Id] = &userGroups[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.UserGroupCache.SetAll(userGroupsMap)
|
||||||
|
logger.Debugf("timer: sync userGroups done, cost: %dms", time.Since(start).Milliseconds())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue