diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index a2eccfdd..32d4d35d 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -484,6 +484,10 @@ func (this *RPCClient) ServerStatBoardRPC() pb.ServerStatBoardServiceClient { return pb.NewServerStatBoardServiceClient(this.pickConn()) } +func (this *RPCClient) ServerDomainHourlyStatRPC() pb.ServerDomainHourlyStatServiceClient { + return pb.NewServerDomainHourlyStatServiceClient(this.pickConn()) +} + func (this *RPCClient) ServerStatBoardChartRPC() pb.ServerStatBoardChartServiceClient { return pb.NewServerStatBoardChartServiceClient(this.pickConn()) } diff --git a/internal/web/actions/default/servers/server/boards/index.go b/internal/web/actions/default/servers/server/boards/index.go deleted file mode 100644 index 166ca07c..00000000 --- a/internal/web/actions/default/servers/server/boards/index.go +++ /dev/null @@ -1,180 +0,0 @@ -package boards - -import ( - "fmt" - teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" - "github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" - "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" - "github.com/iwind/TeaGo/maps" - "strconv" -) - -type IndexAction struct { - actionutils.ParentAction -} - -func (this *IndexAction) Init() { - this.Nav("", "board", "") - this.SecondMenu("index") -} - -func (this *IndexAction) RunGet(params struct { - ServerId int64 -}) { - if !teaconst.IsPlus { - this.RedirectURL("/servers/server/stat?serverId=" + strconv.FormatInt(params.ServerId, 10)) - return - } - - serverResp, err := this.RPC().ServerRPC().FindEnabledServer(this.AdminContext(), &pb.FindEnabledServerRequest{ServerId: params.ServerId}) - if err != nil { - this.ErrorPage(err) - return - } - var server = serverResp.Server - if server == nil { - this.NotFound("server", params.ServerId) - return - } - this.Data["server"] = maps.Map{ - "id": server.Id, - "name": server.Name, - } - - this.Show() -} - -func (this *IndexAction) RunPost(params struct { - ServerId int64 -}) { - resp, err := this.RPC().ServerStatBoardRPC().ComposeServerStatBoard(this.AdminContext(), &pb.ComposeServerStatBoardRequest{ServerId: params.ServerId}) - if err != nil { - this.ErrorPage(err) - return - } - - // 24小时流量趋势 - { - var statMaps = []maps.Map{} - for _, stat := range resp.HourlyTrafficStats { - statMaps = append(statMaps, maps.Map{ - "bytes": stat.Bytes, - "cachedBytes": stat.CachedBytes, - "countRequests": stat.CountRequests, - "countCachedRequests": stat.CountCachedRequests, - "countAttackRequests": stat.CountAttackRequests, - "attackBytes": stat.AttackBytes, - "day": stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日", - "hour": stat.Hour[8:], - }) - } - this.Data["hourlyStats"] = statMaps - } - - // 15天流量趋势 - { - var statMaps = []maps.Map{} - for _, stat := range resp.DailyTrafficStats { - statMaps = append(statMaps, maps.Map{ - "bytes": stat.Bytes, - "cachedBytes": stat.CachedBytes, - "countRequests": stat.CountRequests, - "countCachedRequests": stat.CountCachedRequests, - "countAttackRequests": stat.CountAttackRequests, - "attackBytes": stat.AttackBytes, - "day": stat.Day[4:6] + "月" + stat.Day[6:] + "日", - }) - } - this.Data["dailyStats"] = statMaps - } - - // 节点排行 - { - var statMaps = []maps.Map{} - for _, stat := range resp.TopNodeStats { - statMaps = append(statMaps, maps.Map{ - "nodeId": stat.NodeId, - "nodeName": stat.NodeName, - "countRequests": stat.CountRequests, - "bytes": stat.Bytes, - "countAttackRequests": stat.CountAttackRequests, - "attackBytes": stat.AttackBytes, - }) - } - this.Data["topNodeStats"] = statMaps - } - - // 域名排行 - { - var statMaps = []maps.Map{} - for _, stat := range resp.TopDomainStats { - statMaps = append(statMaps, maps.Map{ - "serverId": stat.ServerId, - "domain": stat.Domain, - "countRequests": stat.CountRequests, - "bytes": stat.Bytes, - "countAttackRequests": stat.CountAttackRequests, - "attackBytes": stat.AttackBytes, - }) - } - this.Data["topDomainStats"] = statMaps - } - - // 地区排行 - { - var countryMaps = []maps.Map{} - for _, stat := range resp.TopCountryStats { - countryMaps = append(countryMaps, maps.Map{ - "name": stat.CountryName, - "bytes": stat.Bytes, - "formattedBytes": numberutils.FormatBytes(stat.Bytes), - "countRequests": stat.CountRequests, - "countAttackRequests": stat.CountAttackRequests, - "percent": fmt.Sprintf("%.2f", stat.Percent), - }) - } - this.Data["topCountryStats"] = countryMaps - } - - // 指标 - { - var chartMaps = []maps.Map{} - for _, chart := range resp.MetricDataCharts { - var statMaps = []maps.Map{} - for _, stat := range chart.MetricStats { - statMaps = append(statMaps, maps.Map{ - "keys": stat.Keys, - "time": stat.Time, - "value": stat.Value, - "count": stat.SumCount, - "total": stat.SumTotal, - }) - } - chartMaps = append(chartMaps, maps.Map{ - "chart": maps.Map{ - "id": chart.MetricChart.Id, - "name": chart.MetricChart.Name, - "widthDiv": chart.MetricChart.WidthDiv, - "isOn": chart.MetricChart.IsOn, - "maxItems": chart.MetricChart.MaxItems, - "type": chart.MetricChart.Type, - }, - "item": maps.Map{ - "id": chart.MetricChart.MetricItem.Id, - "name": chart.MetricChart.MetricItem.Name, - "period": chart.MetricChart.MetricItem.Period, - "periodUnit": chart.MetricChart.MetricItem.PeriodUnit, - "valueType": serverconfigs.FindMetricValueType(chart.MetricChart.MetricItem.Category, chart.MetricChart.MetricItem.Value), - "valueTypeName": serverconfigs.FindMetricValueName(chart.MetricChart.MetricItem.Category, chart.MetricChart.MetricItem.Value), - "keys": chart.MetricChart.MetricItem.Keys, - }, - "stats": statMaps, - }) - } - this.Data["metricCharts"] = chartMaps - } - - this.Success() -} diff --git a/internal/web/actions/default/servers/server/boards/init.go b/internal/web/actions/default/servers/server/boards/init.go deleted file mode 100644 index 0383ba34..00000000 --- a/internal/web/actions/default/servers/server/boards/init.go +++ /dev/null @@ -1,19 +0,0 @@ -package boards - -import ( - "github.com/TeaOSLab/EdgeAdmin/internal/configloaders" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/helpers" - "github.com/iwind/TeaGo" -) - -func init() { - TeaGo.BeforeStart(func(server *TeaGo.Server) { - server. - Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)). - Helper(serverutils.NewServerHelper()). - Prefix("/servers/server/boards"). - GetPost("", new(IndexAction)). - EndAll() - }) -} diff --git a/web/public/js/components/common/message-loading.js b/web/public/js/components/common/message-loading.js new file mode 100644 index 00000000..76e62b96 --- /dev/null +++ b/web/public/js/components/common/message-loading.js @@ -0,0 +1,5 @@ +Vue.component("loading-message", { + template: `
+
  +
