From 585cf538d095e5be6f81de58377657c6d20eb450 Mon Sep 17 00:00:00 2001 From: naiba Date: Thu, 22 Apr 2021 21:53:31 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20=E5=8F=AF=E4=BB=A5=E4=BD=BF?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E6=9C=8D=E5=8A=A1=E5=99=A8=E4=B8=8D=E5=8F=82?= =?UTF-8?q?=E4=B8=8E=E6=9C=8D=E5=8A=A1=E7=9B=91=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- cmd/dashboard/controller/member_api.go | 12 +- cmd/dashboard/rpc/rpc.go | 4 +- model/monitor.go | 26 +- resource/static/main.js | 540 +++++++++++++---------- resource/template/common/footer.html | 2 +- resource/template/component/monitor.html | 9 + resource/template/dashboard/monitor.html | 108 ++--- service/dao/dao.go | 2 +- service/dao/servicesentinel.go | 4 +- 10 files changed, 419 insertions(+), 292 deletions(-) diff --git a/README.md b/README.md index 6c30292..4a6bb4d 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@


-    +   

:trollface: 哪吒监控 一站式轻监控轻运维系统。支持系统状态、HTTP(SSL 证书变更、即将到期、到期)、TCP、Ping 监控报警,命令批量执行和计划任务。

