router_collect_rule.go 5.7 KB
Newer Older
7
3.0.0  
710leo 已提交
1 2 3 4 5
package http

import (
	"regexp"
	"strings"
Q
qinyening 已提交
6
	"time"
7
3.0.0  
710leo 已提交
7 8

	"github.com/gin-gonic/gin"
Q
qinyening 已提交
9 10 11

	"github.com/didi/nightingale/v5/cache"
	"github.com/didi/nightingale/v5/models"
7
710leo 已提交
12
	"github.com/didi/nightingale/v5/pkg/i18n"
7
3.0.0  
710leo 已提交
13 14
)

Q
qinyening 已提交
15 16 17 18 19 20 21 22 23
type collectRuleForm struct {
	ClasspathId int64  `json:"classpath_id"`
	PrefixMatch int    `json:"prefix_match"`
	Name        string `json:"name"`
	Note        string `json:"note"`
	Step        int    `json:"step"`
	Type        string `json:"type"`
	Data        string `json:"data"`
	AppendTags  string `json:"append_tags"`
7
3.0.0  
710leo 已提交
24 25
}

Q
qinyening 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
func collectRuleAdd(c *gin.Context) {
	var f collectRuleForm
	bind(c, &f)

	me := loginUser(c).MustPerm("collect_rule_create")

	cr := models.CollectRule{
		ClasspathId: f.ClasspathId,
		PrefixMatch: f.PrefixMatch,
		Name:        f.Name,
		Note:        f.Note,
		Step:        f.Step,
		Type:        f.Type,
		Data:        f.Data,
		AppendTags:  f.AppendTags,
		CreateBy:    me.Username,
		UpdateBy:    me.Username,
7
3.0.0  
710leo 已提交
43 44
	}

Q
qinyening 已提交
45
	renderMessage(c, cr.Add())
7
3.0.0  
710leo 已提交
46 47
}

Q
qinyening 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
func collectRulePut(c *gin.Context) {
	var f collectRuleForm
	bind(c, &f)

	me := loginUser(c).MustPerm("collect_rule_modify")
	cr := CollectRule(urlParamInt64(c, "id"))

	cr.PrefixMatch = f.PrefixMatch
	cr.Name = f.Name
	cr.Note = f.Note
	cr.Step = f.Step
	cr.Type = f.Type
	cr.Data = f.Data
	cr.AppendTags = f.AppendTags
	cr.UpdateAt = time.Now().Unix()
	cr.UpdateBy = me.Username

	renderMessage(c, cr.Update(
		"prefix_match",
		"name",
		"note",
		"step",
		"type",
		"data",
		"update_at",
		"update_by",
		"append_tags",
	))
7
3.0.0  
710leo 已提交
76 77
}

Q
qinyening 已提交
78 79 80 81 82 83
func collectRuleDel(c *gin.Context) {
	var f idsForm
	bind(c, &f)
	f.Validate()
	loginUser(c).MustPerm("collect_rule_delete")
	renderMessage(c, models.CollectRulesDel(f.Ids))
7
3.0.0  
710leo 已提交
84 85
}

Q
qinyening 已提交
86 87
func collectRuleGets(c *gin.Context) {
	classpathId := urlParamInt64(c, "id")
7
3.0.0  
710leo 已提交
88

Q
qinyening 已提交
89 90
	where := "classpath_id = ?"
	param := []interface{}{classpathId}
Y
yubo 已提交
91

Q
qinyening 已提交
92 93 94 95
	typ := queryStr(c, "type", "")
	if typ != "" {
		where += " and type = ?"
		param = append(param, typ)
7
3.0.0  
710leo 已提交
96 97
	}

Q
qinyening 已提交
98 99
	objs, err := models.CollectRuleGets(where, param...)
	renderData(c, objs, err)
7
3.0.0  
710leo 已提交
100 101
}

Q
qinyening 已提交
102 103
func collectRuleGetsByIdent(c *gin.Context) {
	ident := queryStr(c, "ident")
104

Q
qinyening 已提交
105 106
	objs := cache.CollectRulesOfIdent.GetBy(ident)
	renderData(c, objs, nil)
107 108
}

Q
qinyening 已提交
109 110 111
type Summary struct {
	LatestUpdatedAt int64 `json:"latestUpdatedAt"`
	Total           int   `json:"total"`
7
3.0.0  
710leo 已提交
112 113
}

Q
qinyening 已提交
114 115 116 117 118 119 120 121 122 123 124
func collectRuleSummaryGetByIdent(c *gin.Context) {
	ident := queryStr(c, "ident")
	var summary Summary
	objs := cache.CollectRulesOfIdent.GetBy(ident)
	total := len(objs)
	if total > 0 {
		summary.Total = total
		var latestUpdatedAt int64
		for _, obj := range objs {
			if latestUpdatedAt < obj.UpdateAt {
				latestUpdatedAt = obj.UpdateAt
7
3.0.0  
710leo 已提交
125 126
			}
		}
Q
qinyening 已提交
127
		summary.LatestUpdatedAt = latestUpdatedAt
7
3.0.0  
710leo 已提交
128 129
	}

Q
qinyening 已提交
130
	renderData(c, summary, nil)
7
3.0.0  
710leo 已提交
131 132
}