` +}) \ No newline at end of file diff --git a/web/views/@default/clusters/cluster/boards/index.html b/web/views/@default/clusters/cluster/boards/index.html deleted file mode 100644 index f5ed4648..00000000 --- a/web/views/@default/clusters/cluster/boards/index.html +++ /dev/null @@ -1,87 +0,0 @@ -{$layout} -{$template "/echarts"} - - -
-
-
  数据加载中... -
-
- -
-
-

在线节点

-
{{board.countActiveNodes}}
-
-
-

离线节点

-
{{board.countInactiveNodes}}
-
-
-

服务

-
{{board.countServers}}
-
-
-

用户

-
{{board.countUsers}}
-
-
- - - - -
- - -
- -
- - - - -
- - -
- -
- - -

域名访问排行 (24小时)

-
- -
- - -

节点访问排行 (24小时)

-
- -
- - - -
-
-
- - -
- - - - \ No newline at end of file diff --git a/web/views/@default/clusters/cluster/boards/index.js b/web/views/@default/clusters/cluster/boards/index.js deleted file mode 100644 index b4365d4a..00000000 --- a/web/views/@default/clusters/cluster/boards/index.js +++ /dev/null @@ -1,453 +0,0 @@ -Tea.context(function () { - this.isLoading = true - this.board = {} - this.metricCharts = [] - - - /** - * 流量统计 - */ - this.trafficTab = "hourly" - - this.$delay(function () { - this.$post("$") - .params({ - clusterId: this.clusterId - }) - .timeout(30) - .success(function (resp) { - for (let k in resp.data) { - this[k] = resp.data[k] - } - - this.reloadHourlyTrafficChart() - this.reloadHourlyRequestsChart() - this.reloadTopNodesChart() - this.reloadTopDomainsChart() - this.reloadCPUChart() - - this.isLoading = false - }) - }) - - this.selectTrafficTab = function (tab) { - this.trafficTab = tab - if (tab == "hourly") { - this.$delay(function () { - this.reloadHourlyTrafficChart() - }) - } else if (tab == "daily") { - this.$delay(function () { - this.reloadDailyTrafficChart() - }) - } - } - - this.reloadHourlyTrafficChart = function () { - let stats = this.hourlyStats - this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].bytes > 0) { - cachedRatio = Math.round(stats[index].cachedBytes * 10000 / stats[index].bytes) / 100 - attackRatio = Math.round(stats[index].attackBytes * 10000 / stats[index].bytes) / 100 - } - - return stats[index].day + " " + stats[index].hour + "时
总流量:" + teaweb.formatBytes(stats[index].bytes) + "
缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "
缓存命中率:" + cachedRatio + "%
拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadDailyTrafficChart = function () { - let stats = this.dailyStats - this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].bytes > 0) { - cachedRatio = Math.round(stats[index].cachedBytes * 10000 / stats[index].bytes) / 100 - attackRatio = Math.round(stats[index].attackBytes * 10000 / stats[index].bytes) / 100 - } - - return stats[index].day + "
总流量:" + teaweb.formatBytes(stats[index].bytes) + "
缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "
缓存命中率:" + cachedRatio + "%
拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadTrafficChart = function (chartId, name, stats, tooltipFunc) { - let chartBox = document.getElementById(chartId) - if (chartBox == null) { - return - } - - let axis = teaweb.bytesAxis(stats, function (v) { - return Math.max(v.bytes, v.cachedBytes) - }) - - let chart = teaweb.initChart(chartBox) - let option = { - xAxis: { - data: stats.map(function (v) { - if (v.hour != null) { - return v.hour - } - return v.day - }) - }, - yAxis: { - axisLabel: { - formatter: function (value) { - return value + axis.unit - } - } - }, - tooltip: { - show: true, - trigger: "item", - formatter: tooltipFunc - }, - grid: { - left: 50, - top: 40, - right: 20, - bottom: 20 - }, - series: [ - { - name: "流量", - type: "line", - data: stats.map(function (v) { - return v.bytes / axis.divider - }), - itemStyle: { - color: "#9DD3E8" - }, - areaStyle: { - color: "#9DD3E8" - }, - smooth: true - }, - { - name: "缓存流量", - type: "line", - data: stats.map(function (v) { - return v.cachedBytes / axis.divider - }), - itemStyle: { - color: "#61A0A8" - }, - areaStyle: { - color: "#61A0A8" - }, - smooth: true - }, - { - name: "攻击流量", - type: "line", - data: stats.map(function (v) { - return v.attackBytes / axis.divider - }), - itemStyle: { - color: "#F39494" - }, - areaStyle: { - color: "#F39494" - }, - smooth: true - } - ], - legend: { - data: ["流量", "缓存流量", "攻击流量"] - }, - animation: true - } - chart.setOption(option) - chart.resize() - } - - /** - * 请求数统计 - */ - this.requestsTab = "hourly" - - this.selectRequestsTab = function (tab) { - this.requestsTab = tab - if (tab == "hourly") { - this.$delay(function () { - this.reloadHourlyRequestsChart() - }) - } else if (tab == "daily") { - this.$delay(function () { - this.reloadDailyRequestsChart() - }) - } - } - - this.reloadHourlyRequestsChart = function () { - let stats = this.hourlyStats - this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].countRequests > 0) { - cachedRatio = Math.round(stats[index].countCachedRequests * 10000 / stats[index].countRequests) / 100 - attackRatio = Math.round(stats[index].countAttackRequests * 10000 / stats[index].countRequests) / 100 - } - - return stats[index].day + " " + stats[index].hour + "时
总请求数:" + teaweb.formatNumber(stats[index].countRequests) + "
缓存请求数:" + teaweb.formatNumber(stats[index].countCachedRequests) + "
缓存命中率:" + cachedRatio + "%
拦截攻击数:" + teaweb.formatNumber(stats[index].countAttackRequests) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadDailyRequestsChart = function () { - let stats = this.dailyStats - this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].countRequests > 0) { - cachedRatio = Math.round(stats[index].countCachedRequests * 10000 / stats[index].countRequests) / 100 - attackRatio = Math.round(stats[index].countAttackRequests * 10000 / stats[index].countRequests) / 100 - } - - return stats[index].day + "
总请求数:" + teaweb.formatNumber(stats[index].countRequests) + "
缓存请求数:" + teaweb.formatNumber(stats[index].countCachedRequests) + "
缓存命中率:" + cachedRatio + "%
拦截攻击数:" + teaweb.formatNumber(stats[index].countAttackRequests) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadRequestsChart = function (chartId, name, stats, tooltipFunc) { - let chartBox = document.getElementById(chartId) - if (chartBox == null) { - return - } - - let axis = teaweb.countAxis(stats, function (v) { - return Math.max(v.countRequests, v.countCachedRequests) - }) - - let chart = teaweb.initChart(chartBox) - let option = { - xAxis: { - data: stats.map(function (v) { - if (v.hour != null) { - return v.hour - } - if (v.day != null) { - return v.day - } - return "" - }) - }, - yAxis: { - axisLabel: { - formatter: function (value) { - return value + axis.unit - } - } - }, - tooltip: { - show: true, - trigger: "item", - formatter: tooltipFunc - }, - grid: { - left: 50, - top: 40, - right: 20, - bottom: 20 - }, - series: [ - { - name: "请求数", - type: "line", - data: stats.map(function (v) { - return v.countRequests / axis.divider - }), - itemStyle: { - color: "#9DD3E8" - }, - areaStyle: { - color: "#9DD3E8" - }, - smooth: true - }, - { - name: "缓存请求数", - type: "line", - data: stats.map(function (v) { - return v.countCachedRequests / axis.divider - }), - itemStyle: { - color: "#61A0A8" - }, - areaStyle: { - color: "#61A0A8" - }, - smooth: true - }, - { - name: "攻击请求数", - type: "line", - data: stats.map(function (v) { - return v.countAttackRequests / axis.divider; - }), - itemStyle: { - color: "#F39494" - }, - areaStyle: { - color: "#F39494" - }, - smooth: true - } - ], - legend: { - data: ["请求数", "缓存请求数", "攻击请求数"] - }, - animation: true - } - chart.setOption(option) - chart.resize() - } - - // 节点排行 - this.reloadTopNodesChart = function () { - let that = this - let axis = teaweb.countAxis(this.topNodeStats, function (v) { - return v.countRequests - }) - teaweb.renderBarChart({ - id: "top-nodes-chart", - name: "节点", - values: this.topNodeStats, - x: function (v) { - return v.nodeName - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].nodeName + "
请求数:" + " " + teaweb.formatNumber(stats[args.dataIndex].countRequests) + "
流量:" + teaweb.formatBytes(stats[args.dataIndex].bytes) - }, - value: function (v) { - return v.countRequests / axis.divider; - }, - axis: axis, - click: function (args, stats) { - window.location = "/clusters/cluster/node?nodeId=" + stats[args.dataIndex].nodeId + "&clusterId=" + that.clusterId - } - }) - } - - // 域名排行 - this.reloadTopDomainsChart = function () { - let axis = teaweb.countAxis(this.topDomainStats, function (v) { - return v.countRequests - }) - teaweb.renderBarChart({ - id: "top-domains-chart", - name: "域名", - values: this.topDomainStats, - x: function (v) { - return v.domain - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].domain + "
请求数:" + " " + teaweb.formatNumber(stats[args.dataIndex].countRequests) + "
流量:" + teaweb.formatBytes(stats[args.dataIndex].bytes) - }, - value: function (v) { - return v.countRequests / axis.divider; - }, - axis: axis, - click: function (args, stats) { - window.location = "/servers/server?serverId=" + stats[args.dataIndex].serverId - } - }) - } - - /** - * 系统信息 - */ - this.nodeStatusTab = "cpu" - - this.selectNodeStatusTab = function (tab) { - this.nodeStatusTab = tab - this.$delay(function () { - switch (tab) { - case "cpu": - this.reloadCPUChart() - break - case "memory": - this.reloadMemoryChart() - break - case "load": - this.reloadLoadChart() - break - } - }) - } - - this.reloadCPUChart = function () { - let axis = {unit: "%", divider: 1} - teaweb.renderLineChart({ - id: "cpu-chart", - name: "CPU", - values: this.cpuValues, - x: function (v) { - return v.time - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].time + ":" + (Math.ceil(stats[args.dataIndex].value * 100 * 100) / 100) + "%" - }, - value: function (v) { - return v.value * 100; - }, - axis: axis, - max: 100 - }) - } - - this.reloadMemoryChart = function () { - let axis = {unit: "%", divider: 1} - teaweb.renderLineChart({ - id: "memory-chart", - name: "内存", - values: this.memoryValues, - x: function (v) { - return v.time - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].time + ":" + (Math.ceil(stats[args.dataIndex].value * 100 * 100) / 100) + "%" - }, - value: function (v) { - return v.value * 100; - }, - axis: axis, - max: 100 - }) - } - - this.reloadLoadChart = function () { - let axis = {unit: "", divider: 1} - let max = this.loadValues.$map(function (k, v) { - return v.value - }).$max() - if (max < 10) { - max = 10 - } else if (max < 20) { - max = 20 - } else if (max < 100) { - max = 100 - } else { - max = null - } - teaweb.renderLineChart({ - id: "load-chart", - name: "负载", - values: this.loadValues, - x: function (v) { - return v.time - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].time + ":" + (Math.ceil(stats[args.dataIndex].value * 100) / 100) - }, - value: function (v) { - return v.value; - }, - axis: axis, - max: max - }) - } -}) \ No newline at end of file diff --git a/web/views/@default/clusters/cluster/boards/index.css b/web/views/@default/clusters/cluster/boards/index_plus.css similarity index 100% rename from web/views/@default/clusters/cluster/boards/index.css rename to web/views/@default/clusters/cluster/boards/index_plus.css diff --git a/web/views/@default/clusters/cluster/boards/index.css.map b/web/views/@default/clusters/cluster/boards/index_plus.css.map similarity index 100% rename from web/views/@default/clusters/cluster/boards/index.css.map rename to web/views/@default/clusters/cluster/boards/index_plus.css.map diff --git a/web/views/@default/clusters/cluster/boards/index.less b/web/views/@default/clusters/cluster/boards/index_plus.less similarity index 100% rename from web/views/@default/clusters/cluster/boards/index.less rename to web/views/@default/clusters/cluster/boards/index_plus.less diff --git a/web/views/@default/clusters/cluster/node/boards/index.html b/web/views/@default/clusters/cluster/node/boards/index.html deleted file mode 100644 index c9559a91..00000000 --- a/web/views/@default/clusters/cluster/node/boards/index.html +++ /dev/null @@ -1,128 +0,0 @@ -{$layout} -{$template "../node_menu"} -{$template "/echarts"} - - -
-
-
  数据加载中... -
-
- - -
-
-

在线状态

-
- 在线 - 离线 - 健康离线 - [上线] -
-
-
-

下行流量

-
{{board.trafficOutBytes}}/分钟
-
-
-

上行流量

-
{{board.trafficInBytes}}/分钟
-
-
-

连接数

-
{{board.countConnections}}/分钟
-
-
-

当前访问量

-
{{board.countRequests}}/分钟
-
-
-

当前攻击访问量

-
{{board.countAttackRequests}}/分钟
-
-
-

磁盘缓存用量

-
{{board.cacheDiskSize}}剩余{{cacheDirAvail}}
-
-
-

内存缓存用量

-
{{board.cacheMemorySize}}
-
-
-

CPU

-
{{board.cpuUsage}}%
-
-
-

内存

-
{{board.memoryUsage}}%
-
-
-

总内存

-
{{board.memoryTotalSize}}G
-
-
-

负载

-
{{board.load}}/分钟
-
-
- -
- - - - -
- - -
- -
- - - - -
- - -
- -
- - -

域名访问排行 (24小时)

-
- -
- - - - -
-
-
- - -
-

缓存目录用量(使用:{{cacheDirUsed}}/总量:{{cacheDirTotal}}/剩余:{{cacheDirAvail}})

-
- - -
- - - - \ No newline at end of file diff --git a/web/views/@default/clusters/cluster/node/boards/index.js b/web/views/@default/clusters/cluster/node/boards/index.js deleted file mode 100644 index b7198b6a..00000000 --- a/web/views/@default/clusters/cluster/node/boards/index.js +++ /dev/null @@ -1,527 +0,0 @@ -Tea.context(function () { - this.isLoading = true - this.board = {} - this.metricCharts = [] - - this.upNode = function (nodeId) { - teaweb.confirm("确定要手动上线此节点吗?", function () { - this.$post("/clusters/cluster/node/up") - .params({ - nodeId: nodeId - }) - .refresh() - }) - } - - this.formatCount = function (count) { - if (count < 1000) { - return count.toString() - } - if (count < 1000 * 1000) { - return (Math.round(count / 1000 * 100) / 100) + "K" - } - return (Math.round(count / 1000 / 1000 * 100) / 100) + "M" - } - - this.loadBoard = function () { - this.board.trafficInBytes = teaweb.formatBytes(this.board.trafficInBytes) - this.board.trafficOutBytes = teaweb.formatBytes(this.board.trafficOutBytes) - this.board.countConnections = this.formatCount(this.board.countConnections) - this.board.countRequests = this.formatCount(this.board.countRequests) - this.board.countAttackRequests = this.formatCount(this.board.countAttackRequests) - this.board.cpuUsage = Math.round(this.board.cpuUsage * 100 * 100) / 100 - this.board.memoryUsage = Math.round(this.board.memoryUsage * 100 * 100) / 100 - this.board.memoryTotalSize = Math.round(this.board.memoryTotalSize / 1024 / 1024 / 1024) - this.board.load = Math.round(this.board.load * 100) / 100 - this.board.cacheDiskSize = teaweb.formatBytes(this.board.cacheDiskSize) - this.board.cacheMemorySize = teaweb.formatBytes(this.board.cacheMemorySize) - } - - /** - * 流量统计 - */ - this.trafficTab = "hourly" - - this.$delay(function () { - this.$post("$") - .params({ - clusterId: this.clusterId, - nodeId: this.node.id - }) - .timeout(60) - .success(function (resp) { - for (let k in resp.data) { - this[k] = resp.data[k] - } - - this.loadBoard() - - this.isLoading = false - - this.$delay(function () { - this.reloadHourlyTrafficChart() - this.reloadHourlyRequestsChart() - this.reloadTopDomainsChart() - this.reloadCPUChart() - this.reloadCacheDirsChart() - - this.renderCacheDirData() - - this.refreshBoard() - }) - }) - }) - - this.refreshBoard = function () { - this.$post(".data") - .params({ - clusterId: this.clusterId, - nodeId: this.node.id - }) - .success(function (resp) { - this.board = resp.data.board - this.loadBoard() - }) - .done(function () { - this.$delay(function () { - this.refreshBoard() - }, 30000) - }) - } - - this.selectTrafficTab = function (tab) { - this.trafficTab = tab - if (tab == "hourly") { - this.$delay(function () { - this.reloadHourlyTrafficChart() - }) - } else if (tab == "daily") { - this.$delay(function () { - this.reloadDailyTrafficChart() - }) - } - } - - this.reloadHourlyTrafficChart = function () { - let stats = this.hourlyStats - this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].bytes > 0) { - cachedRatio = Math.round(stats[index].cachedBytes * 10000 / stats[index].bytes) / 100 - attackRatio = Math.round(stats[index].attackBytes * 10000 / stats[index].bytes) / 100 - } - - return stats[index].day + " " + stats[index].hour + "时
总流量:" + teaweb.formatBytes(stats[index].bytes) + "
缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "
缓存命中率:" + cachedRatio + "%
拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadDailyTrafficChart = function () { - let stats = this.dailyStats - this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].bytes > 0) { - cachedRatio = Math.round(stats[index].cachedBytes * 10000 / stats[index].bytes) / 100 - attackRatio = Math.round(stats[index].attackBytes * 10000 / stats[index].bytes) / 100 - } - - return stats[index].day + "
总流量:" + teaweb.formatBytes(stats[index].bytes) + "
缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "
缓存命中率:" + cachedRatio + "%
拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadTrafficChart = function (chartId, name, stats, tooltipFunc) { - let chartBox = document.getElementById(chartId) - if (chartBox == null) { - return - } - - let axis = teaweb.bytesAxis(stats, function (v) { - return Math.max(v.bytes, v.cachedBytes) - }) - - let chart = teaweb.initChart(chartBox) - let option = { - xAxis: { - data: stats.map(function (v) { - if (v.hour != null) { - return v.hour - } - return v.day - }) - }, - yAxis: { - axisLabel: { - formatter: function (value) { - return value + axis.unit - } - } - }, - tooltip: { - show: true, - trigger: "item", - formatter: tooltipFunc - }, - grid: { - left: 50, - top: 40, - right: 20, - bottom: 20 - }, - series: [ - { - name: "流量", - type: "line", - data: stats.map(function (v) { - return v.bytes / axis.divider - }), - itemStyle: { - color: "#9DD3E8" - }, - areaStyle: { - color: "#9DD3E8" - }, - smooth: true - }, - { - name: "缓存流量", - type: "line", - data: stats.map(function (v) { - return v.cachedBytes / axis.divider - }), - itemStyle: { - color: "#61A0A8" - }, - areaStyle: { - color: "#61A0A8" - }, - smooth: true - }, - { - name: "攻击流量", - type: "line", - data: stats.map(function (v) { - return v.attackBytes / axis.divider; - }), - itemStyle: { - color: "#F39494" - }, - areaStyle: { - color: "#F39494" - }, - smooth: true - } - ], - legend: { - data: ["流量", "缓存流量", "攻击流量"] - }, - animation: true - } - chart.setOption(option) - chart.resize() - } - - /** - * 请求数统计 - */ - this.requestsTab = "hourly" - - this.selectRequestsTab = function (tab) { - this.requestsTab = tab - if (tab == "hourly") { - this.$delay(function () { - this.reloadHourlyRequestsChart() - }) - } else if (tab == "daily") { - this.$delay(function () { - this.reloadDailyRequestsChart() - }) - } - } - - this.reloadHourlyRequestsChart = function () { - let stats = this.hourlyStats - this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].countRequests > 0) { - cachedRatio = Math.round(stats[index].countCachedRequests * 10000 / stats[index].countRequests) / 100 - attackRatio = Math.round(stats[index].countAttackRequests * 10000 / stats[index].countRequests) / 100 - } - - return stats[index].day + " " + stats[index].hour + "时
总请求数:" + teaweb.formatNumber(stats[index].countRequests) + "
缓存请求数:" + teaweb.formatNumber(stats[index].countCachedRequests) + "
缓存命中率:" + cachedRatio + "%
拦截攻击数:" + teaweb.formatNumber(stats[index].countAttackRequests) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadDailyRequestsChart = function () { - let stats = this.dailyStats - this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].countRequests > 0) { - cachedRatio = Math.round(stats[index].countCachedRequests * 10000 / stats[index].countRequests) / 100 - attackRatio = Math.round(stats[index].countAttackRequests * 10000 / stats[index].countRequests) / 100 - } - - return stats[index].day + "
总请求数:" + teaweb.formatNumber(stats[index].countRequests) + "
缓存请求数:" + teaweb.formatNumber(stats[index].countCachedRequests) + "
缓存命中率:" + cachedRatio + "%
拦截攻击数:" + teaweb.formatNumber(stats[index].countAttackRequests) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadRequestsChart = function (chartId, name, stats, tooltipFunc) { - let chartBox = document.getElementById(chartId) - if (chartBox == null) { - return - } - - let axis = teaweb.countAxis(stats, function (v) { - return Math.max(v.countRequests, v.countCachedRequests) - }) - - let chart = teaweb.initChart(chartBox) - let option = { - xAxis: { - data: stats.map(function (v) { - if (v.hour != null) { - return v.hour - } - if (v.day != null) { - return v.day - } - return "" - }) - }, - yAxis: { - axisLabel: { - formatter: function (value) { - return value + axis.unit - } - } - }, - tooltip: { - show: true, - trigger: "item", - formatter: tooltipFunc - }, - grid: { - left: 50, - top: 40, - right: 20, - bottom: 20 - }, - series: [ - { - name: "请求数", - type: "line", - data: stats.map(function (v) { - return v.countRequests / axis.divider - }), - itemStyle: { - color: "#9DD3E8" - }, - areaStyle: { - color: "#9DD3E8" - }, - smooth: true - }, - { - name: "缓存请求数", - type: "line", - data: stats.map(function (v) { - return v.countCachedRequests / axis.divider - }), - itemStyle: { - color: "#61A0A8" - }, - areaStyle: { - color: "#61A0A8" - }, - smooth: true - }, - { - name: "攻击请求数", - type: "line", - data: stats.map(function (v) { - return v.countAttackRequests / axis.divider; - }), - itemStyle: { - color: "#F39494" - }, - areaStyle: { - color: "#F39494" - }, - smooth: true - } - ], - legend: { - data: ["请求数", "缓存请求数", "攻击请求数"] - }, - animation: true - } - chart.setOption(option) - chart.resize() - } - - // 域名排行 - this.reloadTopDomainsChart = function () { - let axis = teaweb.countAxis(this.topDomainStats, function (v) { - return v.countRequests - }) - teaweb.renderBarChart({ - id: "top-domains-chart", - name: "域名", - values: this.topDomainStats, - x: function (v) { - return v.domain - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].domain + "
请求数:" + " " + teaweb.formatNumber(stats[args.dataIndex].countRequests) + "
流量:" + teaweb.formatBytes(stats[args.dataIndex].bytes) - }, - value: function (v) { - return v.countRequests / axis.divider; - }, - axis: axis, - click: function (args, stats) { - window.location = "/servers/server?serverId=" + stats[args.dataIndex].serverId - } - }) - } - - /** - * 系统信息 - */ - this.nodeStatusTab = "cpu" - - this.selectNodeStatusTab = function (tab) { - this.nodeStatusTab = tab - this.$delay(function () { - switch (tab) { - case "cpu": - this.reloadCPUChart() - break - case "memory": - this.reloadMemoryChart() - break - case "load": - this.reloadLoadChart() - break - } - }) - } - - this.reloadCPUChart = function () { - let axis = {unit: "%", divider: 1} - teaweb.renderLineChart({ - id: "cpu-chart", - name: "CPU", - values: this.cpuValues, - x: function (v) { - return v.time - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].time + ":" + (Math.ceil(stats[args.dataIndex].value * 100 * 100) / 100) + "%" - }, - value: function (v) { - return v.value * 100; - }, - axis: axis, - max: 100 - }) - } - - this.reloadMemoryChart = function () { - let axis = {unit: "%", divider: 1} - teaweb.renderLineChart({ - id: "memory-chart", - name: "内存", - values: this.memoryValues, - x: function (v) { - return v.time - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].time + ":" + (Math.ceil(stats[args.dataIndex].value * 100 * 100) / 100) + "%" - }, - value: function (v) { - return v.value * 100; - }, - axis: axis, - max: 100 - }) - } - - this.reloadLoadChart = function () { - let axis = {unit: "", divider: 1} - let max = this.loadValues.$map(function (k, v) { - return v.value - }).$max() - if (max < 10) { - max = 10 - } else if (max < 20) { - max = 20 - } else if (max < 100) { - max = 100 - } else { - max = null - } - teaweb.renderLineChart({ - id: "load-chart", - name: "负载", - values: this.loadValues, - x: function (v) { - return v.time - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].time + ":" + (Math.ceil(stats[args.dataIndex].value * 100) / 100) - }, - value: function (v) { - return v.value; - }, - axis: axis, - max: max - }) - } - - this.cacheDirUsed = "" - this.cacheDirTotal = "" - this.cacheDirAvail = "" - this.cacheDirAvailWarning = false - this.renderCacheDirData = function () { - if (this.cacheDirValues.length > 0) { - let lastStat = this.cacheDirValues.$last() - if (lastStat.value != null && lastStat.value.dirs != null && lastStat.value.dirs.length > 0) { - this.cacheDirUsed = teaweb.formatBytes(this.cacheDirValues.$last().value.dirs[0].used) - this.cacheDirTotal = teaweb.formatBytes(this.cacheDirValues.$last().value.dirs[0].total) - this.cacheDirAvail = teaweb.formatBytes(this.cacheDirValues.$last().value.dirs[0].avail) - this.cacheDirAvailWarning = (this.cacheDirValues.$last().value.dirs[0].avail < 1024 * 1024 * 1024 * 10) - } - } - } - - this.reloadCacheDirsChart = function () { - let axis = {unit: "%", divider: 1} - teaweb.renderLineChart({ - id: "cache-dirs-chart", - name: "缓存目录用量", - values: this.cacheDirValues, - x: function (v) { - return v.time - }, - tooltip: function (args, stats) { - var v = stats[args.dataIndex].value.dirs[0] - return stats[args.dataIndex].time + "
使用:" + teaweb.formatBytes(v.used) + "
总量:" + teaweb.formatBytes(v.total) + "
比例:" + (Math.ceil(v.used * 100 / v.total * 100) / 100) + "%" - }, - value: function (v) { - if (v.value == null || v.value.dirs == null || v.value.dirs.length == 0) { - return 0 - } - v = v.value.dirs[0] - return (v.used * 100 / v.total); - }, - axis: axis, - max: 100 - }) - } -}) \ No newline at end of file diff --git a/web/views/@default/clusters/cluster/node/boards/index.css b/web/views/@default/clusters/cluster/node/boards/index_plus.css similarity index 100% rename from web/views/@default/clusters/cluster/node/boards/index.css rename to web/views/@default/clusters/cluster/node/boards/index_plus.css diff --git a/web/views/@default/clusters/cluster/node/boards/index.css.map b/web/views/@default/clusters/cluster/node/boards/index_plus.css.map similarity index 100% rename from web/views/@default/clusters/cluster/node/boards/index.css.map rename to web/views/@default/clusters/cluster/node/boards/index_plus.css.map diff --git a/web/views/@default/clusters/cluster/node/boards/index.less b/web/views/@default/clusters/cluster/node/boards/index_plus.less similarity index 100% rename from web/views/@default/clusters/cluster/node/boards/index.less rename to web/views/@default/clusters/cluster/node/boards/index_plus.less diff --git a/web/views/@default/servers/server/boards/index.html b/web/views/@default/servers/server/boards/index.html deleted file mode 100644 index ff74c152..00000000 --- a/web/views/@default/servers/server/boards/index.html +++ /dev/null @@ -1,73 +0,0 @@ -{$layout} - -{$var "header"} - - - - -{$end} - - - 服务列表 - | - "{{server.name}}"看板 - | - - - - -
-
-
  数据加载中... -
-
- - -
- -
-
- - - - -
- - -
- -
- - - -
- - -
- -
- - -

域名访问排行 (24小时)

-
- -
- - -
- - - - \ No newline at end of file diff --git a/web/views/@default/servers/server/boards/index.js b/web/views/@default/servers/server/boards/index.js deleted file mode 100644 index 7c2e463f..00000000 --- a/web/views/@default/servers/server/boards/index.js +++ /dev/null @@ -1,340 +0,0 @@ -Tea.context(function () { - this.isLoading = true - this.metricCharts = [] - - this.formatCount = function (count) { - if (count < 1000) { - return count.toString() - } - if (count < 1000 * 1000) { - return (Math.round(count / 1000 * 100) / 100) + "K" - } - return (Math.round(count / 1000 / 1000 * 100) / 100) + "M" - } - - /** - * 流量统计 - */ - this.trafficTab = "hourly" - - this.$delay(function () { - this.load() - }) - - this.load = function () { - this.$post("$") - .params({ - serverId: this.server.id - }) - .success(function (resp) { - for (let k in resp.data) { - this[k] = resp.data[k] - } - this.isLoading = false - - this.$delay(function () { - this.reloadHourlyTrafficChart() - this.reloadHourlyRequestsChart() - this.reloadTopDomainsChart() - }) - }) - } - - this.selectTrafficTab = function (tab) { - this.trafficTab = tab - if (tab == "hourly") { - this.$delay(function () { - this.reloadHourlyTrafficChart() - }) - } else if (tab == "daily") { - this.$delay(function () { - this.reloadDailyTrafficChart() - }) - } - } - - this.reloadHourlyTrafficChart = function () { - let stats = this.hourlyStats - this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].bytes > 0) { - cachedRatio = Math.round(stats[index].cachedBytes * 10000 / stats[index].bytes) / 100 - attackRatio = Math.round(stats[index].attackBytes * 10000 / stats[index].bytes) / 100 - } - - return stats[index].day + " " + stats[index].hour + "时
总流量:" + teaweb.formatBytes(stats[index].bytes) + "
缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "
缓存命中率:" + cachedRatio + "%
拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadDailyTrafficChart = function () { - let stats = this.dailyStats - this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].bytes > 0) { - cachedRatio = Math.round(stats[index].cachedBytes * 10000 / stats[index].bytes) / 100 - attackRatio = Math.round(stats[index].attackBytes * 10000 / stats[index].bytes) / 100 - } - - return stats[index].day + "
总流量:" + teaweb.formatBytes(stats[index].bytes) + "
缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "
缓存命中率:" + cachedRatio + "%
拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadTrafficChart = function (chartId, name, stats, tooltipFunc) { - let chartBox = document.getElementById(chartId) - if (chartBox == null) { - return - } - - let axis = teaweb.bytesAxis(stats, function (v) { - return Math.max(v.bytes, v.cachedBytes) - }) - - let chart = teaweb.initChart(chartBox) - let option = { - xAxis: { - data: stats.map(function (v) { - if (v.hour != null) { - return v.hour - } - return v.day - }) - }, - yAxis: { - axisLabel: { - formatter: function (value) { - return value + axis.unit - } - } - }, - tooltip: { - show: true, - trigger: "item", - formatter: tooltipFunc - }, - grid: { - left: 50, - top: 40, - right: 20, - bottom: 20 - }, - series: [ - { - name: "流量", - type: "line", - data: stats.map(function (v) { - return v.bytes / axis.divider - }), - itemStyle: { - color: "#9DD3E8" - }, - areaStyle: { - color: "#9DD3E8" - }, - smooth: true - }, - { - name: "缓存流量", - type: "line", - data: stats.map(function (v) { - return v.cachedBytes / axis.divider - }), - itemStyle: { - color: "#61A0A8" - }, - areaStyle: { - color: "#61A0A8" - }, - smooth: true - }, - { - name: "攻击流量", - type: "line", - data: stats.map(function (v) { - return v.attackBytes / axis.divider; - }), - itemStyle: { - color: "#F39494" - }, - areaStyle: { - color: "#F39494" - }, - smooth: true - } - ], - legend: { - data: ["流量", "缓存流量", "攻击流量"] - }, - animation: true - } - chart.setOption(option) - chart.resize() - } - - /** - * 请求数统计 - */ - this.requestsTab = "hourly" - - this.selectRequestsTab = function (tab) { - this.requestsTab = tab - if (tab == "hourly") { - this.$delay(function () { - this.reloadHourlyRequestsChart() - }) - } else if (tab == "daily") { - this.$delay(function () { - this.reloadDailyRequestsChart() - }) - } - } - - this.reloadHourlyRequestsChart = function () { - let stats = this.hourlyStats - this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].countRequests > 0) { - cachedRatio = Math.round(stats[index].countCachedRequests * 10000 / stats[index].countRequests) / 100 - attackRatio = Math.round(stats[index].countAttackRequests * 10000 / stats[index].countRequests) / 100 - } - - return stats[index].day + " " + stats[index].hour + "时
总请求数:" + teaweb.formatNumber(stats[index].countRequests) + "
缓存请求数:" + teaweb.formatNumber(stats[index].countCachedRequests) + "
缓存命中率:" + cachedRatio + "%
拦截攻击数:" + teaweb.formatNumber(stats[index].countAttackRequests) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadDailyRequestsChart = function () { - let stats = this.dailyStats - this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) { - let index = args.dataIndex - let cachedRatio = 0 - let attackRatio = 0 - if (stats[index].countRequests > 0) { - cachedRatio = Math.round(stats[index].countCachedRequests * 10000 / stats[index].countRequests) / 100 - attackRatio = Math.round(stats[index].countAttackRequests * 10000 / stats[index].countRequests) / 100 - } - - return stats[index].day + "
总请求数:" + teaweb.formatNumber(stats[index].countRequests) + "
缓存请求数:" + teaweb.formatNumber(stats[index].countCachedRequests) + "
缓存命中率:" + cachedRatio + "%
拦截攻击数:" + teaweb.formatNumber(stats[index].countAttackRequests) + "
拦截比例:" + attackRatio + "%" - }) - } - - this.reloadRequestsChart = function (chartId, name, stats, tooltipFunc) { - let chartBox = document.getElementById(chartId) - if (chartBox == null) { - return - } - - let axis = teaweb.countAxis(stats, function (v) { - return Math.max(v.countRequests, v.countCachedRequests) - }) - - let chart = teaweb.initChart(chartBox) - let option = { - xAxis: { - data: stats.map(function (v) { - if (v.hour != null) { - return v.hour - } - if (v.day != null) { - return v.day - } - return "" - }) - }, - yAxis: { - axisLabel: { - formatter: function (value) { - return value + axis.unit - } - } - }, - tooltip: { - show: true, - trigger: "item", - formatter: tooltipFunc - }, - grid: { - left: 50, - top: 40, - right: 20, - bottom: 20 - }, - series: [ - { - name: "请求数", - type: "line", - data: stats.map(function (v) { - return v.countRequests / axis.divider - }), - itemStyle: { - color: "#9DD3E8" - }, - areaStyle: { - color: "#9DD3E8" - }, - smooth: true - }, - { - name: "缓存请求数", - type: "line", - data: stats.map(function (v) { - return v.countCachedRequests / axis.divider - }), - itemStyle: { - color: "#61A0A8" - }, - areaStyle: { - color: "#61A0A8" - }, - smooth: true - }, - { - name: "攻击请求数", - type: "line", - data: stats.map(function (v) { - return v.countAttackRequests / axis.divider; - }), - itemStyle: { - color: "#F39494" - }, - areaStyle: { - color: "#F39494" - }, - smooth: true - } - ], - legend: { - data: ["请求数", "缓存请求数", "攻击请求数"] - }, - animation: true - } - chart.setOption(option) - chart.resize() - } - - // 域名排行 - this.reloadTopDomainsChart = function () { - let axis = teaweb.countAxis(this.topDomainStats, function (v) { - return v.countRequests - }) - teaweb.renderBarChart({ - id: "top-domains-chart", - name: "域名", - values: this.topDomainStats, - x: function (v) { - return v.domain - }, - tooltip: function (args, stats) { - return stats[args.dataIndex].domain + "
请求数:" + " " + teaweb.formatNumber(stats[args.dataIndex].countRequests) + "
流量:" + teaweb.formatBytes(stats[args.dataIndex].bytes) - }, - value: function (v) { - return v.countRequests / axis.divider; - }, - axis: axis - }) - } -}) \ No newline at end of file diff --git a/web/views/@default/servers/server/boards/index.css b/web/views/@default/servers/server/boards/index_plus.css similarity index 100% rename from web/views/@default/servers/server/boards/index.css rename to web/views/@default/servers/server/boards/index_plus.css diff --git a/web/views/@default/servers/server/boards/index.css.map b/web/views/@default/servers/server/boards/index_plus.css.map similarity index 100% rename from web/views/@default/servers/server/boards/index.css.map rename to web/views/@default/servers/server/boards/index_plus.css.map diff --git a/web/views/@default/servers/server/boards/index.less b/web/views/@default/servers/server/boards/index_plus.less similarity index 100% rename from web/views/@default/servers/server/boards/index.less rename to web/views/@default/servers/server/boards/index_plus.less