mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-10 17:30:29 +08:00
实现服务看板(企业版)
This commit is contained in:
@@ -1,16 +0,0 @@
|
|||||||
package board
|
|
||||||
|
|
||||||
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
|
||||||
|
|
||||||
type IndexAction struct {
|
|
||||||
actionutils.ParentAction
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *IndexAction) Init() {
|
|
||||||
this.Nav("", "board", "")
|
|
||||||
this.SecondMenu("index")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *IndexAction) RunGet(params struct{}) {
|
|
||||||
this.Show()
|
|
||||||
}
|
|
||||||
131
internal/web/actions/default/servers/server/boards/index.go
Normal file
131
internal/web/actions/default/servers/server/boards/index.go
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package boards
|
||||||
|
|
||||||
|
import (
|
||||||
|
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
"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,
|
||||||
|
"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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["topDomainStats"] = statMaps
|
||||||
|
}
|
||||||
|
|
||||||
|
// 指标
|
||||||
|
{
|
||||||
|
var chartMaps = []maps.Map{}
|
||||||
|
for _, chart := range resp.MetricCharts {
|
||||||
|
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),
|
||||||
|
},
|
||||||
|
"stats": statMaps,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.Data["metricCharts"] = chartMaps
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package board
|
package boards
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||||
@@ -12,7 +12,7 @@ func init() {
|
|||||||
server.
|
server.
|
||||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||||
Helper(serverutils.NewServerHelper()).
|
Helper(serverutils.NewServerHelper()).
|
||||||
Prefix("/servers/server/board").
|
Prefix("/servers/server/boards").
|
||||||
Get("", new(IndexAction)).
|
Get("", new(IndexAction)).
|
||||||
EndAll()
|
EndAll()
|
||||||
})
|
})
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
@@ -34,5 +35,9 @@ func (this *IndexAction) RunGet(params struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HTTP跳转到访问日志
|
// HTTP跳转到访问日志
|
||||||
this.RedirectURL("/servers/server/log?serverId=" + strconv.FormatInt(params.ServerId, 10))
|
if teaconst.IsPlus {
|
||||||
|
this.RedirectURL("/servers/server/boards?serverId=" + strconv.FormatInt(params.ServerId, 10))
|
||||||
|
} else {
|
||||||
|
this.RedirectURL("/servers/server/stat?serverId=" + strconv.FormatInt(params.ServerId, 10))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package serverutils
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
@@ -92,13 +93,15 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
|
|||||||
selectedTabbar, _ := action.Data["mainTab"]
|
selectedTabbar, _ := action.Data["mainTab"]
|
||||||
tabbar := actionutils.NewTabbar()
|
tabbar := actionutils.NewTabbar()
|
||||||
tabbar.Add("服务列表", "", "/servers", "", false)
|
tabbar.Add("服务列表", "", "/servers", "", false)
|
||||||
//tabbar.Add("看板", "", "/servers/server/board?serverId="+serverIdString, "dashboard", selectedTabbar == "board")
|
if teaconst.IsPlus {
|
||||||
if family == "http" {
|
tabbar.Add("看板", "", "/servers/server/boards?serverId="+serverIdString, "dashboard", selectedTabbar == "board")
|
||||||
tabbar.Add("日志", "", "/servers/server/log?serverId="+serverIdString, "history", selectedTabbar == "log")
|
|
||||||
}
|
}
|
||||||
if family == "http" {
|
if family == "http" {
|
||||||
tabbar.Add("统计", "", "/servers/server/stat?serverId="+serverIdString, "chart area", selectedTabbar == "stat")
|
tabbar.Add("统计", "", "/servers/server/stat?serverId="+serverIdString, "chart area", selectedTabbar == "stat")
|
||||||
}
|
}
|
||||||
|
if family == "http" {
|
||||||
|
tabbar.Add("日志", "", "/servers/server/log?serverId="+serverIdString, "history", selectedTabbar == "log")
|
||||||
|
}
|
||||||
tabbar.Add("设置", "", "/servers/server/settings?serverId="+serverIdString, "setting", selectedTabbar == "setting")
|
tabbar.Add("设置", "", "/servers/server/settings?serverId="+serverIdString, "setting", selectedTabbar == "setting")
|
||||||
tabbar.Add("删除", "", "/servers/server/delete?serverId="+serverIdString, "trash", selectedTabbar == "delete")
|
tabbar.Add("删除", "", "/servers/server/delete?serverId="+serverIdString, "trash", selectedTabbar == "delete")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,8 +60,11 @@ import (
|
|||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/groups"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/groups"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/log"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/log"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/waf"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/waf"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/iplists"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics"
|
||||||
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics/charts"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/board"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/boards"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/delete"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/delete"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/log"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/log"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings"
|
||||||
@@ -109,11 +112,6 @@ import (
|
|||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/websocket"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/websocket"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/stat"
|
||||||
|
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/iplists"
|
|
||||||
|
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics"
|
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics/charts"
|
|
||||||
|
|
||||||
// 设置相关
|
// 设置相关
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/authority"
|
||||||
|
|||||||
@@ -68,10 +68,10 @@
|
|||||||
<tr v-for="node in nodes">
|
<tr v-for="node in nodes">
|
||||||
<td>{{node.name}}
|
<td>{{node.name}}
|
||||||
<div style="margin-top: 0.5em" v-if="node.region != null">
|
<div style="margin-top: 0.5em" v-if="node.region != null">
|
||||||
<tiny-label class="basic">区域:{{node.region.name}}</tiny-label>
|
<tiny-basic-label>区域:{{node.region.name}}</tiny-basic-label>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 0.5em" v-if="node.group != null">
|
<div style="margin-top: 0.5em" v-if="node.group != null">
|
||||||
<tiny-label class="basic">分组:{{node.group.name}}</tiny-label>
|
<tiny-basic-label>分组:{{node.group.name}}</tiny-basic-label>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
undefined
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{$layout}
|
|
||||||
|
|
||||||
{$template "/left_menu"}
|
|
||||||
<div class="right-box">
|
|
||||||
<div class="ui message">此功能暂未开放,敬请期待。</div>
|
|
||||||
</div>
|
|
||||||
32
web/views/@default/servers/server/boards/index.css
Normal file
32
web/views/@default/servers/server/boards/index.css
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
.grid {
|
||||||
|
margin-top: 2em !important;
|
||||||
|
margin-left: 2em !important;
|
||||||
|
}
|
||||||
|
.grid .column {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
border-right: 1px #eee solid;
|
||||||
|
}
|
||||||
|
.grid .column div.value {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
|
.grid .column div.value span {
|
||||||
|
font-size: 2em;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
}
|
||||||
|
.grid .column.no-border {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
.grid h4 a {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.grid .column:hover a {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.chart-box {
|
||||||
|
height: 20em;
|
||||||
|
}
|
||||||
|
h4 span {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
/*# sourceMappingURL=index.css.map */
|
||||||
1
web/views/@default/servers/server/boards/index.css.map
Normal file
1
web/views/@default/servers/server/boards/index.css.map
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACC,0BAAA;EACA,2BAAA;;AAFD,KAIC;EACC,kBAAA;EACA,4BAAA;;AANF,KAIC,QAIC,IAAG;EACF,iBAAA;;AATH,KAIC,QAIC,IAAG,MAGF;EACC,cAAA;EACA,mBAAA;;AAbJ,KAkBC,QAAO;EACN,eAAA;;AAnBF,KAsBC,GACC;EACC,aAAA;;AAxBH,KA4BC,QAAO,MACN;EACC,eAAA;;AAKH;EACC,YAAA;;AAGD,EACC;EACC,gBAAA;EACA,WAAA","file":"index.css"}
|
||||||
39
web/views/@default/servers/server/boards/index.html
Normal file
39
web/views/@default/servers/server/boards/index.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{$layout}
|
||||||
|
{$template "/echarts"}
|
||||||
|
|
||||||
|
<div class="ui menu tabular">
|
||||||
|
<a href="" class="item" :class="{active: trafficTab == 'hourly'}" @click.prevent="selectTrafficTab('hourly')">24小时流量趋势</a>
|
||||||
|
<a href="" class="item" :class="{active: trafficTab == 'daily'}" @click.prevent="selectTrafficTab('daily')">15天流量趋势</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 按小时统计流量 -->
|
||||||
|
<div class="chart-box" id="hourly-traffic-chart" v-show="trafficTab == 'hourly'"></div>
|
||||||
|
|
||||||
|
<!-- 按日统计流量 -->
|
||||||
|
<div class="chart-box" id="daily-traffic-chart" v-show="trafficTab == 'daily'"></div>
|
||||||
|
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
<div class="ui menu tabular">
|
||||||
|
<a href="" class="item" :class="{active: requestsTab == 'hourly'}" @click.prevent="selectRequestsTab('hourly')">24小时访问量趋势</a>
|
||||||
|
<a href="" class="item" :class="{active: requestsTab == 'daily'}" @click.prevent="selectRequestsTab('daily')">15天访问量趋势</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 按小时统计访问量 -->
|
||||||
|
<div class="chart-box" id="hourly-requests-chart" v-show="requestsTab == 'hourly'"></div>
|
||||||
|
|
||||||
|
<!-- 按日统计访问量 -->
|
||||||
|
<div class="chart-box" id="daily-requests-chart" v-show="requestsTab == 'daily'"></div>
|
||||||
|
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
|
<!-- 域名排行 -->
|
||||||
|
<h4>域名访问排行 <span>(24小时)</span></h4>
|
||||||
|
<div class="chart-box" id="top-domains-chart"></div>
|
||||||
|
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
|
<!-- 指标 -->
|
||||||
|
<div class="ui divider" v-if="metricCharts.length > 0"></div>
|
||||||
|
<metric-board>
|
||||||
|
<metric-chart v-for="chart in metricCharts" :key="chart.id" :v-chart="chart.chart" :v-stats="chart.stats" :v-period="chart.item.period" :v-period-unit="chart.item.periodUnit" :v-value-type="chart.item.valueType"></metric-chart>
|
||||||
|
</metric-board>
|
||||||
296
web/views/@default/servers/server/boards/index.js
Normal file
296
web/views/@default/servers/server/boards/index.js
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
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.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) {
|
||||||
|
if (args.seriesIndex == 0) {
|
||||||
|
return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
|
||||||
|
}
|
||||||
|
if (args.seriesIndex == 1) {
|
||||||
|
let ratio = 0
|
||||||
|
if (stats[args.dataIndex].bytes > 0) {
|
||||||
|
ratio = Math.round(stats[args.dataIndex].cachedBytes * 10000 / stats[args.dataIndex].bytes) / 100
|
||||||
|
}
|
||||||
|
return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 缓存流量: " + teaweb.formatBytes(stats[args.dataIndex].cachedBytes) + ", 命中率:" + ratio + "%"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.reloadDailyTrafficChart = function () {
|
||||||
|
let stats = this.dailyStats
|
||||||
|
this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) {
|
||||||
|
if (args.seriesIndex == 0) {
|
||||||
|
return stats[args.dataIndex].day + " 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
|
||||||
|
}
|
||||||
|
if (args.seriesIndex == 1) {
|
||||||
|
let ratio = 0
|
||||||
|
if (stats[args.dataIndex].bytes > 0) {
|
||||||
|
ratio = Math.round(stats[args.dataIndex].cachedBytes * 10000 / stats[args.dataIndex].bytes) / 100
|
||||||
|
}
|
||||||
|
return stats[args.dataIndex].day + " 缓存流量: " + teaweb.formatBytes(stats[args.dataIndex].cachedBytes) + ", 命中率:" + ratio + "%"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = echarts.init(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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "缓存流量",
|
||||||
|
type: "line",
|
||||||
|
data: stats.map(function (v) {
|
||||||
|
return v.cachedBytes / axis.divider
|
||||||
|
}),
|
||||||
|
itemStyle: {
|
||||||
|
color: "#61A0A8"
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
color: "#61A0A8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
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) {
|
||||||
|
if (args.seriesIndex == 0) {
|
||||||
|
return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
|
||||||
|
}
|
||||||
|
if (args.seriesIndex == 1) {
|
||||||
|
let ratio = 0
|
||||||
|
if (stats[args.dataIndex].countRequests > 0) {
|
||||||
|
ratio = Math.round(stats[args.dataIndex].countCachedRequests * 10000 / stats[args.dataIndex].countRequests) / 100
|
||||||
|
}
|
||||||
|
return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 缓存请求数: " + teaweb.formatNumber(stats[args.dataIndex].countCachedRequests) + ", 命中率:" + ratio + "%"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.reloadDailyRequestsChart = function () {
|
||||||
|
let stats = this.dailyStats
|
||||||
|
this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) {
|
||||||
|
if (args.seriesIndex == 0) {
|
||||||
|
return stats[args.dataIndex].day + " 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
|
||||||
|
}
|
||||||
|
if (args.seriesIndex == 1) {
|
||||||
|
let ratio = 0
|
||||||
|
if (stats[args.dataIndex].countRequests > 0) {
|
||||||
|
ratio = Math.round(stats[args.dataIndex].countCachedRequests * 10000 / stats[args.dataIndex].countRequests) / 100
|
||||||
|
}
|
||||||
|
return stats[args.dataIndex].day + " 缓存请求数: " + teaweb.formatNumber(stats[args.dataIndex].countCachedRequests) + ", 命中率:" + ratio + "%"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = echarts.init(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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "缓存请求数",
|
||||||
|
type: "line",
|
||||||
|
data: stats.map(function (v) {
|
||||||
|
return v.countCachedRequests / axis.divider
|
||||||
|
}),
|
||||||
|
itemStyle: {
|
||||||
|
color: "#61A0A8"
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
color: "#61A0A8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
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 + "<br/>请求数:" + " " + teaweb.formatNumber(stats[args.dataIndex].countRequests) + "<br/>流量:" + teaweb.formatBytes(stats[args.dataIndex].bytes)
|
||||||
|
},
|
||||||
|
value: function (v) {
|
||||||
|
return v.countRequests / axis.divider;
|
||||||
|
},
|
||||||
|
axis: axis
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
45
web/views/@default/servers/server/boards/index.less
Normal file
45
web/views/@default/servers/server/boards/index.less
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
.grid {
|
||||||
|
margin-top: 2em !important;
|
||||||
|
margin-left: 2em !important;
|
||||||
|
|
||||||
|
.column {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
border-right: 1px #eee solid;
|
||||||
|
|
||||||
|
div.value {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 2em;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.no-border {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
a {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column:hover {
|
||||||
|
a {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-box {
|
||||||
|
height: 20em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
span {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user