Q
qinyening 已提交
133
type RegExpCheck struct {
7
3.0.0  
710leo 已提交
134 135 136 137 138
	Success bool                `json:"success"`
	Data    []map[string]string `json:"tags"`
}

func regExpCheck(c *gin.Context) {
Q
qinyening 已提交
139 140
	param := make(map[string]string)
	dangerous(c.ShouldBind(&param))
7
3.0.0  
710leo 已提交
141

Q
qinyening 已提交
142
	ret := &RegExpCheck{
7
3.0.0  
710leo 已提交
143 144 145 146
		Success: true,
		Data:    make([]map[string]string, 0),
	}

7
710leo 已提交
147 148 149
	calcMethod := param["func"]
	if calcMethod == "" {
		tmp := map[string]string{"func": "is empty"}
7
3.0.0  
710leo 已提交
150
		ret.Data = append(ret.Data, tmp)
7
710leo 已提交
151 152
		renderData(c, ret, nil)
		return
7
3.0.0  
710leo 已提交
153 154
	}

7
710leo 已提交
155
	// 处理主正则
7
3.0.0  
710leo 已提交
156
	if re, ok := param["re"]; !ok || re == "" {
7
710leo 已提交
157
		tmp := map[string]string{"re": "regex does not exist or is empty"}
7
3.0.0  
710leo 已提交
158
		ret.Data = append(ret.Data, tmp)
7
710leo 已提交
159 160 161
		renderData(c, ret, nil)
		return
	}
7
3.0.0  
710leo 已提交
162

7
710leo 已提交
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
	// 匹配主正则
	suc, reRes, isSub := checkRegex(param["re"], param["log"])
	if !suc {
		ret.Success = false
		reRes = genErrMsg("re")
		ret.Data = append(ret.Data, map[string]string{"re": reRes})
		renderData(c, ret, nil)
		return
	}
	if calcMethod == "histogram" && !isSub {
		ret.Success = false
		reRes = genSubErrMsg("re")
		ret.Data = append(ret.Data, map[string]string{"re": reRes})
		renderData(c, ret, nil)
		return
7
3.0.0  
710leo 已提交
178 179
	}

7
710leo 已提交
180
	ret.Data = append(ret.Data, map[string]string{"re": reRes})
7
3.0.0  
710leo 已提交
181 182
	// 处理tags
	var nonTagKey = map[string]bool{
7
710leo 已提交
183 184 185
		"re":   true,
		"log":  true,
		"func": true,
7
3.0.0  
710leo 已提交
186 187 188 189 190 191 192
	}

	for tagk, pat := range param {
		// 如果不是tag,就继续循环
		if _, ok := nonTagKey[tagk]; ok {
			continue
		}
7
710leo 已提交
193
		suc, tagRes, isSub := checkRegex(pat, param["log"])
7
3.0.0  
710leo 已提交
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
		if !suc {
			// 正则错误
			ret.Success = false
			tagRes = genErrMsg(tagk)
		} else if !isSub {
			// 未匹配出子串
			ret.Success = false
			tagRes = genSubErrMsg(tagk)
		} else if includeIllegalChar(tagRes) || includeIllegalChar(tagk) {
			// 保留字报错
			ret.Success = false
			tagRes = genIllegalCharErrMsg()
		}

		tmp := map[string]string{tagk: tagRes}
		ret.Data = append(ret.Data, tmp)
	}

	renderData(c, ret, nil)
}

// 出错信息直接放在body里
7
710leo 已提交
216
func checkRegex(pat string, log string) (succ bool, result string, isSub bool) {
7
3.0.0  
710leo 已提交
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
	if pat == "" {
		return false, "", false
	}

	reg, err := regexp.Compile(pat)
	if err != nil {
		return false, "", false
	}

	res := reg.FindStringSubmatch(log)
	switch len(res) {
	// 没查到
	case 0:
		return false, "", false
	// 没查到括号内的串,返回整个匹配串
	case 1:
		return true, res[0], false
	// 查到了,默认取第一个串
	default:
7
710leo 已提交
236
		return true, res[1], true
7
3.0.0  
710leo 已提交
237 238 239 240 241 242 243 244 245 246
	}
}

func includeIllegalChar(s string) bool {
	illegalChars := ":,=\r\n\t"
	return strings.ContainsAny(s, illegalChars)
}

// 生成返回错误信息
func genErrMsg(sign string) string {
7
710leo 已提交
247
	return i18n.Sprintf("regular match failed, please check your configuration:[%s]", sign)
7
3.0.0  
710leo 已提交
248 249 250 251
}

// 生成子串匹配错误信息
func genSubErrMsg(sign string) string {
7
710leo 已提交
252
	return i18n.Sprintf("regular match was successful. according to the configuration, it does not get the substring inside(), please check your configuration:[%s]", sign)
7
3.0.0  
710leo 已提交
253 254 255 256
}

// 生成子串匹配错误信息
func genIllegalCharErrMsg() string {
7
710leo 已提交
257
	return i18n.Sprintf(`key or value of tag contains illegal characters:[:,/=\r\n\t]`)
Q
qinyening 已提交
258
}