Compare commits

..

8 Commits

Author SHA1 Message Date
Yening Qin
7568119667 Merge branch 'release-21' into update-workflow 2026-01-22 19:44:42 +08:00
ning
40722d2ff3 update workflow status 2026-01-16 19:56:24 +08:00
ning
ec7fbf313b update workflow 2026-01-16 15:29:46 +08:00
ning
b3ee1e56ad update callback 2026-01-16 15:15:48 +08:00
ning
d908240912 update workflow 2026-01-16 14:21:50 +08:00
ning
d54bcdd722 update workflow 2026-01-16 14:04:14 +08:00
ning
806b3effe9 update workflow 2026-01-14 19:23:15 +08:00
ning
b296d5bcc3 refactor: update trigger value 2026-01-14 16:15:39 +08:00
48 changed files with 154 additions and 350 deletions

View File

@@ -118,7 +118,7 @@ func (s *Set) updateTargets(m map[string]models.HostMeta) error {
}
start := time.Now()
err := storage.MSet(context.Background(), s.redis, newMap, 7*24*time.Hour)
err := storage.MSet(context.Background(), s.redis, newMap)
if err != nil {
cstats.RedisOperationLatency.WithLabelValues("mset_target_meta", "fail").Observe(time.Since(start).Seconds())
return err
@@ -127,7 +127,7 @@ func (s *Set) updateTargets(m map[string]models.HostMeta) error {
}
if len(extendMap) > 0 {
err = storage.MSet(context.Background(), s.redis, extendMap, 7*24*time.Hour)
err = storage.MSet(context.Background(), s.redis, extendMap)
if err != nil {
cstats.RedisOperationLatency.WithLabelValues("mset_target_extend", "fail").Observe(time.Since(start).Seconds())
return err

View File

@@ -391,8 +391,8 @@ func (rt *Router) Config(r *gin.Engine) {
pages.GET("/busi-group/:id/recording-rules", rt.auth(), rt.user(), rt.perm("/recording-rules"), rt.recordingRuleGets)
pages.POST("/busi-group/:id/recording-rules", rt.auth(), rt.user(), rt.perm("/recording-rules/add"), rt.bgrw(), rt.recordingRuleAddByFE)
pages.DELETE("/busi-group/:id/recording-rules", rt.auth(), rt.user(), rt.perm("/recording-rules/del"), rt.bgrw(), rt.recordingRuleDel)
pages.PUT("/busi-group/:id/recording-rule/:rrid", rt.auth(), rt.user(), rt.perm("/recording-rules/put"), rt.bgrw(), rt.recordingRulePutByFE)
pages.GET("/recording-rule/:rrid", rt.auth(), rt.user(), rt.perm("/recording-rules"), rt.recordingRuleGet)
pages.PUT("/recording-rule/:rrid", rt.auth(), rt.user(), rt.perm("/recording-rules"), rt.recordingRulePutByFE)
pages.PUT("/busi-group/:id/recording-rules/fields", rt.auth(), rt.user(), rt.perm("/recording-rules/put"), rt.recordingRulePutFields)
pages.GET("/busi-groups/alert-mutes", rt.auth(), rt.user(), rt.perm("/alert-mutes"), rt.alertMuteGetsByGids)

View File

@@ -36,7 +36,6 @@ func (rt *Router) alertRuleGets(c *gin.Context) {
for i := 0; i < len(ars); i++ {
ars[i].FillNotifyGroups(rt.Ctx, cache)
}
models.FillUpdateByNicknames(rt.Ctx, ars)
}
ginx.NewRender(c).Data(ars, err)
}
@@ -77,6 +76,7 @@ func (rt *Router) alertRuleGetsByGids(c *gin.Context) {
if err == nil {
cache := make(map[int64]*models.UserGroup)
rids := make([]int64, 0, len(ars))
names := make([]string, 0, len(ars))
for i := 0; i < len(ars); i++ {
ars[i].FillNotifyGroups(rt.Ctx, cache)
@@ -85,6 +85,7 @@ func (rt *Router) alertRuleGetsByGids(c *gin.Context) {
}
rids = append(rids, ars[i].Id)
names = append(names, ars[i].UpdateBy)
}
stime, etime := GetAlertCueEventTimeRange(c)
@@ -95,7 +96,14 @@ func (rt *Router) alertRuleGetsByGids(c *gin.Context) {
}
}
models.FillUpdateByNicknames(rt.Ctx, ars)
users := models.UserMapGet(rt.Ctx, "username in (?)", names)
if users != nil {
for i := 0; i < len(ars); i++ {
if user, exist := users[ars[i].UpdateBy]; exist {
ars[i].UpdateByNickname = user.Nickname
}
}
}
}
ginx.NewRender(c).Data(ars, err)
}
@@ -127,7 +135,6 @@ func (rt *Router) alertRulesGetByService(c *gin.Context) {
ars[i].DatasourceIdsJson = rt.DatasourceCache.GetIDsByDsCateAndQueries(ars[i].Cate, ars[i].DatasourceQueries)
}
}
models.FillUpdateByNicknames(rt.Ctx, ars)
}
ginx.NewRender(c).Data(ars, err)
}

