diff --git a/cmd/agent/monitor/myip.go b/cmd/agent/monitor/myip.go index e0e540b..c7e91cc 100644 --- a/cmd/agent/monitor/myip.go +++ b/cmd/agent/monitor/myip.go @@ -37,7 +37,7 @@ func UpdateIP() { for { ipv4 := fetchGeoIP(ipv4Servers, false) ipv6 := fetchGeoIP(ipv6Servers, true) - cachedIP = fmt.Sprintf("ip(v4:%s,v6:%s)", ipv4.IP, ipv6.IP) + cachedIP = fmt.Sprintf("ip(v4:%s,v6:[%s])", ipv4.IP, ipv6.IP) if ipv4.CountryCode != "" { cachedCountry = ipv4.CountryCode } else if ipv6.CountryCode != "" { diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index e3480c1..09b5c50 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -292,10 +292,13 @@ func (ma *memberAPI) addOrEditCron(c *gin.Context) { Type: model.TaskTypeCommand, }) } else { - dao.SendNotification(fmt.Sprintf("计划任务:%s,服务器:%d 离线,无法执行。", cr.Name, cr.Servers[j]), false) + dao.SendNotification(fmt.Sprintf("计划任务:%s,服务器:%s 离线,无法执行。", cr.Name, dao.ServerList[cr.Servers[j]].Name), false) } } }) + if err != nil { + panic(err) + } delete(dao.Crons, cr.ID) dao.Crons[cr.ID] = &cr diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index a2c4fa8..6680f56 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -95,7 +95,7 @@ func loadCrons() { Type: model.TaskTypeCommand, }) } else { - dao.SendNotification(fmt.Sprintf("计划任务:%s,服务器:%d 离线,无法执行。", cr.Name, cr.Servers[j]), false) + dao.SendNotification(fmt.Sprintf("计划任务:%s,服务器:%s 离线,无法执行。", cr.Name, dao.ServerList[cr.Servers[j]].Name), false) } } }) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 69c8775..07bd654 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "math/rand" "os" + "regexp" "time" "unsafe" ) @@ -45,3 +46,21 @@ func MD5(plantext string) string { func IsWindows() bool { return os.PathSeparator == '\\' && os.PathListSeparator == ';' } + +var ipv4Re = regexp.MustCompile(`(\d*\.).*(\.\d*)`) + +func ipv4Desensitize(ipv4Addr string) string { + return ipv4Re.ReplaceAllString(ipv4Addr, "$1****$2") +} + +var ipv6Re = regexp.MustCompile(`(\w*:\w*:).*(:\w*:\w*)`) + +func ipv6Desensitize(ipv6Addr string) string { + return ipv6Re.ReplaceAllString(ipv6Addr, "$1****$2") +} + +func IPDesensitize(ipAddr string) string { + ipAddr = ipv4Desensitize(ipAddr) + ipAddr = ipv6Desensitize(ipAddr) + return ipAddr +} diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go new file mode 100644 index 0000000..259150a --- /dev/null +++ b/pkg/utils/utils_test.go @@ -0,0 +1,41 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type testSt struct { + input string + output string +} + +func TestNotification(t *testing.T) { + cases := []testSt{ + { + input: "ip(v4:103.80.236.249,v6:[d5ce:d811:cdb8:067a:a873:2076:9521:9d2d])", + output: "ip(v4:103.****.249,v6:[d5ce:d811:****:9521:9d2d])", + }, + { + input: "ip(v4:3.80.236.29,v6:[d5ce::cdb8:067a:a873:2076:9521:9d2d])", + output: "ip(v4:3.****.29,v6:[d5ce::****:9521:9d2d])", + }, + { + input: "ip(v4:3.80.236.29,v6:[d5ce::cdb8:067a:a873:2076::9d2d])", + output: "ip(v4:3.****.29,v6:[d5ce::****::9d2d])", + }, + { + input: "ip(v4:3.80.236.9,v6:[d5ce::cdb8:067a:a873:2076::9d2d])", + output: "ip(v4:3.****.9,v6:[d5ce::****::9d2d])", + }, + { + input: "ip(v4:3.80.236.9,v6:[d5ce::cdb8:067a:a873:2076::9d2d])", + output: "ip(v4:3.****.9,v6:[d5ce::****::9d2d])", + }, + } + + for _, c := range cases { + assert.Equal(t, IPDesensitize(c.input), c.output) + } +} diff --git a/service/dao/alertsentinel.go b/service/dao/alertsentinel.go index 1ad0a77..973554e 100644 --- a/service/dao/alertsentinel.go +++ b/service/dao/alertsentinel.go @@ -7,6 +7,7 @@ import ( "time" "github.com/naiba/nezha/model" + "github.com/naiba/nezha/pkg/utils" ) // 报警规则 @@ -100,7 +101,7 @@ func checkStatus() { // 发送通知 max, desc := alert.Check(alertsStore[alert.ID][server.ID]) if desc != "" { - message := fmt.Sprintf("报警规则:%s,服务器:%s(%s),%s,逮到咯,快去看看!", alert.Name, server.Name, server.Host.IP, desc) + message := fmt.Sprintf("报警规则:%s,服务器:%s(%s),逮到咯,快去看看!", alert.Name, server.Name, utils.IPDesensitize(server.Host.IP)) go SendNotification(message, true) } // 清理旧数据 diff --git a/service/dao/dao.go b/service/dao/dao.go index 747a670..c7a7286 100644 --- a/service/dao/dao.go +++ b/service/dao/dao.go @@ -69,7 +69,7 @@ func CronTrigger(c *model.Cron) { Type: model.TaskTypeCommand, }) } else { - SendNotification(fmt.Sprintf("计划任务:%s,服务器:%d 离线,无法执行。", c.Name, c.Servers[j]), false) + SendNotification(fmt.Sprintf("计划任务:%s,服务器:%s 离线,无法执行。", c.Name, ServerList[c.Servers[j]].Name), false) } } } diff --git a/service/dao/servicesentinel.go b/service/dao/servicesentinel.go index 7a15532..34fd0cd 100644 --- a/service/dao/servicesentinel.go +++ b/service/dao/servicesentinel.go @@ -275,7 +275,9 @@ func (ss *ServiceSentinel) worker() { } stateStr := getStateStr(upPercent) if Conf.Debug { - log.Println("服务监控上报:", ss.monitors[mh.MonitorID].Target, stateStr, "上报者:", r.Reporter, "是否正常:", mh.Successful, "请求输出:", mh.Data) + ServerLock.RLock() + log.Println("服务监控上报:", ss.monitors[mh.MonitorID].Target, stateStr, "上报者:", ServerList[r.Reporter].Name, "是否正常:", mh.Successful, "请求输出:", mh.Data) + ServerLock.RUnlock() } if stateStr == "故障" || stateStr != ss.lastStatus[mh.MonitorID] { ss.monitorsLock.RLock() diff --git a/service/rpc/nezha.go b/service/rpc/nezha.go index 070062d..162ef47 100644 --- a/service/rpc/nezha.go +++ b/service/rpc/nezha.go @@ -31,11 +31,13 @@ func (s *NezhaHandler) ReportTask(c context.Context, r *pb.TaskResult) (*pb.Rece defer dao.CronLock.RUnlock() cr := dao.Crons[r.GetId()] if cr != nil { + dao.ServerLock.RLock() + defer dao.ServerLock.RUnlock() if cr.PushSuccessful && r.GetSuccessful() { - dao.SendNotification(fmt.Sprintf("成功计划任务:%s ,服务器:%d,日志:\n%s", cr.Name, clientID, r.GetData()), false) + dao.SendNotification(fmt.Sprintf("成功计划任务:%s ,服务器:%s,日志:\n%s", cr.Name, dao.ServerList[clientID].Name, r.GetData()), false) } if !r.GetSuccessful() { - dao.SendNotification(fmt.Sprintf("失败计划任务:%s ,服务器:%d,日志:\n%s", cr.Name, clientID, r.GetData()), false) + dao.SendNotification(fmt.Sprintf("失败计划任务:%s ,服务器:%s,日志:\n%s", cr.Name, dao.ServerList[clientID].Name, r.GetData()), false) } dao.DB.Model(cr).Updates(model.Cron{ LastExecutedAt: time.Now().Add(time.Second * -1 * time.Duration(r.GetDelay())),