mirror of
				https://github.com/TeaOSLab/EdgeAPI.git
				synced 2025-11-04 16:00:24 +08:00 
			
		
		
		
	带宽相关数据增加百分位
This commit is contained in:
		@@ -15,6 +15,7 @@ import (
 | 
				
			|||||||
	"github.com/iwind/TeaGo/types"
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
	timeutil "github.com/iwind/TeaGo/utils/time"
 | 
						timeutil "github.com/iwind/TeaGo/utils/time"
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -452,6 +453,75 @@ func (this *ServerBandwidthStatDAO) FindPercentileBetweenDays(tx *dbs.Tx, server
 | 
				
			|||||||
	return one.(*ServerBandwidthStat), nil
 | 
						return one.(*ServerBandwidthStat), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FindPercentileBetweenTimes 获取时间段内内百分位
 | 
				
			||||||
 | 
					// timeFrom 开始时间,格式 YYYYMMDDHHII
 | 
				
			||||||
 | 
					// timeTo 结束时间,格式 YYYYMMDDHHII
 | 
				
			||||||
 | 
					func (this *ServerBandwidthStatDAO) FindPercentileBetweenTimes(tx *dbs.Tx, serverId int64, timeFrom string, timeTo string, percentile int32) (result *ServerBandwidthStat, err error) {
 | 
				
			||||||
 | 
						var reg = regexp.MustCompile(`^\d{12}$`)
 | 
				
			||||||
 | 
						if !reg.MatchString(timeFrom) {
 | 
				
			||||||
 | 
							return nil, errors.New("invalid timeFrom '" + timeFrom + "'")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !reg.MatchString(timeTo) {
 | 
				
			||||||
 | 
							return nil, errors.New("invalid timeTo '" + timeTo + "'")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if timeFrom > timeTo {
 | 
				
			||||||
 | 
							timeFrom, timeTo = timeTo, timeFrom
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if percentile <= 0 {
 | 
				
			||||||
 | 
							percentile = 95
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 如果是100%以上,则快速返回
 | 
				
			||||||
 | 
						if percentile >= 100 {
 | 
				
			||||||
 | 
							one, err := this.Query(tx).
 | 
				
			||||||
 | 
								Table(this.partialTable(serverId)).
 | 
				
			||||||
 | 
								Attr("serverId", serverId).
 | 
				
			||||||
 | 
								Between("CONCAT(day, timeAt)", timeFrom, timeTo).
 | 
				
			||||||
 | 
								Desc("bytes").
 | 
				
			||||||
 | 
								Find()
 | 
				
			||||||
 | 
							if err != nil || one == nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return one.(*ServerBandwidthStat), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 总数量
 | 
				
			||||||
 | 
						total, err := this.Query(tx).
 | 
				
			||||||
 | 
							Table(this.partialTable(serverId)).
 | 
				
			||||||
 | 
							Attr("serverId", serverId).
 | 
				
			||||||
 | 
							Between("CONCAT(day, timeAt)", timeFrom, timeTo).
 | 
				
			||||||
 | 
							Count()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if total == 0 {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var offset int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if total > 1 {
 | 
				
			||||||
 | 
							offset = int64(math.Ceil(float64(total) * float64(100-percentile) / 100))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 查询 nth 位置
 | 
				
			||||||
 | 
						one, err := this.Query(tx).
 | 
				
			||||||
 | 
							Table(this.partialTable(serverId)).
 | 
				
			||||||
 | 
							Attr("serverId", serverId).
 | 
				
			||||||
 | 
							Between("CONCAT(day, timeAt)", timeFrom, timeTo).
 | 
				
			||||||
 | 
							Desc("bytes").
 | 
				
			||||||
 | 
							Offset(offset).
 | 
				
			||||||
 | 
							Find()
 | 
				
			||||||
 | 
						if err != nil || one == nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return one.(*ServerBandwidthStat), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Clean 清理过期数据
 | 
					// Clean 清理过期数据
 | 
				
			||||||
func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
 | 
					func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
 | 
				
			||||||
	var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
 | 
						var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,8 +10,10 @@ import (
 | 
				
			|||||||
	"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
						"github.com/iwind/TeaGo/dbs"
 | 
				
			||||||
	"github.com/iwind/TeaGo/types"
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
 | 
						timeutil "github.com/iwind/TeaGo/utils/time"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -186,14 +188,45 @@ func (this *ServerBandwidthStatService) FindHourlyServerBandwidthStats(ctx conte
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if req.Hours <= 0 {
 | 
				
			||||||
 | 
							req.Hours = 12
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var tx = this.NullTx()
 | 
						var tx = this.NullTx()
 | 
				
			||||||
	stats, err := models.SharedServerBandwidthStatDAO.FindHourlyBandwidthStats(tx, req.ServerId, req.Hours)
 | 
						stats, err := models.SharedServerBandwidthStatDAO.FindHourlyBandwidthStats(tx, req.ServerId, req.Hours)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// percentile
 | 
				
			||||||
 | 
						var percentile = systemconfigs.DefaultBandwidthPercentile
 | 
				
			||||||
 | 
						userUIConfig, _ := models.SharedSysSettingDAO.ReadUserUIConfig(tx)
 | 
				
			||||||
 | 
						if userUIConfig != nil && userUIConfig.TrafficStats.BandwidthPercentile > 0 {
 | 
				
			||||||
 | 
							percentile = userUIConfig.TrafficStats.BandwidthPercentile
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var timestamp = time.Now().Unix() - int64(req.Hours)*3600
 | 
				
			||||||
 | 
						var timeFrom = timeutil.FormatTime("YmdH00", timestamp)
 | 
				
			||||||
 | 
						var timeTo = timeutil.Format("YmdHi")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var pbNthStat *pb.FindHourlyServerBandwidthStatsResponse_Stat
 | 
				
			||||||
 | 
						percentileStat, err := models.SharedServerBandwidthStatDAO.FindPercentileBetweenTimes(tx, req.ServerId, timeFrom, timeTo, percentile)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if percentileStat != nil {
 | 
				
			||||||
 | 
							pbNthStat = &pb.FindHourlyServerBandwidthStatsResponse_Stat{
 | 
				
			||||||
 | 
								Day:   percentileStat.Day,
 | 
				
			||||||
 | 
								Hour:  types.Int32(percentileStat.TimeAt[:2]),
 | 
				
			||||||
 | 
								Bytes: int64(percentileStat.Bytes),
 | 
				
			||||||
 | 
								Bits:  int64(percentileStat.Bytes * 8),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &pb.FindHourlyServerBandwidthStatsResponse{
 | 
						return &pb.FindHourlyServerBandwidthStatsResponse{
 | 
				
			||||||
		Stats:      stats,
 | 
							Stats:      stats,
 | 
				
			||||||
 | 
							Percentile: percentile,
 | 
				
			||||||
 | 
							NthStat:    pbNthStat,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -205,13 +238,52 @@ func (this *ServerBandwidthStatService) FindDailyServerBandwidthStats(ctx contex
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var tx = this.NullTx()
 | 
						var tx = this.NullTx()
 | 
				
			||||||
	stats, err := models.SharedServerBandwidthStatDAO.FindDailyBandwidthStats(tx, req.ServerId, req.Days)
 | 
					
 | 
				
			||||||
 | 
						if req.Days <= 0 {
 | 
				
			||||||
 | 
							req.Days = 30
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var timestamp = time.Now().Unix() - int64(req.Days)*86400
 | 
				
			||||||
 | 
						var dayFrom = timeutil.FormatTime("Ymd", timestamp)
 | 
				
			||||||
 | 
						var dayTo = timeutil.Format("Ymd")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stats, err := models.SharedServerBandwidthStatDAO.FindBandwidthStatsBetweenDays(tx, req.ServerId, dayFrom, dayTo)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						var pbStats = []*pb.FindDailyServerBandwidthStatsResponse_Stat{}
 | 
				
			||||||
 | 
						for _, stat := range stats {
 | 
				
			||||||
 | 
							pbStats = append(pbStats, &pb.FindDailyServerBandwidthStatsResponse_Stat{
 | 
				
			||||||
 | 
								Day:   stat.Day,
 | 
				
			||||||
 | 
								Bytes: stat.Bytes,
 | 
				
			||||||
 | 
								Bits:  stat.Bytes * 8,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// percentile
 | 
				
			||||||
 | 
						var percentile = systemconfigs.DefaultBandwidthPercentile
 | 
				
			||||||
 | 
						userUIConfig, _ := models.SharedSysSettingDAO.ReadUserUIConfig(tx)
 | 
				
			||||||
 | 
						if userUIConfig != nil && userUIConfig.TrafficStats.BandwidthPercentile > 0 {
 | 
				
			||||||
 | 
							percentile = userUIConfig.TrafficStats.BandwidthPercentile
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var pbNthStat = &pb.FindDailyServerBandwidthStatsResponse_Stat{}
 | 
				
			||||||
 | 
						percentileStat, err := models.SharedServerBandwidthStatDAO.FindPercentileBetweenDays(tx, req.ServerId, dayFrom, dayTo, percentile)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if percentileStat != nil {
 | 
				
			||||||
 | 
							pbNthStat = &pb.FindDailyServerBandwidthStatsResponse_Stat{
 | 
				
			||||||
 | 
								Day:   percentileStat.Day,
 | 
				
			||||||
 | 
								Bytes: int64(percentileStat.Bytes),
 | 
				
			||||||
 | 
								Bits:  int64(percentileStat.Bytes * 8),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &pb.FindDailyServerBandwidthStatsResponse{
 | 
						return &pb.FindDailyServerBandwidthStatsResponse{
 | 
				
			||||||
		Stats: stats,
 | 
							Stats:      pbStats,
 | 
				
			||||||
 | 
							Percentile: percentile,
 | 
				
			||||||
 | 
							NthStat:    pbNthStat,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ import (
 | 
				
			|||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
				
			||||||
	"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"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
 | 
				
			||||||
	timeutil "github.com/iwind/TeaGo/utils/time"
 | 
						timeutil "github.com/iwind/TeaGo/utils/time"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -465,7 +466,16 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context,
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		var bandwidthMinutes = utils.RangeMinutes(time.Now(), 12, 5)
 | 
							var bandwidthMinutes = utils.RangeMinutes(time.Now(), 12, 5)
 | 
				
			||||||
		var bandwidthStatMap = map[string]*pb.ServerBandwidthStat{}
 | 
							var bandwidthStatMap = map[string]*pb.ServerBandwidthStat{}
 | 
				
			||||||
 | 
							var timeFrom = ""
 | 
				
			||||||
 | 
							var timeTo = ""
 | 
				
			||||||
		for _, r := range utils.GroupMinuteRanges(bandwidthMinutes) {
 | 
							for _, r := range utils.GroupMinuteRanges(bandwidthMinutes) {
 | 
				
			||||||
 | 
								if len(timeFrom) == 0 || timeFrom > r.Day+r.MinuteFrom {
 | 
				
			||||||
 | 
									timeFrom = r.Day + r.MinuteFrom
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if len(timeTo) == 0 || timeTo < r.Day+r.MinuteTo {
 | 
				
			||||||
 | 
									timeTo = r.Day + r.MinuteTo
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bandwidthStats, err := models.SharedServerBandwidthStatDAO.FindServerStats(tx, req.ServerId, r.Day, r.MinuteFrom, r.MinuteTo)
 | 
								bandwidthStats, err := models.SharedServerBandwidthStatDAO.FindServerStats(tx, req.ServerId, r.Day, r.MinuteFrom, r.MinuteTo)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
@@ -499,6 +509,29 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context,
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		result.MinutelyBandwidthStats = pbBandwidthStats
 | 
							result.MinutelyBandwidthStats = pbBandwidthStats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// percentile
 | 
				
			||||||
 | 
							if len(timeFrom) > 0 && len(timeTo) > 0 {
 | 
				
			||||||
 | 
								var percentile = systemconfigs.DefaultBandwidthPercentile
 | 
				
			||||||
 | 
								userUIConfig, _ := models.SharedSysSettingDAO.ReadUserUIConfig(tx)
 | 
				
			||||||
 | 
								if userUIConfig != nil && userUIConfig.TrafficStats.BandwidthPercentile > 0 {
 | 
				
			||||||
 | 
									percentile = userUIConfig.TrafficStats.BandwidthPercentile
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								result.BandwidthPercentile = percentile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								percentileStat, err := models.SharedServerBandwidthStatDAO.FindPercentileBetweenTimes(tx, req.ServerId, timeFrom, timeTo, percentile)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if percentileStat != nil {
 | 
				
			||||||
 | 
									result.MinutelyNthBandwidthStat = &pb.ServerBandwidthStat{
 | 
				
			||||||
 | 
										Day:    percentileStat.Day,
 | 
				
			||||||
 | 
										TimeAt: percentileStat.TimeAt,
 | 
				
			||||||
 | 
										Bytes:  int64(percentileStat.Bytes),
 | 
				
			||||||
 | 
										Bits:   int64(percentileStat.Bytes * 8),
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 按日流量统计
 | 
						// 按日流量统计
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user