View File

@@ -30,7 +30,6 @@ func (rt *Router) alertSubscribeGets(c *gin.Context) {
ginx.Dangerous(lst[i].FillDatasourceIds(rt.Ctx))
ginx.Dangerous(lst[i].DB2FE())
}
models.FillUpdateByNicknames(rt.Ctx, lst)
ginx.NewRender(c).Data(lst, err)
}
@@ -67,7 +66,6 @@ func (rt *Router) alertSubscribeGetsByGids(c *gin.Context) {
ginx.Dangerous(lst[i].FillDatasourceIds(rt.Ctx))
ginx.Dangerous(lst[i].DB2FE())
}
models.FillUpdateByNicknames(rt.Ctx, lst)
ginx.NewRender(c).Data(lst, err)
}

View File

@@ -260,9 +260,6 @@ func (rt *Router) boardGets(c *gin.Context) {
query := ginx.QueryStr(c, "query", "")
boards, err := models.BoardGetsByGroupId(rt.Ctx, bgid, query)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, boards)
}
ginx.NewRender(c).Data(boards, err)
}
@@ -276,9 +273,6 @@ func (rt *Router) publicBoardGets(c *gin.Context) {
ginx.Dangerous(err)
boards, err := models.BoardGets(rt.Ctx, "", "public=1 and (public_cate in (?) or id in (?))", []int64{0, 1}, boardIds)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, boards)
}
ginx.NewRender(c).Data(boards, err)
}
@@ -318,7 +312,6 @@ func (rt *Router) boardGetsByGids(c *gin.Context) {
boards[i].Bgids = ids
}
}
models.FillUpdateByNicknames(rt.Ctx, boards)
ginx.NewRender(c).Data(boards, err)
}

View File

@@ -27,8 +27,6 @@ func (rt *Router) metricFilterGets(c *gin.Context) {
}
}
models.FillUpdateByNicknames(rt.Ctx, arr)
ginx.NewRender(c).Data(arr, err)
}

View File

@@ -119,9 +119,6 @@ func (rt *Router) busiGroupGets(c *gin.Context) {
if len(lst) == 0 {
lst = []models.BusiGroup{}
}
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, lst)
}
ginx.NewRender(c).Data(lst, err)
}

View File

@@ -15,9 +15,6 @@ func (rt *Router) configsGet(c *gin.Context) {
prefix := ginx.QueryStr(c, "prefix", "")
limit := ginx.QueryInt(c, "limit", 10)
configs, err := models.ConfigsGets(rt.Ctx, prefix, limit, ginx.Offset(c, limit))
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, configs)
}
ginx.NewRender(c).Data(configs, err)
}

View File

@@ -13,7 +13,6 @@ import (
func (rt *Router) embeddedProductGets(c *gin.Context) {
products, err := models.EmbeddedProductGets(rt.Ctx)
ginx.Dangerous(err)
models.FillUpdateByNicknames(rt.Ctx, products)
// 获取当前用户可访问的Group ID 列表
me := c.MustGet("user").(*models.User)

View File

@@ -69,10 +69,6 @@ func (rt *Router) esIndexPatternGetList(c *gin.Context) {
lst, err = models.EsIndexPatternGets(rt.Ctx, "")
}
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, lst)
}
ginx.NewRender(c).Data(lst, err)
}

View File

@@ -35,7 +35,6 @@ func (rt *Router) eventPipelinesList(c *gin.Context) {
// 兼容处理:自动填充工作流字段
pipeline.FillWorkflowFields()
}
models.FillUpdateByNicknames(rt.Ctx, pipelines)
gids, err := models.MyGroupIdsMap(rt.Ctx, me.Id)
ginx.Dangerous(err)

View File

@@ -154,7 +154,6 @@ func (rt *Router) messageTemplatesGet(c *gin.Context) {
lst, err := models.MessageTemplatesGetBy(rt.Ctx, notifyChannelIdents)
ginx.Dangerous(err)
models.FillUpdateByNicknames(rt.Ctx, lst)
if me.IsAdmin() {
ginx.NewRender(c).Data(lst, nil)

View File

@@ -22,9 +22,6 @@ func (rt *Router) alertMuteGetsByBG(c *gin.Context) {
query := ginx.QueryStr(c, "query", "")
expired := ginx.QueryInt(c, "expired", -1)
lst, err := models.AlertMuteGets(rt.Ctx, prods, bgid, -1, expired, query)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, lst)
}
ginx.NewRender(c).Data(lst, err)
}
@@ -50,9 +47,6 @@ func (rt *Router) alertMuteGetsByGids(c *gin.Context) {
}
lst, err := models.AlertMuteGetsByBGIds(rt.Ctx, gids)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, lst)
}
ginx.NewRender(c).Data(lst, err)
}
@@ -64,9 +58,6 @@ func (rt *Router) alertMuteGets(c *gin.Context) {
disabled := ginx.QueryInt(c, "disabled", -1)
expired := ginx.QueryInt(c, "expired", -1)
lst, err := models.AlertMuteGets(rt.Ctx, prods, bgid, disabled, expired, query)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, lst)
}
ginx.NewRender(c).Data(lst, err)
}