\>> QQ 交流群: ~~955957790~~ 已解散,**自 2021 年 3 月 26 日起不再提供技术支持,接受 PR。**
-\>> 交流论坛:正在选型搭建中…… 欢迎想建设社区的铁子与奶爸取得联系。 +\>> 交流论坛:~~正在选型搭建中……~~ NodeBB 是理想选择,目前没精力维护。 \>> [我们的用户](https://www.google.com/search?q="powered+by+哪吒监控%7C哪吒面板"&filter=0) (Google) diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index 4fd1cb1..5bf15fc 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -191,11 +191,12 @@ func (ma *memberAPI) addOrEditServer(c *gin.Context) { } type monitorForm struct { - ID uint64 - Name string - Target string - Type uint8 - Notify string + ID uint64 + Name string + Target string + Type uint8 + Notify string + SkipServersRaw string } func (ma *memberAPI) addOrEditMonitor(c *gin.Context) { @@ -207,6 +208,7 @@ func (ma *memberAPI) addOrEditMonitor(c *gin.Context) { m.Target = mf.Target m.Type = mf.Type m.ID = mf.ID + m.SkipServersRaw = mf.SkipServersRaw m.Notify = mf.Notify == "on" } if err == nil { diff --git a/cmd/dashboard/rpc/rpc.go b/cmd/dashboard/rpc/rpc.go index c95ff38..19a3fb4 100644 --- a/cmd/dashboard/rpc/rpc.go +++ b/cmd/dashboard/rpc/rpc.go @@ -39,7 +39,9 @@ func DispatchTask(duration time.Duration) { } hasAliveAgent = false } - if dao.SortedServerList[index].TaskStream == nil { + // 1. 如果此任务不可使用此服务器请求,跳过这个服务器(有些 IPv6 only 开了 NAT64 的机器请求 IPv4 总会出问题) + // 2. 如果服务器不在线,跳过这个服务器 + if tasks[i].SkipServers[dao.SortedServerList[index].ID] || dao.SortedServerList[index].TaskStream == nil { i-- index++ continue diff --git a/model/monitor.go b/model/monitor.go index 819d155..49ceb3d 100644 --- a/model/monitor.go +++ b/model/monitor.go @@ -1,7 +1,10 @@ package model import ( + "encoding/json" + pb "github.com/naiba/nezha/proto" + "gorm.io/gorm" ) const ( @@ -14,10 +17,13 @@ const ( type Monitor struct { Common - Name string - Type uint8 - Target string - Notify bool + Name string + Type uint8 + Target string + SkipServersRaw string + Notify bool + + SkipServers map[uint64]bool `gorm:"-" json:"-"` } func (m *Monitor) PB() *pb.Task { @@ -27,3 +33,15 @@ func (m *Monitor) PB() *pb.Task { Data: m.Target, } } + +func (m *Monitor) AfterFind(tx *gorm.DB) error { + var skipServers []uint64 + if err := json.Unmarshal([]byte(m.SkipServersRaw), &skipServers); err != nil { + return err + } + m.SkipServers = make(map[uint64]bool) + for i := 0; i < len(skipServers); i++ { + m.SkipServers[skipServers[i]] = true + } + return nil +} diff --git a/resource/static/main.js b/resource/static/main.js index 47ce0f1..f36bb93 100644 --- a/resource/static/main.js +++ b/resource/static/main.js @@ -1,278 +1,368 @@ function readableBytes(bytes) { - var i = Math.floor(Math.log(bytes) / Math.log(1024)), - sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - return (bytes / Math.pow(1024, i)).toFixed(0) + ' ' + sizes[i]; + var i = Math.floor(Math.log(bytes) / Math.log(1024)), + sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + return (bytes / Math.pow(1024, i)).toFixed(0) + " " + sizes[i]; } -const confirmBtn = $('.mini.confirm.modal .positive.button') +const confirmBtn = $(".mini.confirm.modal .positive.button"); function showConfirm(title, content, callFn, extData) { - const modal = $('.mini.confirm.modal') - modal.children('.header').text(title) - modal.children('.content').text(content) - if (confirmBtn.hasClass('loading')) { - return false - } - modal.modal({ - closable: true, - onApprove: function () { - confirmBtn.toggleClass('loading') - callFn(extData) - return false - } - }).modal('show') + const modal = $(".mini.confirm.modal"); + modal.children(".header").text(title); + modal.children(".content").text(content); + if (confirmBtn.hasClass("loading")) { + return false; + } + modal + .modal({ + closable: true, + onApprove: function () { + confirmBtn.toggleClass("loading"); + callFn(extData); + return false; + }, + }) + .modal("show"); } function showFormModal(modelSelector, formID, URL, getData) { - $(modelSelector).modal({ - closable: true, - onApprove: function () { - let success = false - const btn = $(modelSelector + ' .positive.button') - const form = $(modelSelector + ' form') - if (btn.hasClass('loading')) { - return success - } - form.children('.message').remove() - btn.toggleClass('loading') - const data = getData ? getData() : $(formID).serializeArray().reduce(function (obj, item) { + $(modelSelector) + .modal({ + closable: true, + onApprove: function () { + let success = false; + const btn = $(modelSelector + " .positive.button"); + const form = $(modelSelector + " form"); + if (btn.hasClass("loading")) { + return success; + } + form.children(".message").remove(); + btn.toggleClass("loading"); + const data = getData + ? getData() + : $(formID) + .serializeArray() + .reduce(function (obj, item) { // ID 类的数据 - if ((item.name.endsWith('_id') || - item.name === 'id' || item.name === 'ID' || - item.name === 'RequestType' || item.name === 'RequestMethod' || - item.name === 'DisplayIndex' || item.name === 'Type')) { - obj[item.name] = parseInt(item.value); + if ( + item.name.endsWith("_id") || + item.name === "id" || + item.name === "ID" || + item.name === "RequestType" || + item.name === "RequestMethod" || + item.name === "DisplayIndex" || + item.name === "Type" + ) { + obj[item.name] = parseInt(item.value); } else { - obj[item.name] = item.value; + obj[item.name] = item.value; } - if (item.name == 'ServersRaw') { - if (item.value.length > 2) { - obj[item.name] = '[' + item.value.substr(3, item.value.length - 1) + ']' - } + if (item.name.endsWith("ServersRaw")) { + if (item.value.length > 2) { + obj[item.name] = + "[" + item.value.substr(3, item.value.length - 1) + "]"; + } } return obj; - }, {}); - $.post(URL, JSON.stringify(data)).done(function (resp) { - if (resp.code == 200) { - if (resp.message) { - $.suiAlert({ - title: '操作成功', - type: 'success', - description: resp.message, - time: '3', - position: 'top-center', - }); - } - window.location.reload() - } else { - form.append(`
操作失败

` + resp.message + `

`) - } - }).fail(function (err) { - form.append(`
网络错误

` + err.responseText + `

`) - }).always(function () { - btn.toggleClass('loading') - }); - return success - } - }).modal('show') + }, {}); + $.post(URL, JSON.stringify(data)) + .done(function (resp) { + if (resp.code == 200) { + if (resp.message) { + $.suiAlert({ + title: "操作成功", + type: "success", + description: resp.message, + time: "3", + position: "top-center", + }); + } + window.location.reload(); + } else { + form.append( + `
操作失败

` + + resp.message + + `

` + ); + } + }) + .fail(function (err) { + form.append( + `
网络错误

` + + err.responseText + + `

` + ); + }) + .always(function () { + btn.toggleClass("loading"); + }); + return success; + }, + }) + .modal("show"); } function addOrEditAlertRule(rule) { - const modal = $('.rule.modal') - modal.children('.header').text((rule ? '修改' : '添加') + '报警规则') - modal.find('.positive.button').html(rule ? '修改' : '添加') - modal.find('input[name=ID]').val(rule ? rule.ID : null) - modal.find('input[name=Name]').val(rule ? rule.Name : null) - modal.find('textarea[name=RulesRaw]').val(rule ? rule.RulesRaw : null) - if (rule && rule.Enable) { - modal.find('.ui.rule-enable.checkbox').checkbox('set checked') - } else { - modal.find('.ui.rule-enable.checkbox').checkbox('set unchecked') - } - showFormModal('.rule.modal', '#ruleForm', '/api/alert-rule') + const modal = $(".rule.modal"); + modal.children(".header").text((rule ? "修改" : "添加") + "报警规则"); + modal + .find(".positive.button") + .html( + rule ? '修改' : '添加' + ); + modal.find("input[name=ID]").val(rule ? rule.ID : null); + modal.find("input[name=Name]").val(rule ? rule.Name : null); + modal.find("textarea[name=RulesRaw]").val(rule ? rule.RulesRaw : null); + if (rule && rule.Enable) { + modal.find(".ui.rule-enable.checkbox").checkbox("set checked"); + } else { + modal.find(".ui.rule-enable.checkbox").checkbox("set unchecked"); + } + showFormModal(".rule.modal", "#ruleForm", "/api/alert-rule"); } function addOrEditNotification(notification) { - const modal = $('.notification.modal') - modal.children('.header').text((notification ? '修改' : '添加') + '通知方式') - modal.find('.positive.button').html(notification ? '修改' : '添加') - modal.find('input[name=ID]').val(notification ? notification.ID : null) - modal.find('input[name=Name]').val(notification ? notification.Name : null) - modal.find('input[name=URL]').val(notification ? notification.URL : null) - modal.find('textarea[name=RequestBody]').val(notification ? notification.RequestBody : null) - modal.find('select[name=RequestMethod]').val(notification ? notification.RequestMethod : 1) - modal.find('select[name=RequestType]').val(notification ? notification.RequestType : 1) - if (notification && notification.VerifySSL) { - modal.find('.ui.nf-ssl.checkbox').checkbox('set checked') - } else { - modal.find('.ui.nf-ssl.checkbox').checkbox('set unchecked') - } - showFormModal('.notification.modal', '#notificationForm', '/api/notification') + const modal = $(".notification.modal"); + modal.children(".header").text((notification ? "修改" : "添加") + "通知方式"); + modal + .find(".positive.button") + .html( + notification + ? '修改' + : '添加' + ); + modal.find("input[name=ID]").val(notification ? notification.ID : null); + modal.find("input[name=Name]").val(notification ? notification.Name : null); + modal.find("input[name=URL]").val(notification ? notification.URL : null); + modal + .find("textarea[name=RequestBody]") + .val(notification ? notification.RequestBody : null); + modal + .find("select[name=RequestMethod]") + .val(notification ? notification.RequestMethod : 1); + modal + .find("select[name=RequestType]") + .val(notification ? notification.RequestType : 1); + if (notification && notification.VerifySSL) { + modal.find(".ui.nf-ssl.checkbox").checkbox("set checked"); + } else { + modal.find(".ui.nf-ssl.checkbox").checkbox("set unchecked"); + } + showFormModal( + ".notification.modal", + "#notificationForm", + "/api/notification" + ); } function addOrEditServer(server) { - const modal = $('.server.modal') - modal.children('.header').text((server ? '修改' : '添加') + '服务器') - modal.find('.positive.button').html(server ? '修改' : '添加') - modal.find('input[name=id]').val(server ? server.ID : null) - modal.find('input[name=name]').val(server ? server.Name : null) - modal.find('input[name=Tag]').val(server ? server.Tag : null) - modal.find('input[name=DisplayIndex]').val(server ? server.DisplayIndex : null) - modal.find('textarea[name=Note]').val(server ? server.Note : null) - if (server) { - modal.find('.secret.field').attr('style', '') - modal.find('input[name=secret]').val(server.Secret) - } else { - modal.find('.secret.field').attr('style', 'display:none') - modal.find('input[name=secret]').val('') - } - showFormModal('.server.modal', '#serverForm', '/api/server') + const modal = $(".server.modal"); + modal.children(".header").text((server ? "修改" : "添加") + "服务器"); + modal + .find(".positive.button") + .html( + server ? '修改' : '添加' + ); + modal.find("input[name=id]").val(server ? server.ID : null); + modal.find("input[name=name]").val(server ? server.Name : null); + modal.find("input[name=Tag]").val(server ? server.Tag : null); + modal + .find("input[name=DisplayIndex]") + .val(server ? server.DisplayIndex : null); + modal.find("textarea[name=Note]").val(server ? server.Note : null); + if (server) { + modal.find(".secret.field").attr("style", ""); + modal.find("input[name=secret]").val(server.Secret); + } else { + modal.find(".secret.field").attr("style", "display:none"); + modal.find("input[name=secret]").val(""); + } + showFormModal(".server.modal", "#serverForm", "/api/server"); } function addOrEditMonitor(monitor) { - const modal = $('.monitor.modal') - modal.children('.header').text((monitor ? '修改' : '添加') + '监控') - modal.find('.positive.button').html(monitor ? '修改' : '添加') - modal.find('input[name=ID]').val(monitor ? monitor.ID : null) - modal.find('input[name=Name]').val(monitor ? monitor.Name : null) - modal.find('input[name=Target]').val(monitor ? monitor.Target : null) - modal.find('select[name=Type]').val(monitor ? monitor.Type : 1) - if (monitor && monitor.Notify) { - modal.find(".ui.nb-notify.checkbox").checkbox("set checked"); - } else { - modal.find(".ui.nb-notify.checkbox").checkbox("set unchecked"); + const modal = $(".monitor.modal"); + modal.children(".header").text((monitor ? "修改" : "添加") + "监控"); + modal + .find(".positive.button") + .html( + monitor ? '修改' : '添加' + ); + modal.find("input[name=ID]").val(monitor ? monitor.ID : null); + modal.find("input[name=Name]").val(monitor ? monitor.Name : null); + modal.find("input[name=Target]").val(monitor ? monitor.Target : null); + modal.find("select[name=Type]").val(monitor ? monitor.Type : 1); + if (monitor && monitor.Notify) { + modal.find(".ui.nb-notify.checkbox").checkbox("set checked"); + } else { + modal.find(".ui.nb-notify.checkbox").checkbox("set unchecked"); + } + var servers; + if (monitor) { + servers = monitor.SkipServersRaw || "[]"; + const serverList = JSON.parse(servers); + const node = modal.find("i.dropdown.icon"); + for (let i = 0; i < serverList.length; i++) { + node.after( + 'ID:' + + serverList[i] + + '' + ); } - showFormModal('.monitor.modal', '#monitorForm', '/api/monitor') + } + modal + .find("input[name=SkipServersRaw]") + .val(monitor ? "[]," + servers.substr(1, servers.length - 2) : "[]"); + showFormModal(".monitor.modal", "#monitorForm", "/api/monitor"); } function addOrEditCron(cron) { - const modal = $('.cron.modal') - modal.children('.header').text((cron ? '修改' : '添加') + '计划任务') - modal.find('.positive.button').html(cron ? '修改' : '添加') - modal.find('input[name=ID]').val(cron ? cron.ID : null) - modal.find('input[name=Name]').val(cron ? cron.Name : null) - modal.find('input[name=Scheduler]').val(cron ? cron.Scheduler : null) - modal.find('a.ui.label.visible').each((i, el) => { - el.remove() - }) - var servers - if (cron) { - servers = cron.ServersRaw - serverList = JSON.parse(servers) - const node = modal.find('i.dropdown.icon') - for (let i = 0; i < serverList.length; i++) { - node.after('ID:' + serverList[i] + '') - } + const modal = $(".cron.modal"); + modal.children(".header").text((cron ? "修改" : "添加") + "计划任务"); + modal + .find(".positive.button") + .html( + cron ? '修改' : '添加' + ); + modal.find("input[name=ID]").val(cron ? cron.ID : null); + modal.find("input[name=Name]").val(cron ? cron.Name : null); + modal.find("input[name=Scheduler]").val(cron ? cron.Scheduler : null); + modal.find("a.ui.label.visible").each((i, el) => { + el.remove(); + }); + var servers; + if (cron) { + servers = cron.ServersRaw; + const serverList = JSON.parse(servers); + const node = modal.find("i.dropdown.icon"); + for (let i = 0; i < serverList.length; i++) { + node.after( + 'ID:' + + serverList[i] + + '' + ); } - modal.find('input[name=ServersRaw]').val(cron ? '[],' + servers.substr(1, servers.length - 2) : '[]') - modal.find('textarea[name=Command]').val(cron ? cron.Command : null) - if (cron && cron.PushSuccessful) { - modal.find('.ui.push-successful.checkbox').checkbox('set checked') - } else { - modal.find('.ui.push-successful.checkbox').checkbox('set unchecked') - } - showFormModal('.cron.modal', '#cronForm', '/api/cron') + } + modal + .find("input[name=ServersRaw]") + .val(cron ? "[]," + servers.substr(1, servers.length - 2) : "[]"); + modal.find("textarea[name=Command]").val(cron ? cron.Command : null); + if (cron && cron.PushSuccessful) { + modal.find(".ui.push-successful.checkbox").checkbox("set checked"); + } else { + modal.find(".ui.push-successful.checkbox").checkbox("set unchecked"); + } + showFormModal(".cron.modal", "#cronForm", "/api/cron"); } function deleteRequest(api) { - $.ajax({ - url: api, - type: 'DELETE', - }).done(resp => { - if (resp.code == 200) { - if (resp.message) { - alert(resp.message) - } else { - alert('删除成功') - } - window.location.reload() + $.ajax({ + url: api, + type: "DELETE", + }) + .done((resp) => { + if (resp.code == 200) { + if (resp.message) { + alert(resp.message); } else { - alert('删除失败 ' + resp.code + ':' + resp.message) - confirmBtn.toggleClass('loading') + alert("删除成功"); } - }).fail(err => { - alert('网络错误:' + err.responseText) + window.location.reload(); + } else { + alert("删除失败 " + resp.code + ":" + resp.message); + confirmBtn.toggleClass("loading"); + } + }) + .fail((err) => { + alert("网络错误:" + err.responseText); }); } function manualTrigger(btn, cronId) { - $(btn).toggleClass('loading') - $.ajax({ - url: '/api/cron/' + cronId + '/manual', - type: 'GET', - }).done(resp => { - $(btn).toggleClass('loading') - if (resp.code == 200) { - $.suiAlert({ - title: '触发成功,等待执行结果', - type: 'success', - description: resp.message, - time: '3', - position: 'top-center', - }); - } else { - $.suiAlert({ - title: '触发失败 ', - type: 'error', - description: resp.code + ':' + resp.message, - time: '3', - position: 'top-center', - }); - } - }).fail(err => { - $(btn).toggleClass('loading') + $(btn).toggleClass("loading"); + $.ajax({ + url: "/api/cron/" + cronId + "/manual", + type: "GET", + }) + .done((resp) => { + $(btn).toggleClass("loading"); + if (resp.code == 200) { $.suiAlert({ - title: '触发失败 ', - type: 'error', - description: '网络错误:' + err.responseText, - time: '3', - position: 'top-center', + title: "触发成功,等待执行结果", + type: "success", + description: resp.message, + time: "3", + position: "top-center", }); + } else { + $.suiAlert({ + title: "触发失败 ", + type: "error", + description: resp.code + ":" + resp.message, + time: "3", + position: "top-center", + }); + } + }) + .fail((err) => { + $(btn).toggleClass("loading"); + $.suiAlert({ + title: "触发失败 ", + type: "error", + description: "网络错误:" + err.responseText, + time: "3", + position: "top-center", + }); }); } function logout(id) { - $.post('/api/logout', JSON.stringify({ id: id })).done(function (resp) { - if (resp.code == 200) { - $.suiAlert({ - title: '注销成功', - type: 'success', - description: '如需继续访问请使用 GitHub 再次登录', - time: '3', - position: 'top-center', - }); - window.location.reload() - } else { - $.suiAlert({ - title: '注销失败', - description: resp.code + ':' + resp.message, - type: 'error', - time: '3', - position: 'top-center', - }); - } - }).fail(function (err) { + $.post("/api/logout", JSON.stringify({ id: id })) + .done(function (resp) { + if (resp.code == 200) { $.suiAlert({ - title: '网络错误', - description: err.responseText, - type: 'error', - time: '3', - position: 'top-center', + title: "注销成功", + type: "success", + description: "如需继续访问请使用 GitHub 再次登录", + time: "3", + position: "top-center", }); + window.location.reload(); + } else { + $.suiAlert({ + title: "注销失败", + description: resp.code + ":" + resp.message, + type: "error", + time: "3", + position: "top-center", + }); + } }) + .fail(function (err) { + $.suiAlert({ + title: "网络错误", + description: err.responseText, + type: "error", + time: "3", + position: "top-center", + }); + }); } $(document).ready(() => { - try { - $('.ui.servers.search.dropdown').dropdown({ - clearable: true, - apiSettings: { - url: '/api/search-server?word={query}', - cache: false, - }, - }) - } catch (error) { - } -}) \ No newline at end of file + try { + $(".ui.servers.search.dropdown").dropdown({ + clearable: true, + apiSettings: { + url: "/api/search-server?word={query}", + cache: false, + }, + }); + } catch (error) {} +}); diff --git a/resource/template/common/footer.html b/resource/template/common/footer.html index 3c5a4ef..afbd9b0 100644 --- a/resource/template/common/footer.html +++ b/resource/template/common/footer.html @@ -9,7 +9,7 @@ - + diff --git a/resource/template/component/monitor.html b/resource/template/component/monitor.html index 8e24319..58661e5 100644 --- a/resource/template/component/monitor.html +++ b/resource/template/component/monitor.html @@ -24,6 +24,15 @@ +
+ + +
diff --git a/resource/template/dashboard/monitor.html b/resource/template/dashboard/monitor.html index 475a397..723bfb2 100644 --- a/resource/template/dashboard/monitor.html +++ b/resource/template/dashboard/monitor.html @@ -2,60 +2,66 @@ {{template "common/header" .}} {{template "common/menu" .}}
-
-
-
- -
-
- - - - - - - - - - - - - {{range $monitor := .Monitors}} - - - - - - - - - {{end}} - -
ID名称通知目标类型管理
{{$monitor.ID}}{{$monitor.Name}}{{$monitor.Notify}}{{$monitor.Target}} - {{if eq $monitor.Type 1}}HTTP(S)/SSL证书 - {{else if eq $monitor.Type 2}} - ICMP Ping - {{else}} - TCP 端口 - {{end}} - -
- - -
-
+
+
+
+ +
+ + + + + + + + + + + + + + {{range $monitor := .Monitors}} + + + + + + + + + + {{end}} + +
ID名称通知目标类型跳过的服务器管理
{{$monitor.ID}}{{$monitor.Name}}{{$monitor.Notify}}{{$monitor.Target}} + {{if eq $monitor.Type 1}}HTTP(S)/SSL证书 {{else if eq $monitor.Type + 2}} ICMP Ping {{else}} TCP 端口 {{end}} + {{$monitor.SkipServersRaw}} +
+ + +
+
+
{{template "component/monitor"}} {{template "common/footer" .}} -{{end}} \ No newline at end of file +{{end}} diff --git a/service/dao/dao.go b/service/dao/dao.go index 03f3461..03af4cf 100644 --- a/service/dao/dao.go +++ b/service/dao/dao.go @@ -13,7 +13,7 @@ import ( pb "github.com/naiba/nezha/proto" ) -var Version = "v0.6.2" // !!记得修改 README 重的 badge 版本!! +var Version = "v0.6.3" // !!记得修改 README 中的 badge 版本!! const ( SnapshotDelay = 3 diff --git a/service/dao/servicesentinel.go b/service/dao/servicesentinel.go index 83798bc..77390bf 100644 --- a/service/dao/servicesentinel.go +++ b/service/dao/servicesentinel.go @@ -11,7 +11,7 @@ import ( pb "github.com/naiba/nezha/proto" ) -const _CurrentStatusSize = 60 // 统计 10 分钟内的数据为当前状态 +const _CurrentStatusSize = 30 // 统计 5 分钟内的数据为当前状态 var ServiceSentinelShared *ServiceSentinel @@ -186,7 +186,7 @@ func (ss *ServiceSentinel) LoadStats() map[uint64]*model.ServiceItemResponse { msm[k].Delay[29] = (msm[k].Delay[29]*float32(msm[k].Up[29]) + v[i].Delay) / float32(msm[k].Up[29]+1) } } - // 最后 10 分钟的状态 与 monitor 对象填充 + // 最后 5 分钟的状态 与 monitor 对象填充 for k, v := range ss.serviceResponseDataStoreCurrentDown { msm[k].CurrentDown = v }