@ -1,16 +1,15 @@
package http
import (
"fmt"
"regexp"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/toolkits/pkg/logger"
"github.com/didi/nightingale/v5/cache"
"github.com/didi/nightingale/v5/models"
"github.com/didi/nightingale/v5/pkg/i18n"
)
type collectRuleForm struct {
@ -136,8 +135,6 @@ type RegExpCheck struct {
Data [ ] map [ string ] string ` json:"tags" `
}
var RegExpExcludePatition string = "```EXCLUDE```"
func regExpCheck ( c * gin . Context ) {
param := make ( map [ string ] string )
dangerous ( c . ShouldBind ( & param ) )
@ -147,75 +144,45 @@ func regExpCheck(c *gin.Context) {
Data : make ( [ ] map [ string ] string , 0 ) ,
}
// 处理时间格式
if t, ok := param [ "time" ] ; ! ok || t == "" {
tmp := map [ string ] string { " time": "time参数不存在或为空 "}
calcMethod := param [ "func" ]
if calcMethod == "" {
tmp := map [ string ] string { " func": "is empty "}
ret . Data = append ( ret . Data , tmp )
} else {
timePat , _ := GetPatAndTimeFormat ( param [ "time" ] )
if timePat == "" {
tmp := map [ string ] string { "time" : genErrMsg ( "时间格式" ) }
ret . Data = append ( ret . Data , tmp )
} else {
suc , tRes , _ := checkRegPat ( timePat , param [ "log" ] , true )
if ! suc {
ret . Success = false
tRes = genErrMsg ( "时间格式" )
}
tmp := map [ string ] string { "time" : tRes }
ret . Data = append ( ret . Data , tmp )
}
renderData ( c , ret , nil )
return
}
// 计算方式
calc_method := param [ "calc_method" ]
// 处理主正则(with exclude)
// 处理主正则
if re , ok := param [ "re" ] ; ! ok || re == "" {
tmp := map [ string ] string { "re" : "re参数不存在或为空" }
ret . Data = append ( ret . Data , tmp )
} else {
// 处理exclude的情况
exclude := ""
if strings . Contains ( re , RegExpExcludePatition ) {
l := strings . Split ( re , RegExpExcludePatition )
if len ( l ) >= 2 {
param [ "re" ] = l [ 0 ]
exclude = l [ 1 ]
}
}
// 匹配主正则
suc , reRes , isSub := checkRegPat ( param [ "re" ] , param [ "log" ] , false )
if ! suc {
ret . Success = false
reRes = genErrMsg ( "主正则" )
}
if calc_method != "" && calc_method != "cnt" && ! isSub {
ret . Success = false
reRes = genSubErrMsg ( "主正则" )
}
tmp := map [ string ] string { "主正则" : reRes }
tmp := map [ string ] string { "re" : "regex does not exist or is empty" }
ret . Data = append ( ret . Data , tmp )
renderData ( c , ret , nil )
return
}
// 匹配exclude, 这个不影响失败
if exclude != "" {
suc , exRes , _ := checkRegPat ( exclude , param [ "log" ] , false )
if ! suc {
//ret.Success = false
exRes = "未匹配到排除串,请检查是否符合预期"
}
tmp := map [ string ] string { "排除串" : exRes }
ret . Data = append ( ret . Data , tmp )
}
// 匹配主正则
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
}
ret . Data = append ( ret . Data , map [ string ] string { "re" : reRes } )
// 处理tags
var nonTagKey = map [ string ] bool {
"re" : true ,
"log" : true ,
"time" : true ,
"calc_method" : true ,
"re" : true ,
"log" : true ,
"func" : true ,
}
for tagk , pat := range param {
@ -223,7 +190,7 @@ func regExpCheck(c *gin.Context) {
if _ , ok := nonTagKey [ tagk ] ; ok {
continue
}
suc , tagRes , isSub := checkReg Pat ( pat , param [ "log" ] , false )
suc , tagRes , isSub := checkReg ex ( pat , param [ "log" ] )
if ! suc {
// 正则错误
ret . Success = false
@ -245,49 +212,8 @@ func regExpCheck(c *gin.Context) {
renderData ( c , ret , nil )
}
//根据配置的时间格式, 获取对应的正则匹配pattern和time包用的时间格式
func GetPatAndTimeFormat ( tf string ) ( string , string ) {
var pat , timeFormat string
switch tf {
case "dd/mmm/yyyy:HH:MM:SS" :
pat = ` ([012][0-9]|3[01])/[JFMASOND][a-z] { 2}/(2[0-9] { 3}):([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "02/Jan/2006:15:04:05"
case "dd/mmm/yyyy HH:MM:SS" :
pat = ` ([012][0-9]|3[01])/[JFMASOND][a-z] { 2}/(2[0-9] { 3})\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "02/Jan/2006 15:04:05"
case "yyyy-mm-ddTHH:MM:SS" :
pat = ` (2[0-9] { 3})-(0[1-9]|1[012])-([012][0-9]|3[01])T([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "2006-01-02T15:04:05"
case "dd-mmm-yyyy HH:MM:SS" :
pat = ` ([012][0-9]|3[01])-[JFMASOND][a-z] { 2}-(2[0-9] { 3})\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "02-Jan-2006 15:04:05"
case "yyyy-mm-dd HH:MM:SS" :
pat = ` (2[0-9] { 3})-(0[1-9]|1[012])-([012][0-9]|3[01])\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "2006-01-02 15:04:05"
case "yyyy/mm/dd HH:MM:SS" :
pat = ` (2[0-9] { 3})/(0[1-9]|1[012])/([012][0-9]|3[01])\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "2006/01/02 15:04:05"
case "yyyymmdd HH:MM:SS" :
pat = ` (2[0-9] { 3})(0[1-9]|1[012])([012][0-9]|3[01])\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "20060102 15:04:05"
case "mmm dd HH:MM:SS" :
pat = ` [JFMASOND][a-z] { 2}\s+([1-9]|[1-2][0-9]|3[01])\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "Jan 2 15:04:05"
case "mmdd HH:MM:SS" :
pat = ` (0[1-9]|1[012])([012][0-9]|3[01])\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "0102 15:04:05"
case "dd mmm yyyy HH:MM:SS" :
pat = ` ([012][0-9]|3[01])\s+[JFMASOND][a-z] { 2}\s+(2[0-9] { 3})\s([01][0-9]|2[0-4])(:[012345][0-9]) { 2} `
timeFormat = "02 Jan 2006 15:04:05"
default :
logger . Errorf ( "match time pac failed : [timeFormat:%s]" , tf )
return "" , ""
}
return pat , timeFormat
}
// 出错信息直接放在body里
func checkReg Pat ( pat string , log string , origin bool ) ( succ bool , result string , isSub bool ) {
func checkRegex ( pat string , log string ) ( succ bool , result string , isSub bool ) {
if pat == "" {
return false , "" , false
}
@ -307,15 +233,7 @@ func checkRegPat(pat string, log string, origin bool) (succ bool, result string,
return true , res [ 0 ] , false
// 查到了,默认取第一个串
default :
var msg string
if origin {
msg = res [ 0 ]
isSub = false
} else {
msg = res [ 1 ]
isSub = true
}
return true , msg , isSub
return true , res [ 1 ] , true
}
}
@ -326,15 +244,15 @@ func includeIllegalChar(s string) bool {
// 生成返回错误信息
func genErrMsg ( sign string ) string {
return fmt. Sprintf ( "正则匹配失败,请认真检查您[%s]的配置 ", sign )
return i18n. Sprintf ( "regular match failed, please check your configuration:[%s] ", sign )
}
// 生成子串匹配错误信息
func genSubErrMsg ( sign string ) string {
return fmt. Sprintf ( "正则匹配成功。但根据配置,并没有获取到()内的子串,请认真检查您[%s]的配置 ", sign )
return i18n. Sprintf ( "regular match was successful. according to the configuration, it does not get the substring inside(), please check your configuration:[%s] ", sign )
}
// 生成子串匹配错误信息
func genIllegalCharErrMsg ( ) string {
return ` 正则匹配成功。但是tag的key或者value包含非法字符:[:,/=\r\n\t], 请重新调整 `
return i18n . Sprintf ( ` key or value of tag contains illegal characters:[:,/=\r\n\t] ` )
}