View File

@@ -118,9 +118,6 @@ func (rt *Router) notifyChannelGetBy(c *gin.Context) {
func (rt *Router) notifyChannelsGet(c *gin.Context) {
lst, err := models.NotifyChannelsGet(rt.Ctx, "", nil)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, lst)
}
ginx.NewRender(c).Data(lst, err)
}

View File

@@ -118,7 +118,6 @@ func (rt *Router) notifyRulesGet(c *gin.Context) {
lst, err := models.NotifyRulesGet(rt.Ctx, "", nil)
ginx.Dangerous(err)
models.FillUpdateByNicknames(rt.Ctx, lst)
if me.IsAdmin() {
ginx.NewRender(c).Data(lst, nil)
return

View File

@@ -25,14 +25,11 @@ func (rt *Router) notifyTplGets(c *gin.Context) {
m[models.EmailSubject] = struct{}{}
lst, err := models.NotifyTplGets(rt.Ctx)
ginx.Dangerous(err)
for i := 0; i < len(lst); i++ {
if _, exists := m[lst[i].Channel]; exists {
lst[i].BuiltIn = true
}
}
models.FillUpdateByNicknames(rt.Ctx, lst)
ginx.NewRender(c).Data(lst, err)
}
@@ -203,9 +200,6 @@ func (rt *Router) messageTemplateGets(c *gin.Context) {
ident := ginx.QueryStr(c, "ident", "")
tpls, err := models.MessageTemplateGets(rt.Ctx, id, name, ident)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, tpls)
}
ginx.NewRender(c).Data(tpls, err)
}

View File

@@ -15,9 +15,6 @@ import (
func (rt *Router) recordingRuleGets(c *gin.Context) {
busiGroupId := ginx.UrlParamInt64(c, "id")
ars, err := models.RecordingRuleGets(rt.Ctx, busiGroupId)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, ars)
}
ginx.NewRender(c).Data(ars, err)
}
@@ -42,9 +39,6 @@ func (rt *Router) recordingRuleGetsByGids(c *gin.Context) {
}
ars, err := models.RecordingRuleGetsByBGIds(rt.Ctx, gids)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, ars)
}
ginx.NewRender(c).Data(ars, err)
}
@@ -118,7 +112,6 @@ func (rt *Router) recordingRulePutByFE(c *gin.Context) {
}
rt.bgrwCheck(c, ar.GroupId)
rt.bgroCheck(c, f.GroupId)
f.UpdateBy = c.MustGet("username").(string)
ginx.NewRender(c).Message(ar.Update(rt.Ctx, f))

View File

