mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	优化看板
This commit is contained in:
		@@ -50,6 +50,8 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
				"cachedBytes":         stat.CachedBytes,
 | 
									"cachedBytes":         stat.CachedBytes,
 | 
				
			||||||
				"countRequests":       stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"countCachedRequests": stat.CountCachedRequests,
 | 
									"countCachedRequests": stat.CountCachedRequests,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
				"day":                 stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
 | 
									"day":                 stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
 | 
				
			||||||
				"hour":                stat.Hour[8:],
 | 
									"hour":                stat.Hour[8:],
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
@@ -66,6 +68,8 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
				"cachedBytes":         stat.CachedBytes,
 | 
									"cachedBytes":         stat.CachedBytes,
 | 
				
			||||||
				"countRequests":       stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"countCachedRequests": stat.CountCachedRequests,
 | 
									"countCachedRequests": stat.CountCachedRequests,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
				"day":                 stat.Day[4:6] + "月" + stat.Day[6:] + "日",
 | 
									"day":                 stat.Day[4:6] + "月" + stat.Day[6:] + "日",
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,6 +69,8 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
				"cachedBytes":         stat.CachedBytes,
 | 
									"cachedBytes":         stat.CachedBytes,
 | 
				
			||||||
				"countRequests":       stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"countCachedRequests": stat.CountCachedRequests,
 | 
									"countCachedRequests": stat.CountCachedRequests,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
				"day":                 stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
 | 
									"day":                 stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
 | 
				
			||||||
				"hour":                stat.Hour[8:],
 | 
									"hour":                stat.Hour[8:],
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
@@ -85,6 +87,8 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
				"cachedBytes":         stat.CachedBytes,
 | 
									"cachedBytes":         stat.CachedBytes,
 | 
				
			||||||
				"countRequests":       stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"countCachedRequests": stat.CountCachedRequests,
 | 
									"countCachedRequests": stat.CountCachedRequests,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
				"day":                 stat.Day[4:6] + "月" + stat.Day[6:] + "日",
 | 
									"day":                 stat.Day[4:6] + "月" + stat.Day[6:] + "日",
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,8 +80,14 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
				
			|||||||
		statMaps := []maps.Map{}
 | 
							statMaps := []maps.Map{}
 | 
				
			||||||
		for _, stat := range resp.HourlyTrafficStats {
 | 
							for _, stat := range resp.HourlyTrafficStats {
 | 
				
			||||||
			statMaps = append(statMaps, maps.Map{
 | 
								statMaps = append(statMaps, maps.Map{
 | 
				
			||||||
				"bytes": stat.Bytes,
 | 
									"bytes":               stat.Bytes,
 | 
				
			||||||
				"hour":  stat.Hour[8:],
 | 
									"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["hourlyTrafficStats"] = statMaps
 | 
							this.Data["hourlyTrafficStats"] = statMaps
 | 
				
			||||||
@@ -92,13 +98,46 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
				
			|||||||
		statMaps := []maps.Map{}
 | 
							statMaps := []maps.Map{}
 | 
				
			||||||
		for _, stat := range resp.DailyTrafficStats {
 | 
							for _, stat := range resp.DailyTrafficStats {
 | 
				
			||||||
			statMaps = append(statMaps, maps.Map{
 | 
								statMaps = append(statMaps, maps.Map{
 | 
				
			||||||
				"bytes": stat.Bytes,
 | 
									"bytes":               stat.Bytes,
 | 
				
			||||||
				"day":   stat.Day[4:6] + "月" + stat.Day[6:] + "日",
 | 
									"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["dailyTrafficStats"] = statMaps
 | 
							this.Data["dailyTrafficStats"] = 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
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 版本升级
 | 
						// 版本升级
 | 
				
			||||||
	if resp.NodeUpgradeInfo != nil {
 | 
						if resp.NodeUpgradeInfo != nil {
 | 
				
			||||||
		this.Data["nodeUpgradeInfo"] = maps.Map{
 | 
							this.Data["nodeUpgradeInfo"] = maps.Map{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,21 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
		return
 | 
							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,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp, err := this.RPC().ServerStatBoardRPC().ComposeServerStatBoard(this.AdminContext(), &pb.ComposeServerStatBoardRequest{ServerId: params.ServerId})
 | 
						resp, err := this.RPC().ServerStatBoardRPC().ComposeServerStatBoard(this.AdminContext(), &pb.ComposeServerStatBoardRequest{ServerId: params.ServerId})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.ErrorPage(err)
 | 
							this.ErrorPage(err)
 | 
				
			||||||
@@ -41,6 +56,8 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
				"cachedBytes":         stat.CachedBytes,
 | 
									"cachedBytes":         stat.CachedBytes,
 | 
				
			||||||
				"countRequests":       stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"countCachedRequests": stat.CountCachedRequests,
 | 
									"countCachedRequests": stat.CountCachedRequests,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
				"day":                 stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
 | 
									"day":                 stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
 | 
				
			||||||
				"hour":                stat.Hour[8:],
 | 
									"hour":                stat.Hour[8:],
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
@@ -57,6 +74,8 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
				"cachedBytes":         stat.CachedBytes,
 | 
									"cachedBytes":         stat.CachedBytes,
 | 
				
			||||||
				"countRequests":       stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"countCachedRequests": stat.CountCachedRequests,
 | 
									"countCachedRequests": stat.CountCachedRequests,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
				"day":                 stat.Day[4:6] + "月" + stat.Day[6:] + "日",
 | 
									"day":                 stat.Day[4:6] + "月" + stat.Day[6:] + "日",
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -68,10 +87,12 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
		var statMaps = []maps.Map{}
 | 
							var statMaps = []maps.Map{}
 | 
				
			||||||
		for _, stat := range resp.TopNodeStats {
 | 
							for _, stat := range resp.TopNodeStats {
 | 
				
			||||||
			statMaps = append(statMaps, maps.Map{
 | 
								statMaps = append(statMaps, maps.Map{
 | 
				
			||||||
				"nodeId":        stat.NodeId,
 | 
									"nodeId":              stat.NodeId,
 | 
				
			||||||
				"nodeName":      stat.NodeName,
 | 
									"nodeName":            stat.NodeName,
 | 
				
			||||||
				"countRequests": stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"bytes":         stat.Bytes,
 | 
									"bytes":               stat.Bytes,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		this.Data["topNodeStats"] = statMaps
 | 
							this.Data["topNodeStats"] = statMaps
 | 
				
			||||||
@@ -82,10 +103,12 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
		var statMaps = []maps.Map{}
 | 
							var statMaps = []maps.Map{}
 | 
				
			||||||
		for _, stat := range resp.TopDomainStats {
 | 
							for _, stat := range resp.TopDomainStats {
 | 
				
			||||||
			statMaps = append(statMaps, maps.Map{
 | 
								statMaps = append(statMaps, maps.Map{
 | 
				
			||||||
				"serverId":      stat.ServerId,
 | 
									"serverId":            stat.ServerId,
 | 
				
			||||||
				"domain":        stat.Domain,
 | 
									"domain":              stat.Domain,
 | 
				
			||||||
				"countRequests": stat.CountRequests,
 | 
									"countRequests":       stat.CountRequests,
 | 
				
			||||||
				"bytes":         stat.Bytes,
 | 
									"bytes":               stat.Bytes,
 | 
				
			||||||
 | 
									"countAttackRequests": stat.CountAttackRequests,
 | 
				
			||||||
 | 
									"attackBytes":         stat.AttackBytes,
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		this.Data["topDomainStats"] = statMaps
 | 
							this.Data["topDomainStats"] = statMaps
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,34 +28,30 @@ Tea.context(function () {
 | 
				
			|||||||
	this.reloadHourlyTrafficChart = function () {
 | 
						this.reloadHourlyTrafficChart = function () {
 | 
				
			||||||
		let stats = this.hourlyStats
 | 
							let stats = this.hourlyStats
 | 
				
			||||||
		this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) {
 | 
							this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + " " + stats[index].hour  + "时<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 () {
 | 
						this.reloadDailyTrafficChart = function () {
 | 
				
			||||||
		let stats = this.dailyStats
 | 
							let stats = this.dailyStats
 | 
				
			||||||
		this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) {
 | 
							this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + "<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 ""
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -123,10 +119,20 @@ Tea.context(function () {
 | 
				
			|||||||
					areaStyle: {
 | 
										areaStyle: {
 | 
				
			||||||
						color: "#61A0A8"
 | 
											color: "#61A0A8"
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击流量",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.attackBytes / axis.divider
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
			legend: {
 | 
								legend: {
 | 
				
			||||||
				data: ['流量', '缓存流量']
 | 
									data: ["流量", "缓存流量", "攻击流量"]
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			animation: true
 | 
								animation: true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -155,34 +161,30 @@ Tea.context(function () {
 | 
				
			|||||||
	this.reloadHourlyRequestsChart = function () {
 | 
						this.reloadHourlyRequestsChart = function () {
 | 
				
			||||||
		let stats = this.hourlyStats
 | 
							let stats = this.hourlyStats
 | 
				
			||||||
		this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) {
 | 
							this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + " " + stats[index].hour + "时<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 () {
 | 
						this.reloadDailyRequestsChart = function () {
 | 
				
			||||||
		let stats = this.dailyStats
 | 
							let stats = this.dailyStats
 | 
				
			||||||
		this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) {
 | 
							this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + "<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 ""
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -253,10 +255,23 @@ Tea.context(function () {
 | 
				
			|||||||
					areaStyle: {
 | 
										areaStyle: {
 | 
				
			||||||
						color: "#61A0A8"
 | 
											color: "#61A0A8"
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击请求数",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.countAttackRequests / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
			legend: {
 | 
								legend: {
 | 
				
			||||||
				data: ['请求数', '缓存请求数']
 | 
									data: ["请求数", "缓存请求数", "攻击请求数"]
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			animation: true
 | 
								animation: true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<second-menu>
 | 
					<second-menu>
 | 
				
			||||||
	<menu-item :href="'/clusters/cluster/nodes?clusterId=' + clusterId">节点列表</menu-item>
 | 
						<menu-item :href="'/clusters/cluster/nodes?clusterId=' + clusterId">节点列表</menu-item>
 | 
				
			||||||
	<span class="item">|</span>
 | 
						<span class="item disabled">|</span>
 | 
				
			||||||
	<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + node.id" code="node"
 | 
						<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + node.id" code="node"
 | 
				
			||||||
               v-if="!teaIsPlus">"{{node.name}}"节点详情</menu-item>
 | 
					               v-if="!teaIsPlus">"{{node.name}}"节点详情</menu-item>
 | 
				
			||||||
    <menu-item :href="'/clusters/cluster/node/boards?clusterId=' + clusterId + '&nodeId=' + node.id" code="board" v-if="teaIsPlus">"{{node.name}}" 节点看板</menu-item>
 | 
					    <menu-item :href="'/clusters/cluster/node/boards?clusterId=' + clusterId + '&nodeId=' + node.id" code="board" v-if="teaIsPlus">"{{node.name}}" 节点看板</menu-item>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,34 +74,30 @@ Tea.context(function () {
 | 
				
			|||||||
	this.reloadHourlyTrafficChart = function () {
 | 
						this.reloadHourlyTrafficChart = function () {
 | 
				
			||||||
		let stats = this.hourlyStats
 | 
							let stats = this.hourlyStats
 | 
				
			||||||
		this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) {
 | 
							this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + " " + stats[index].hour  + "时<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 () {
 | 
						this.reloadDailyTrafficChart = function () {
 | 
				
			||||||
		let stats = this.dailyStats
 | 
							let stats = this.dailyStats
 | 
				
			||||||
		this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) {
 | 
							this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + "<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 ""
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -169,10 +165,23 @@ Tea.context(function () {
 | 
				
			|||||||
					areaStyle: {
 | 
										areaStyle: {
 | 
				
			||||||
						color: "#61A0A8"
 | 
											color: "#61A0A8"
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击流量",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.attackBytes / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
			legend: {
 | 
								legend: {
 | 
				
			||||||
				data: ['流量', '缓存流量']
 | 
									data: ["流量", "缓存流量", "攻击流量"]
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			animation: true
 | 
								animation: true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -201,34 +210,30 @@ Tea.context(function () {
 | 
				
			|||||||
	this.reloadHourlyRequestsChart = function () {
 | 
						this.reloadHourlyRequestsChart = function () {
 | 
				
			||||||
		let stats = this.hourlyStats
 | 
							let stats = this.hourlyStats
 | 
				
			||||||
		this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) {
 | 
							this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + " " + stats[index].hour + "时<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 () {
 | 
						this.reloadDailyRequestsChart = function () {
 | 
				
			||||||
		let stats = this.dailyStats
 | 
							let stats = this.dailyStats
 | 
				
			||||||
		this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) {
 | 
							this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + "<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 ""
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -299,10 +304,23 @@ Tea.context(function () {
 | 
				
			|||||||
					areaStyle: {
 | 
										areaStyle: {
 | 
				
			||||||
						color: "#61A0A8"
 | 
											color: "#61A0A8"
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击请求数",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.countAttackRequests / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
			legend: {
 | 
								legend: {
 | 
				
			||||||
				data: ['请求数', '缓存请求数']
 | 
									data: ["请求数", "缓存请求数", "攻击请求数"]
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			animation: true
 | 
								animation: true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -328,7 +346,10 @@ Tea.context(function () {
 | 
				
			|||||||
			value: function (v) {
 | 
								value: function (v) {
 | 
				
			||||||
				return v.countRequests / axis.divider;
 | 
									return v.countRequests / axis.divider;
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			axis: axis
 | 
								axis: axis,
 | 
				
			||||||
 | 
								click: function (args, stats) {
 | 
				
			||||||
 | 
									window.location = "/servers/server?serverId=" + stats[args.dataIndex].serverId
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -450,6 +471,9 @@ Tea.context(function () {
 | 
				
			|||||||
				return stats[args.dataIndex].time + "<br/>使用:" + teaweb.formatBytes(v.used) + "<br/>总量:" + teaweb.formatBytes(v.total) + "<br/>比例:" + (Math.ceil(v.used * 100 / v.total * 100) / 100) + "%"
 | 
									return stats[args.dataIndex].time + "<br/>使用:" + teaweb.formatBytes(v.used) + "<br/>总量:" + teaweb.formatBytes(v.total) + "<br/>比例:" + (Math.ceil(v.used * 100 / v.total * 100) / 100) + "%"
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			value: function (v) {
 | 
								value: function (v) {
 | 
				
			||||||
 | 
									if (v.value.dirs.length ==0) {
 | 
				
			||||||
 | 
										return 0
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				v = v.value.dirs[0]
 | 
									v = v.value.dirs[0]
 | 
				
			||||||
				return (v.used * 100 / v.total);
 | 
									return (v.used * 100 / v.total);
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,10 @@
 | 
				
			|||||||
{$template "/echarts"}
 | 
					{$template "/echarts"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- 升级提醒 -->
 | 
					<!-- 升级提醒 -->
 | 
				
			||||||
<div class="ui message error" v-if="nodeUpgradeInfo.count > 0"><a href="/clusters">升级提醒:有 {{nodeUpgradeInfo.count}} 个边缘节点需要升级到 v{{nodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a></div>
 | 
					<div class="ui message error" v-if="nodeUpgradeInfo.count > 0">
 | 
				
			||||||
 | 
					    <a href="/clusters">
 | 
				
			||||||
 | 
					    升级提醒:有 {{nodeUpgradeInfo.count}} 个边缘节点需要升级到 v{{nodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
<div class="ui message error" v-if="monitorNodeUpgradeInfo.count > 0 && teaIsPlus"><a href="/settings/monitorNodes">升级提醒:有 {{monitorNodeUpgradeInfo.count}} 个监控节点需要升级到 v{{monitorNodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a></div>
 | 
					<div class="ui message error" v-if="monitorNodeUpgradeInfo.count > 0 && teaIsPlus"><a href="/settings/monitorNodes">升级提醒:有 {{monitorNodeUpgradeInfo.count}} 个监控节点需要升级到 v{{monitorNodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a></div>
 | 
				
			||||||
<div class="ui message error" v-if="userNodeUpgradeInfo.count > 0 && teaIsPlus"><a href="/settings/userNodes">升级提醒:有 {{userNodeUpgradeInfo.count}} 个用户节点需要升级到 v{{userNodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a></div>
 | 
					<div class="ui message error" v-if="userNodeUpgradeInfo.count > 0 && teaIsPlus"><a href="/settings/userNodes">升级提醒:有 {{userNodeUpgradeInfo.count}} 个用户节点需要升级到 v{{userNodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a></div>
 | 
				
			||||||
<div class="ui message error" v-if="apiNodeUpgradeInfo.count > 0"><a href="/api">升级提醒:有 {{apiNodeUpgradeInfo.count}} 个API节点需要升级到 v{{apiNodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a></div>
 | 
					<div class="ui message error" v-if="apiNodeUpgradeInfo.count > 0"><a href="/api">升级提醒:有 {{apiNodeUpgradeInfo.count}} 个API节点需要升级到 v{{apiNodeUpgradeInfo.version}} 版本</a><a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a></div>
 | 
				
			||||||
@@ -12,7 +15,7 @@
 | 
				
			|||||||
{$template "menu"}
 | 
					{$template "menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- 统计图表 -->
 | 
					<!-- 统计图表 -->
 | 
				
			||||||
<div class="ui three columns grid">
 | 
					<div class="ui four columns grid">
 | 
				
			||||||
    <div class="ui column">
 | 
					    <div class="ui column">
 | 
				
			||||||
        <h4>集群<link-icon href="/clusters" v-if="dashboard.canGoNodes"></link-icon></h4>
 | 
					        <h4>集群<link-icon href="/clusters" v-if="dashboard.canGoNodes"></link-icon></h4>
 | 
				
			||||||
        <div class="value"><span>{{dashboard.countNodeClusters}}</span>个</div>
 | 
					        <div class="value"><span>{{dashboard.countNodeClusters}}</span>个</div>
 | 
				
			||||||
@@ -23,7 +26,7 @@
 | 
				
			|||||||
        <div class="value"><span>{{dashboard.countNodes}}</span>个</div>
 | 
					        <div class="value"><span>{{dashboard.countNodes}}</span>个</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="ui column no-border">
 | 
					    <div class="ui column">
 | 
				
			||||||
        <h4>API节点<link-icon href="/api" v-if="dashboard.canGoSettings"></link-icon></h4>
 | 
					        <h4>API节点<link-icon href="/api" v-if="dashboard.canGoSettings"></link-icon></h4>
 | 
				
			||||||
        <div class="value"><span>{{dashboard.countAPINodes}}</span>个</div>
 | 
					        <div class="value"><span>{{dashboard.countAPINodes}}</span>个</div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@@ -46,6 +49,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<div class="ui divider"></div>
 | 
					<div class="ui divider"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- 流量 -->
 | 
				
			||||||
<div class="ui menu tabular">
 | 
					<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 == 'hourly'}" @click.prevent="selectTrafficTab('hourly')">24小时流量趋势</a>
 | 
				
			||||||
    <a href="" class="item" :class="{active: trafficTab == 'daily'}" @click.prevent="selectTrafficTab('daily')">15天流量趋势</a>
 | 
					    <a href="" class="item" :class="{active: trafficTab == 'daily'}" @click.prevent="selectTrafficTab('daily')">15天流量趋势</a>
 | 
				
			||||||
@@ -55,4 +59,27 @@
 | 
				
			|||||||
<div class="chart-box" id="hourly-traffic-chart-box" v-show="trafficTab == 'hourly'"></div>
 | 
					<div class="chart-box" id="hourly-traffic-chart-box" v-show="trafficTab == 'hourly'"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- 按日统计 -->
 | 
					<!-- 按日统计 -->
 | 
				
			||||||
<div class="chart-box" id="daily-traffic-chart-box" v-show="trafficTab == 'daily'"></div>
 | 
					<div class="chart-box" id="daily-traffic-chart-box" 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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- 域名排行 -->
 | 
				
			||||||
 | 
					<h4>域名访问排行 <span>(24小时)</span></h4>
 | 
				
			||||||
 | 
					<div class="chart-box" id="top-domains-chart"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="ui divider"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- 节点排行 -->
 | 
				
			||||||
 | 
					<h4>节点访问排行 <span>(24小时)</span></h4>
 | 
				
			||||||
 | 
					<div class="chart-box" id="top-nodes-chart"></div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,9 @@ Tea.context(function () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	this.$delay(function () {
 | 
						this.$delay(function () {
 | 
				
			||||||
		this.reloadHourlyTrafficChart()
 | 
							this.reloadHourlyTrafficChart()
 | 
				
			||||||
 | 
							this.reloadHourlyRequestsChart()
 | 
				
			||||||
 | 
							this.reloadTopDomainsChart()
 | 
				
			||||||
 | 
							this.reloadTopNodesChart()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let that = this
 | 
							let that = this
 | 
				
			||||||
		window.addEventListener("resize", function () {
 | 
							window.addEventListener("resize", function () {
 | 
				
			||||||
@@ -28,86 +31,63 @@ Tea.context(function () {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.reloadHourlyTrafficChart = function () {
 | 
				
			||||||
 | 
							let stats = this.hourlyTrafficStats
 | 
				
			||||||
 | 
							this.reloadTrafficChart("hourly-traffic-chart-box", 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  + "时<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.reloadDailyTrafficChart = function () {
 | 
				
			||||||
 | 
							let stats = this.dailyTrafficStats
 | 
				
			||||||
 | 
							this.reloadTrafficChart("daily-traffic-chart-box", 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 + "<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.resizeHourlyTrafficChart = function () {
 | 
						this.resizeHourlyTrafficChart = function () {
 | 
				
			||||||
		let chartBox = document.getElementById("hourly-traffic-chart-box")
 | 
							let chartBox = document.getElementById("hourly-traffic-chart-box")
 | 
				
			||||||
		let chart = echarts.init(chartBox)
 | 
							let chart = echarts.init(chartBox)
 | 
				
			||||||
		chart.resize()
 | 
							chart.resize()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.reloadHourlyTrafficChart = function () {
 | 
					 | 
				
			||||||
		let axis = teaweb.bytesAxis(this.hourlyTrafficStats, function (v) {
 | 
					 | 
				
			||||||
			return v.bytes
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		let chartBox = document.getElementById("hourly-traffic-chart-box")
 | 
					 | 
				
			||||||
		let chart = echarts.init(chartBox)
 | 
					 | 
				
			||||||
		let that = this
 | 
					 | 
				
			||||||
		let option = {
 | 
					 | 
				
			||||||
			xAxis: {
 | 
					 | 
				
			||||||
				data: this.hourlyTrafficStats.map(function (v) {
 | 
					 | 
				
			||||||
					return v.hour;
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			yAxis: {
 | 
					 | 
				
			||||||
				axisLabel: {
 | 
					 | 
				
			||||||
					formatter: function (v) {
 | 
					 | 
				
			||||||
						return v + axis.unit
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			tooltip: {
 | 
					 | 
				
			||||||
				show: true,
 | 
					 | 
				
			||||||
				trigger: "item",
 | 
					 | 
				
			||||||
				formatter: function (args) {
 | 
					 | 
				
			||||||
					let index = args.dataIndex
 | 
					 | 
				
			||||||
					return that.hourlyTrafficStats[index].hour + "时:" + teaweb.formatBytes(that.hourlyTrafficStats[index].bytes)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			grid: {
 | 
					 | 
				
			||||||
				left: 40,
 | 
					 | 
				
			||||||
				top: 10,
 | 
					 | 
				
			||||||
				right: 20
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			series: [
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					name: "流量",
 | 
					 | 
				
			||||||
					type: "line",
 | 
					 | 
				
			||||||
					data: this.hourlyTrafficStats.map(function (v) {
 | 
					 | 
				
			||||||
						return v.bytes / axis.divider;
 | 
					 | 
				
			||||||
					}),
 | 
					 | 
				
			||||||
					itemStyle: {
 | 
					 | 
				
			||||||
						color: "#9DD3E8"
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
					lineStyle: {
 | 
					 | 
				
			||||||
						color: "#9DD3E8"
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
					areaStyle: {
 | 
					 | 
				
			||||||
						color: "#9DD3E8"
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			],
 | 
					 | 
				
			||||||
			animation: false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		chart.setOption(option)
 | 
					 | 
				
			||||||
		chart.resize()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	this.resizeDailyTrafficChart = function () {
 | 
						this.resizeDailyTrafficChart = function () {
 | 
				
			||||||
		let chartBox = document.getElementById("daily-traffic-chart-box")
 | 
							let chartBox = document.getElementById("daily-traffic-chart-box")
 | 
				
			||||||
		let chart = echarts.init(chartBox)
 | 
							let chart = echarts.init(chartBox)
 | 
				
			||||||
		chart.resize()
 | 
							chart.resize()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.reloadDailyTrafficChart = function () {
 | 
					
 | 
				
			||||||
		let axis = teaweb.bytesAxis(this.dailyTrafficStats, function (v) {
 | 
						this.reloadTrafficChart = function (chartId, stats, tooltipFunc) {
 | 
				
			||||||
 | 
							let axis = teaweb.bytesAxis(stats, function (v) {
 | 
				
			||||||
			return v.bytes
 | 
								return v.bytes
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		let chartBox = document.getElementById("daily-traffic-chart-box")
 | 
							let chartBox = document.getElementById(chartId)
 | 
				
			||||||
		let chart = echarts.init(chartBox)
 | 
							let chart = echarts.init(chartBox)
 | 
				
			||||||
		let that = this
 | 
							let that = this
 | 
				
			||||||
		let option = {
 | 
							let option = {
 | 
				
			||||||
			xAxis: {
 | 
								xAxis: {
 | 
				
			||||||
				data: this.dailyTrafficStats.map(function (v) {
 | 
									data: stats.map(function (v) {
 | 
				
			||||||
					return v.day;
 | 
										if (v.hour != null) {
 | 
				
			||||||
 | 
											return v.hour
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										return v.day
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			yAxis: {
 | 
								yAxis: {
 | 
				
			||||||
@@ -120,21 +100,19 @@ Tea.context(function () {
 | 
				
			|||||||
			tooltip: {
 | 
								tooltip: {
 | 
				
			||||||
				show: true,
 | 
									show: true,
 | 
				
			||||||
				trigger: "item",
 | 
									trigger: "item",
 | 
				
			||||||
				formatter: function (args) {
 | 
									formatter: tooltipFunc
 | 
				
			||||||
					let index = args.dataIndex
 | 
					 | 
				
			||||||
					return that.dailyTrafficStats[index].day + ":" + teaweb.formatBytes(that.dailyTrafficStats[index].bytes)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			grid: {
 | 
								grid: {
 | 
				
			||||||
				left: 40,
 | 
									left: 50,
 | 
				
			||||||
				top: 10,
 | 
									top: 40,
 | 
				
			||||||
				right: 20
 | 
									right: 20,
 | 
				
			||||||
 | 
									bottom: 20
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			series: [
 | 
								series: [
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					name: "流量",
 | 
										name: "总流量",
 | 
				
			||||||
					type: "line",
 | 
										type: "line",
 | 
				
			||||||
					data: this.dailyTrafficStats.map(function (v) {
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
						return v.bytes / axis.divider;
 | 
											return v.bytes / axis.divider;
 | 
				
			||||||
					}),
 | 
										}),
 | 
				
			||||||
					itemStyle: {
 | 
										itemStyle: {
 | 
				
			||||||
@@ -146,14 +124,234 @@ Tea.context(function () {
 | 
				
			|||||||
					areaStyle: {
 | 
										areaStyle: {
 | 
				
			||||||
						color: "#9DD3E8"
 | 
											color: "#9DD3E8"
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "缓存流量",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.cachedBytes / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#61A0A8"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#61A0A8"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击流量",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.attackBytes / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
 | 
								legend: {
 | 
				
			||||||
 | 
									data: ["总流量", "缓存流量", "攻击流量"]
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
			animation: false
 | 
								animation: false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		chart.setOption(option)
 | 
							chart.setOption(option)
 | 
				
			||||||
		chart.resize()
 | 
							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.hourlyTrafficStats
 | 
				
			||||||
 | 
							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 + "时<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.reloadDailyRequestsChart = function () {
 | 
				
			||||||
 | 
							let stats = this.dailyTrafficStats
 | 
				
			||||||
 | 
							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 + "<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + 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 = 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"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击请求数",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.countAttackRequests / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								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 + "<br/>请求数:" + " " + teaweb.formatNumber(stats[args.dataIndex].countRequests) + "<br/>流量:" + 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 + "<br/>请求数:" + " " + teaweb.formatNumber(stats[args.dataIndex].countRequests) + "<br/>流量:" + teaweb.formatBytes(stats[args.dataIndex].bytes)
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								value: function (v) {
 | 
				
			||||||
 | 
									return v.countRequests / axis.divider;
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								axis: axis,
 | 
				
			||||||
 | 
								click: function (args, stats) {
 | 
				
			||||||
 | 
									let index = args.dataIndex
 | 
				
			||||||
 | 
									window.location = "/servers/server?serverId=" + stats[index].serverId
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * 升级提醒
 | 
						 * 升级提醒
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,12 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/echarts"}
 | 
					{$template "/echarts"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<first-menu>
 | 
				
			||||||
 | 
					    <menu-item href="/servers">服务列表</menu-item>
 | 
				
			||||||
 | 
					    <span class="item disabled">|</span>
 | 
				
			||||||
 | 
					    <menu-item :href="'/servers/server?serverId=' + server.id" active="true">"{{server.name}}"看板</menu-item>
 | 
				
			||||||
 | 
					</first-menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="ui menu tabular">
 | 
					<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 == 'hourly'}" @click.prevent="selectTrafficTab('hourly')">24小时流量趋势</a>
 | 
				
			||||||
    <a href="" class="item" :class="{active: trafficTab == 'daily'}" @click.prevent="selectTrafficTab('daily')">15天流量趋势</a>
 | 
					    <a href="" class="item" :class="{active: trafficTab == 'daily'}" @click.prevent="selectTrafficTab('daily')">15天流量趋势</a>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,34 +36,30 @@ Tea.context(function () {
 | 
				
			|||||||
	this.reloadHourlyTrafficChart = function () {
 | 
						this.reloadHourlyTrafficChart = function () {
 | 
				
			||||||
		let stats = this.hourlyStats
 | 
							let stats = this.hourlyStats
 | 
				
			||||||
		this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) {
 | 
							this.reloadTrafficChart("hourly-traffic-chart", "流量统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + " " + stats[index].hour  + "时<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 () {
 | 
						this.reloadDailyTrafficChart = function () {
 | 
				
			||||||
		let stats = this.dailyStats
 | 
							let stats = this.dailyStats
 | 
				
			||||||
		this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) {
 | 
							this.reloadTrafficChart("daily-traffic-chart", "流量统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " 流量: " + teaweb.formatBytes(stats[args.dataIndex].bytes)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + "<br/>总流量:" + teaweb.formatBytes(stats[index].bytes) + "<br/>缓存流量:" + teaweb.formatBytes(stats[index].cachedBytes) + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击流量:" + teaweb.formatBytes(stats[index].attackBytes) + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 ""
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -131,10 +127,23 @@ Tea.context(function () {
 | 
				
			|||||||
					areaStyle: {
 | 
										areaStyle: {
 | 
				
			||||||
						color: "#61A0A8"
 | 
											color: "#61A0A8"
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击流量",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.attackBytes / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
			legend: {
 | 
								legend: {
 | 
				
			||||||
				data: ['流量', '缓存流量']
 | 
									data: ["流量", "缓存流量", "攻击流量"]
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			animation: true
 | 
								animation: true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -163,34 +172,30 @@ Tea.context(function () {
 | 
				
			|||||||
	this.reloadHourlyRequestsChart = function () {
 | 
						this.reloadHourlyRequestsChart = function () {
 | 
				
			||||||
		let stats = this.hourlyStats
 | 
							let stats = this.hourlyStats
 | 
				
			||||||
		this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) {
 | 
							this.reloadRequestsChart("hourly-requests-chart", "请求数统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + " " + stats[index].hour + "时<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 () {
 | 
						this.reloadDailyRequestsChart = function () {
 | 
				
			||||||
		let stats = this.dailyStats
 | 
							let stats = this.dailyStats
 | 
				
			||||||
		this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) {
 | 
							this.reloadRequestsChart("daily-requests-chart", "请求数统计", stats, function (args) {
 | 
				
			||||||
			if (args.seriesIndex == 0) {
 | 
								let index = args.dataIndex
 | 
				
			||||||
				return stats[args.dataIndex].day + " 请求数: " + teaweb.formatNumber(stats[args.dataIndex].countRequests)
 | 
								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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args.seriesIndex == 1) {
 | 
					
 | 
				
			||||||
				let ratio = 0
 | 
								return stats[index].day + "<br/>总请求数:" + stats[index].countRequests + "<br/>缓存请求数:" + stats[index].countCachedRequests + "<br/>缓存命中率:" + cachedRatio + "%<br/>拦截攻击数:" + stats[index].countAttackRequests + "<br/>拦截比例:" + attackRatio + "%"
 | 
				
			||||||
				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 ""
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -261,10 +266,23 @@ Tea.context(function () {
 | 
				
			|||||||
					areaStyle: {
 | 
										areaStyle: {
 | 
				
			||||||
						color: "#61A0A8"
 | 
											color: "#61A0A8"
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										name: "攻击请求数",
 | 
				
			||||||
 | 
										type: "line",
 | 
				
			||||||
 | 
										data: stats.map(function (v) {
 | 
				
			||||||
 | 
											return v.countAttackRequests / axis.divider;
 | 
				
			||||||
 | 
										}),
 | 
				
			||||||
 | 
										itemStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										lineStyle: {
 | 
				
			||||||
 | 
											color: "#F39494"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			],
 | 
								],
 | 
				
			||||||
			legend: {
 | 
								legend: {
 | 
				
			||||||
				data: ['请求数', '缓存请求数']
 | 
									data: ["请求数", "缓存请求数", "攻击请求数"]
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			animation: true
 | 
								animation: true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user