@@ -20,7 +20,6 @@ func (rt *Router) savedViewGets(c *gin.Context) {
ginx.NewRender(c).Data(nil, err)
return
}
models.FillUpdateByNicknames(rt.Ctx, lst)
userGids, err := models.MyGroupIds(rt.Ctx, me.Id)
if err != nil {

View File

@@ -25,7 +25,6 @@ func (rt *Router) taskTplGets(c *gin.Context) {
list, err := models.TaskTplGets(rt.Ctx, []int64{groupId}, query, limit, ginx.Offset(c, limit))
ginx.Dangerous(err)
models.FillUpdateByNicknames(rt.Ctx, list)
ginx.NewRender(c).Data(gin.H{
"total": total,
@@ -61,7 +60,6 @@ func (rt *Router) taskTplGetsByGids(c *gin.Context) {
list, err := models.TaskTplGets(rt.Ctx, gids, query, limit, ginx.Offset(c, limit))
ginx.Dangerous(err)
models.FillUpdateByNicknames(rt.Ctx, list)
ginx.NewRender(c).Data(gin.H{
"total": total,

View File

@@ -27,9 +27,6 @@ func (rt *Router) userGroupGets(c *gin.Context) {
me := c.MustGet("user").(*models.User)
lst, err := me.UserGroups(rt.Ctx, limit, query)
if err == nil {
models.FillUpdateByNicknames(rt.Ctx, lst)
}
ginx.NewRender(c).Data(lst, err)
}

View File

@@ -192,7 +192,6 @@ type AlertMute struct {
Activated int `json:"activated" gorm:"-"` // 0: not activated, 1: activated
CreateBy string `json:"create_by"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
ITags []TagFilter `json:"-" gorm:"-"` // inner tags

View File

@@ -45,7 +45,6 @@ type AlertSubscribe struct {
CreateAt int64 `json:"create_at"`
UpdateBy string `json:"update_by"`
UpdateAt int64 `json:"update_at"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
ITags []TagFilter `json:"-" gorm:"-"` // inner tags
BusiGroups ormx.JSONArr `json:"busi_groups"`
IBusiGroups []TagFilter `json:"-" gorm:"-"` // inner busiGroups

View File

@@ -19,23 +19,22 @@ const (
)
type Board struct {
Id int64 `json:"id" gorm:"primaryKey"`
GroupId int64 `json:"group_id"`
Name string `json:"name"`
Ident string `json:"ident"`
Tags string `json:"tags"`
Note string `json:"note"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
Configs string `json:"configs" gorm:"-"`
Public int `json:"public"` // 0: false, 1: true
PublicCate int `json:"public_cate"` // 0: anonymous, 1: login, 2: busi
Bgids []int64 `json:"bgids" gorm:"-"`
BuiltIn int `json:"built_in"` // 0: false, 1: true
Hide int `json:"hide"` // 0: false, 1: true
Id int64 `json:"id" gorm:"primaryKey"`
GroupId int64 `json:"group_id"`
Name string `json:"name"`
Ident string `json:"ident"`
Tags string `json:"tags"`
Note string `json:"note"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
Configs string `json:"configs" gorm:"-"`
Public int `json:"public"` // 0: false, 1: true
PublicCate int `json:"public_cate"` // 0: anonymous, 1: login, 2: busi
Bgids []int64 `json:"bgids" gorm:"-"`
BuiltIn int `json:"built_in"` // 0: false, 1: true
Hide int `json:"hide"` // 0: false, 1: true
}
func (b *Board) TableName() string {

View File

@@ -9,15 +9,14 @@ import (
)
type MetricFilter struct {
ID int64 `json:"id" gorm:"primaryKey;type:bigint;autoIncrement;comment:'unique identifier'"`
Name string `json:"name" gorm:"type:varchar(191);not null;index:idx_metricfilter_name,sort:asc;comment:'name of metric filter'"`
Configs string `json:"configs" gorm:"type:varchar(4096);not null;comment:'configuration of metric filter'"`
GroupsPerm []GroupPerm `json:"groups_perm" gorm:"type:text;serializer:json;"`
CreateAt int64 `json:"create_at" gorm:"type:bigint;not null;default:0;comment:'create time'"`
CreateBy string `json:"create_by" gorm:"type:varchar(191);not null;default:'';comment:'creator'"`
UpdateAt int64 `json:"update_at" gorm:"type:bigint;not null;default:0;comment:'update time'"`
UpdateBy string `json:"update_by" gorm:"type:varchar(191);not null;default:'';comment:'updater'"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
ID int64 `json:"id" gorm:"primaryKey;type:bigint;autoIncrement;comment:'unique identifier'"`
Name string `json:"name" gorm:"type:varchar(191);not null;index:idx_metricfilter_name,sort:asc;comment:'name of metric filter'"`
Configs string `json:"configs" gorm:"type:varchar(4096);not null;comment:'configuration of metric filter'"`
GroupsPerm []GroupPerm `json:"groups_perm" gorm:"type:text;serializer:json;"`
CreateAt int64 `json:"create_at" gorm:"type:bigint;not null;default:0;comment:'create time'"`
CreateBy string `json:"create_by" gorm:"type:varchar(191);not null;default:'';comment:'creator'"`
UpdateAt int64 `json:"update_at" gorm:"type:bigint;not null;default:0;comment:'update time'"`
UpdateBy string `json:"update_by" gorm:"type:varchar(191);not null;default:'';comment:'updater'"`
}
type GroupPerm struct {

View File

@@ -12,17 +12,16 @@ import (
)
type BusiGroup struct {
Id int64 `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
LabelEnable int `json:"label_enable"`
LabelValue string `json:"label_value"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
UserGroups []UserGroupWithPermFlag `json:"user_groups" gorm:"-"`
DB *gorm.DB `json:"-" gorm:"-"`
Id int64 `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
LabelEnable int `json:"label_enable"`
LabelValue string `json:"label_value"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UserGroups []UserGroupWithPermFlag `json:"user_groups" gorm:"-"`
DB *gorm.DB `json:"-" gorm:"-"`
}
func New(db *gorm.DB) *BusiGroup {

View File

@@ -20,17 +20,16 @@ import (
)
type Configs struct { //ckey+external
Id int64 `json:"id" gorm:"primaryKey"`
Ckey string `json:"ckey"` // Before inserting external configs, check if they are already defined as built-in configs.
Cval string `json:"cval"`
Note string `json:"note"`
External int `json:"external"` //Controls frontend list display: 0 hides built-in (default), 1 shows external
Encrypted int `json:"encrypted"` //Indicates whether the value(cval) is encrypted (1 for ciphertext, 0 for plaintext(default))
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
Id int64 `json:"id" gorm:"primaryKey"`
Ckey string `json:"ckey"` // Before inserting external configs, check if they are already defined as built-in configs.
Cval string `json:"cval"`
Note string `json:"note"`
External int `json:"external"` //Controls frontend list display: 0 hides built-in (default), 1 shows external
Encrypted int `json:"encrypted"` //Indicates whether the value(cval) is encrypted (1 for ciphertext, 0 for plaintext(default))
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
}
func (Configs) TableName() string {

View File

@@ -7,20 +7,19 @@ import (
)
type DashAnnotation struct {
Id int64 `json:"id" gorm:"primaryKey"`
DashboardId int64 `json:"dashboard_id"`
PanelId string `json:"panel_id"`
Tags string `json:"-"`
TagsJSON []string `json:"tags" gorm:"-"`
Description string `json:"description"`
Config string `json:"config"`
TimeStart int64 `json:"time_start"`
TimeEnd int64 `json:"time_end"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
Id int64 `json:"id" gorm:"primaryKey"`
DashboardId int64 `json:"dashboard_id"`
PanelId string `json:"panel_id"`
Tags string `json:"-"`
TagsJSON []string `json:"tags" gorm:"-"`
Description string `json:"description"`
Config string `json:"config"`
TimeStart int64 `json:"time_start"`
TimeEnd int64 `json:"time_end"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
}
func (da *DashAnnotation) TableName() string {

View File

@@ -517,8 +517,7 @@ func (ds *Datasource) Encrypt(openRsa bool, publicKeyData []byte) error {
// Decrypt 用于 edge 将从中心同步的数据源解密,中心不可调用
func (ds *Datasource) Decrypt() error {
if rsaConfig == nil {
logger.Debugf("datasource %s rsa config is nil", ds.Name)
return nil
return errors.New("rsa config is nil")
}
if !rsaConfig.OpenRSA {

View File

@@ -14,16 +14,15 @@ import (
)
type EmbeddedProduct struct {
ID int64 `json:"id" gorm:"primaryKey"` // 主键
Name string `json:"name" gorm:"column:name;type:varchar(255)"`
URL string `json:"url" gorm:"column:url;type:varchar(255)"`
IsPrivate bool `json:"is_private" gorm:"column:is_private;type:boolean"`
TeamIDs []int64 `json:"team_ids" gorm:"serializer:json"`
CreateAt int64 `json:"create_at" gorm:"column:create_at;not null;default:0"`
CreateBy string `json:"create_by" gorm:"column:create_by;type:varchar(64);not null;default:''"`
UpdateAt int64 `json:"update_at" gorm:"column:update_at;not null;default:0"`
UpdateBy string `json:"update_by" gorm:"column:update_by;type:varchar(64);not null;default:''"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
ID int64 `json:"id" gorm:"primaryKey"` // 主键
Name string `json:"name" gorm:"column:name;type:varchar(255)"`
URL string `json:"url" gorm:"column:url;type:varchar(255)"`
IsPrivate bool `json:"is_private" gorm:"column:is_private;type:boolean"`
TeamIDs []int64 `json:"team_ids" gorm:"serializer:json"`
CreateAt int64 `json:"create_at" gorm:"column:create_at;not null;default:0"`
CreateBy string `json:"create_by" gorm:"column:create_by;type:varchar(64);not null;default:''"`
UpdateAt int64 `json:"update_at" gorm:"column:update_at;not null;default:0"`
UpdateBy string `json:"update_by" gorm:"column:update_by;type:varchar(64);not null;default:''"`
}
func (e *EmbeddedProduct) TableName() string {

View File

@@ -24,7 +24,6 @@ type EsIndexPattern struct {
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
CrossClusterEnabled int `json:"cross_cluster_enabled"`
Note string `json:"note"`
}

View File

@@ -32,11 +32,10 @@ type EventPipeline struct {
// 输入参数(工作流级别的配置变量)
Inputs []InputVariable `json:"inputs,omitempty" gorm:"type:text;serializer:json"`
CreateAt int64 `json:"create_at" gorm:"type:bigint"`
CreateBy string `json:"create_by" gorm:"type:varchar(64)"`
UpdateAt int64 `json:"update_at" gorm:"type:bigint"`
UpdateBy string `json:"update_by" gorm:"type:varchar(64)"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
CreateAt int64 `json:"create_at" gorm:"type:bigint"`
CreateBy string `json:"create_by" gorm:"type:varchar(64)"`
UpdateAt int64 `json:"update_at" gorm:"type:bigint"`
UpdateBy string `json:"update_by" gorm:"type:varchar(64)"`
}
type ProcessorConfig struct {

View File

@@ -7,8 +7,8 @@ import (
"github.com/ccfos/nightingale/v6/pkg/ctx"
"github.com/ccfos/nightingale/v6/pkg/poster"
"gorm.io/gorm"
"gorm.io/gorm"
)
// 执行状态常量

View File

@@ -31,7 +31,6 @@ type MessageTemplate struct {
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
}
func MessageTemplateStatistics(ctx *ctx.Context) (*Statistics, error) {

View File

@@ -57,12 +57,11 @@ type NotifyChannelConfig struct {
RequestType string `json:"request_type"` // http, stmp, script, flashduty
RequestConfig *RequestConfig `json:"request_config,omitempty" gorm:"serializer:json"`
Weight int `json:"weight"` // 权重,根据此字段对内置模板进行排序
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
Weight int `json:"weight"` // 权重,根据此字段对内置模板进行排序
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
}
func (ncc *NotifyChannelConfig) TableName() string {

View File

@@ -24,11 +24,10 @@ type NotifyRule struct {
NotifyConfigs []NotifyConfig `json:"notify_configs" gorm:"serializer:json"`
ExtraConfig interface{} `json:"extra_config,omitempty" gorm:"serializer:json"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
}
type PipelineConfig struct {

View File

@@ -17,16 +17,15 @@ import (
)
type NotifyTpl struct {
Id int64 `json:"id"`
Name string `json:"name"`
Channel string `json:"channel"`
Content string `json:"content"`
BuiltIn bool `json:"built_in" gorm:"-"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
Id int64 `json:"id"`
Name string `json:"name"`
Channel string `json:"channel"`
Content string `json:"content"`
BuiltIn bool `json:"built_in" gorm:"-"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
}
func (n *NotifyTpl) TableName() string {

View File

@@ -36,7 +36,6 @@ type RecordingRule struct {
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
}
type QueryConfig struct {
@@ -213,6 +212,7 @@ func (re *RecordingRule) Update(ctx *ctx.Context, ref RecordingRule) error {
ref.FE2DB()
ref.Id = re.Id
ref.GroupId = re.GroupId
ref.CreateAt = re.CreateAt
ref.CreateBy = re.CreateBy
ref.UpdateAt = time.Now().Unix()

View File

@@ -16,17 +16,16 @@ var (
)
type SavedView struct {
Id int64 `json:"id" gorm:"primaryKey;autoIncrement"`
Name string `json:"name" gorm:"type:varchar(255);not null"`
Page string `json:"page" gorm:"type:varchar(64);not null;index"`
Filter string `json:"filter" gorm:"type:text"`
PublicCate int `json:"public_cate" gorm:"default:0"` // 0: self, 1: team, 2: all
Gids []int64 `json:"gids" gorm:"column:gids;type:text;serializer:json"`
CreateAt int64 `json:"create_at" gorm:"type:bigint;not null;default:0"`
CreateBy string `json:"create_by" gorm:"type:varchar(64);index"`
UpdateAt int64 `json:"update_at" gorm:"type:bigint;not null;default:0"`
UpdateBy string `json:"update_by" gorm:"type:varchar(64)"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
Id int64 `json:"id" gorm:"primaryKey;autoIncrement"`
Name string `json:"name" gorm:"type:varchar(255);not null"`
Page string `json:"page" gorm:"type:varchar(64);not null;index"`
Filter string `json:"filter" gorm:"type:text"`
PublicCate int `json:"public_cate" gorm:"default:0"` // 0: self, 1: team, 2: all
Gids []int64 `json:"gids" gorm:"column:gids;type:text;serializer:json"`
CreateAt int64 `json:"create_at" gorm:"type:bigint;not null;default:0"`
CreateBy string `json:"create_by" gorm:"type:varchar(64);index"`
UpdateAt int64 `json:"update_at" gorm:"type:bigint;not null;default:0"`
UpdateBy string `json:"update_by" gorm:"type:varchar(64)"`
// 查询时填充的字段
IsFavorite bool `json:"is_favorite" gorm:"-"`

View File

@@ -15,23 +15,22 @@ import (
)
type TaskTpl struct {
Id int64 `json:"id" gorm:"primaryKey"`
GroupId int64 `json:"group_id"`
Title string `json:"title"`
Batch int `json:"batch"`
Tolerance int `json:"tolerance"`
Timeout int `json:"timeout"`
Pause string `json:"pause"`
Script string `json:"script"`
Args string `json:"args"`
Tags string `json:"-"`
TagsJSON []string `json:"tags" gorm:"-"`
Account string `json:"account"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
Id int64 `json:"id" gorm:"primaryKey"`
GroupId int64 `json:"group_id"`
Title string `json:"title"`
Batch int `json:"batch"`
Tolerance int `json:"tolerance"`
Timeout int `json:"timeout"`
Pause string `json:"pause"`
Script string `json:"script"`
Args string `json:"args"`
Tags string `json:"-"`
TagsJSON []string `json:"tags" gorm:"-"`
Account string `json:"account"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
}
func (t *TaskTpl) TableName() string {

View File

@@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"os"
"reflect"
"regexp"
"strconv"
"strings"
@@ -411,80 +410,6 @@ func UserMapGet(ctx *ctx.Context, where string, args ...interface{}) map[string]
return um
}
// UserNicknameMap returns a deduplicated username -> nickname map.
func UserNicknameMap(ctx *ctx.Context, names []string) map[string]string {
m := make(map[string]string)
if len(names) == 0 {
return m
}
seen := make(map[string]struct{}, len(names))
unique := make([]string, 0, len(names))
for _, name := range names {
if name == "" {
continue
}
if _, ok := seen[name]; ok {
continue
}
seen[name] = struct{}{}
unique = append(unique, name)
}
if len(unique) == 0 {
return m
}
users := UserMapGet(ctx, "username in (?)", unique)
for username, user := range users {
m[username] = user.Nickname
}
return m
}
// FillUpdateByNicknames fills the UpdateByNickname field for each element in items
// by looking up the UpdateBy username. Supports both []T and []*T slices.
func FillUpdateByNicknames[T any](ctx *ctx.Context, items []T) {
if len(items) == 0 {
return
}
elemType := reflect.TypeOf(items).Elem()
isPtr := elemType.Kind() == reflect.Ptr
if isPtr {
elemType = elemType.Elem()
}
updateByField, ok1 := elemType.FieldByName("UpdateBy")
nicknameField, ok2 := elemType.FieldByName("UpdateByNickname")
if !ok1 || !ok2 {
return
}
names := make([]string, 0, len(items))
for i := range items {
v := reflect.ValueOf(&items[i]).Elem()
if isPtr {
if v.IsNil() {
continue
}
v = v.Elem()
}
names = append(names, v.FieldByIndex(updateByField.Index).String())
}
nm := UserNicknameMap(ctx, names)
for i := range items {
v := reflect.ValueOf(&items[i]).Elem()
if isPtr {
if v.IsNil() {
continue
}
v = v.Elem()
}
updateBy := v.FieldByIndex(updateByField.Index).String()
v.FieldByIndex(nicknameField.Index).SetString(nm[updateBy])
}
}
func UserGetByUsername(ctx *ctx.Context, username string) (*User, error) {
return UserGet(ctx, "username=?", username)
}

View File

@@ -12,17 +12,16 @@ import (
)
type UserGroup struct {
Id int64 `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
Note string `json:"note"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UpdateByNickname string `json:"update_by_nickname" gorm:"-"`
UserIds []int64 `json:"-" gorm:"-"`
Users []User `json:"users" gorm:"-"`
BusiGroups []*BusiGroup `json:"busi_groups" gorm:"-"`
Id int64 `json:"id" gorm:"primaryKey"`
Name string `json:"name"`
Note string `json:"note"`
CreateAt int64 `json:"create_at"`
CreateBy string `json:"create_by"`
UpdateAt int64 `json:"update_at"`
UpdateBy string `json:"update_by"`
UserIds []int64 `json:"-" gorm:"-"`
Users []User `json:"users" gorm:"-"`
BusiGroups []*BusiGroup `json:"busi_groups" gorm:"-"`
}
func (ug *UserGroup) TableName() string {

View File

@@ -312,8 +312,6 @@ func (s *SsoClient) Callback(redis storage.Redis, ctx context.Context, code, sta
// 根据UsernameField配置确定username
switch s.FeiShuConfig.UsernameField {
case "userid":
callbackOutput.Username = username
case "name":
if nickname == "" {
return nil, errors.New("feishu user name is empty")

View File

@@ -248,7 +248,7 @@ func (s *Set) writeTargetTsInRedis(ctx context.Context, redis storage.Redis, con
for i := 0; i < retryCount; i++ {
start := time.Now()
err := storage.MSet(ctx, redis, content, 24*time.Hour)
err := storage.MSet(ctx, redis, content)
duration := time.Since(start).Seconds()
logger.Debugf("update_ts: write target ts in redis, keys: %v, retryCount: %d, retryInterval: %v, error: %v", keys, retryCount, retryInterval, err)

View File

@@ -35,12 +35,6 @@ type Pushgw struct {
WriterOpt WriterGlobalOpt
Writers []WriterOptions
KafkaWriters []KafkaWriterOptions
// 预处理的字段,用于快速匹配只有 __name__ 的 DropSample 规则
// key: metric name, value: struct{}
DropMetricNames map[string]struct{}
// 包含多个标签的复杂 DropSample 规则
DropSampleComplex []map[string]string
}
type WriterGlobalOpt struct {

View File

@@ -109,30 +109,21 @@ func (rt *Router) debugSample(remoteAddr string, v *prompb.TimeSeries) {
}
func (rt *Router) DropSample(v *prompb.TimeSeries) bool {
// 快速路径:检查仅 __name__ 的过滤器 O(1)
if len(rt.dropByNameOnly) > 0 {
for i := 0; i < len(v.Labels); i++ {
if v.Labels[i].Name == "__name__" {
if _, ok := rt.dropByNameOnly[v.Labels[i].Value]; ok {
return true
}
break // __name__ 只会出现一次,找到后直接跳出
}
}
}
// 慢速路径:处理复杂的多条件过滤器
if len(rt.dropComplex) == 0 {
filters := rt.Pushgw.DropSample
if len(filters) == 0 {
return false
}
// 只有复杂过滤器存在时才创建 labelMap
labelMap := make(map[string]string, len(v.Labels))
labelMap := make(map[string]string)
for i := 0; i < len(v.Labels); i++ {
labelMap[v.Labels[i].Name] = v.Labels[i].Value
}
for _, filter := range rt.dropComplex {
for _, filter := range filters {
if len(filter) == 0 {
continue
}
if matchSample(filter, labelMap) {
return true
}

View File

@@ -6,7 +6,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/prometheus/prometheus/prompb"
"github.com/toolkits/pkg/logger"
"github.com/ccfos/nightingale/v6/alert/aconf"
"github.com/ccfos/nightingale/v6/center/metas"
@@ -34,10 +33,6 @@ type Router struct {
Ctx *ctx.Context
HandleTS HandleTSFunc
HeartbeatApi string
// 预编译的 DropSample 过滤器
dropByNameOnly map[string]struct{} // 仅 __name__ 条件的快速匹配
dropComplex []map[string]string // 多条件的复杂匹配
}
func stat() gin.HandlerFunc {
@@ -56,7 +51,7 @@ func stat() gin.HandlerFunc {
func New(httpConfig httpx.Config, pushgw pconf.Pushgw, aconf aconf.Alert, tc *memsto.TargetCacheType, bg *memsto.BusiGroupCacheType,
idents *idents.Set, metas *metas.Set,
writers *writer.WritersType, ctx *ctx.Context) *Router {
rt := &Router{
return &Router{
HTTP: httpConfig,
Pushgw: pushgw,
Aconf: aconf,
@@ -68,38 +63,6 @@ func New(httpConfig httpx.Config, pushgw pconf.Pushgw, aconf aconf.Alert, tc *me
MetaSet: metas,
HandleTS: func(pt *prompb.TimeSeries) *prompb.TimeSeries { return pt },
}
// 预编译 DropSample 过滤器
rt.initDropSampleFilters()
return rt
}
// initDropSampleFilters 预编译 DropSample 过滤器,将单条件 __name__ 过滤器
// 放入 map 实现 O(1) 查找,多条件过滤器保留原有逻辑
func (rt *Router) initDropSampleFilters() {
rt.dropByNameOnly = make(map[string]struct{})
rt.dropComplex = make([]map[string]string, 0)
for _, filter := range rt.Pushgw.DropSample {
if len(filter) == 0 {
continue
}
// 如果只有一个条件且是 __name__放入快速匹配 map
if len(filter) == 1 {
if name, ok := filter["__name__"]; ok {
rt.dropByNameOnly[name] = struct{}{}
continue
}
}
// 其他情况放入复杂匹配列表
rt.dropComplex = append(rt.dropComplex, filter)
}
logger.Infof("DropSample filters initialized: %d name-only, %d complex",
len(rt.dropByNameOnly), len(rt.dropComplex))
}
func (rt *Router) Config(r *gin.Engine) {

View File

@@ -163,10 +163,10 @@ func MGet(ctx context.Context, r Redis, keys []string) [][]byte {
return vals
}
func MSet(ctx context.Context, r Redis, m map[string]interface{}, expiration time.Duration) error {
func MSet(ctx context.Context, r Redis, m map[string]interface{}) error {
pipe := r.Pipeline()
for k, v := range m {
pipe.Set(ctx, k, v, expiration)
pipe.Set(ctx, k, v, 0)
}
_, err := pipe.Exec(ctx)
return err

View File

@@ -30,7 +30,7 @@ func TestMiniRedisMGet(t *testing.T) {
mp["key2"] = "value2"
mp["key3"] = "value3"
err = MSet(context.Background(), rdb, mp, 0)
err = MSet(context.Background(), rdb, mp)
if err != nil {
t.Fatalf("failed to set miniredis value: %v", err)
}