diff --git a/internal/db/models/stats/traffic_daily_stat_dao.go b/internal/db/models/stats/traffic_daily_stat_dao.go index e98455a7..33666bcf 100644 --- a/internal/db/models/stats/traffic_daily_stat_dao.go +++ b/internal/db/models/stats/traffic_daily_stat_dao.go @@ -85,6 +85,22 @@ func (this *TrafficDailyStatDAO) IncreaseDailyStat(tx *dbs.Tx, day string, bytes return nil } +// IncreaseIPs 增加独立IP统计数据 +func (this *TrafficDailyStatDAO) IncreaseIPs(tx *dbs.Tx, day string, countIPs int64) error { + if len(day) != 8 { + return errors.New("invalid day '" + day + "'") + } + + return this.Query(tx). + Param("countIPs", countIPs). + InsertOrUpdateQuickly(maps.Map{ + "day": day, + "countIPs": countIPs, + }, maps.Map{ + "countIPs": dbs.SQL("countIPs+:countIPs"), + }) +} + // FindDailyStats 获取日期之间统计 func (this *TrafficDailyStatDAO) FindDailyStats(tx *dbs.Tx, dayFrom string, dayTo string) (result []*TrafficDailyStat, err error) { ones, err := this.Query(tx). diff --git a/internal/db/models/stats/traffic_daily_stat_dao_test.go b/internal/db/models/stats/traffic_daily_stat_dao_test.go index bdab4cfb..34f0c46a 100644 --- a/internal/db/models/stats/traffic_daily_stat_dao_test.go +++ b/internal/db/models/stats/traffic_daily_stat_dao_test.go @@ -11,10 +11,20 @@ import ( func TestTrafficDailyStatDAO_IncreaseDayBytes(t *testing.T) { dbs.NotifyReady() - now := time.Now() + var now = time.Now() err := SharedTrafficDailyStatDAO.IncreaseDailyStat(nil, timeutil.Format("Ymd"), 1, 1, 1, 1, 1, 1) if err != nil { t.Fatal(err) } t.Log("ok", time.Since(now).Seconds()*1000, "ms") } + +func TestTrafficDailyStatDAO_IncreaseIPs(t *testing.T) { + dbs.NotifyReady() + + var tx *dbs.Tx + err := SharedTrafficDailyStatDAO.IncreaseIPs(tx, timeutil.Format("Ymd"), 123) + if err != nil { + t.Fatal(err) + } +} diff --git a/internal/db/models/stats/traffic_daily_stat_model.go b/internal/db/models/stats/traffic_daily_stat_model.go index df56c4d8..9baef99b 100644 --- a/internal/db/models/stats/traffic_daily_stat_model.go +++ b/internal/db/models/stats/traffic_daily_stat_model.go @@ -1,5 +1,19 @@ package stats +import "github.com/iwind/TeaGo/dbs" + +const ( + TrafficDailyStatField_Id dbs.FieldName = "id" // ID + TrafficDailyStatField_Day dbs.FieldName = "day" // YYYYMMDD + TrafficDailyStatField_CachedBytes dbs.FieldName = "cachedBytes" // 缓存流量 + TrafficDailyStatField_Bytes dbs.FieldName = "bytes" // 流量字节 + TrafficDailyStatField_CountRequests dbs.FieldName = "countRequests" // 请求数 + TrafficDailyStatField_CountCachedRequests dbs.FieldName = "countCachedRequests" // 缓存请求数 + TrafficDailyStatField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 攻击量 + TrafficDailyStatField_AttackBytes dbs.FieldName = "attackBytes" // 攻击流量 + TrafficDailyStatField_CountIPs dbs.FieldName = "countIPs" // 独立IP数 +) + // TrafficDailyStat 总的流量统计(按天) type TrafficDailyStat struct { Id uint64 `field:"id"` // ID @@ -10,17 +24,19 @@ type TrafficDailyStat struct { CountCachedRequests uint64 `field:"countCachedRequests"` // 缓存请求数 CountAttackRequests uint64 `field:"countAttackRequests"` // 攻击量 AttackBytes uint64 `field:"attackBytes"` // 攻击流量 + CountIPs uint64 `field:"countIPs"` // 独立IP数 } type TrafficDailyStatOperator struct { - Id interface{} // ID - Day interface{} // YYYYMMDD - CachedBytes interface{} // 缓存流量 - Bytes interface{} // 流量字节 - CountRequests interface{} // 请求数 - CountCachedRequests interface{} // 缓存请求数 - CountAttackRequests interface{} // 攻击量 - AttackBytes interface{} // 攻击流量 + Id any // ID + Day any // YYYYMMDD + CachedBytes any // 缓存流量 + Bytes any // 流量字节 + CountRequests any // 请求数 + CountCachedRequests any // 缓存请求数 + CountAttackRequests any // 攻击量 + AttackBytes any // 攻击流量 + CountIPs any // 独立IP数 } func NewTrafficDailyStatOperator() *TrafficDailyStatOperator { diff --git a/internal/rpc/services/service_admin.go b/internal/rpc/services/service_admin.go index 205b4ff0..f93bc852 100644 --- a/internal/rpc/services/service_admin.go +++ b/internal/rpc/services/service_admin.go @@ -555,13 +555,15 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com result.CountNodeClusters = countClusters // 节点数 - this.BeginTag(ctx, "SharedNodeDAO.CountAllEnabledNodes") - countNodes, err := models.SharedNodeDAO.CountAllEnabledNodes(tx) - this.EndTag(ctx, "SharedNodeDAO.CountAllEnabledNodes") - if err != nil { - return nil, err + { + this.BeginTag(ctx, "SharedNodeDAO.CountAllEnabledNodes") + countNodes, err := models.SharedNodeDAO.CountAllEnabledNodes(tx) + this.EndTag(ctx, "SharedNodeDAO.CountAllEnabledNodes") + if err != nil { + return nil, err + } + result.CountNodes = countNodes } - result.CountNodes = countNodes // 离线节点 this.BeginTag(ctx, "SharedNodeDAO.CountAllEnabledOfflineNodes") @@ -572,7 +574,7 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com } result.CountOfflineNodes = countOfflineNodes - // 服务数 + // 网站数 this.BeginTag(ctx, "SharedServerDAO.CountAllEnabledServers") countServers, err := models.SharedServerDAO.CountAllEnabledServers(tx) this.EndTag(ctx, "SharedServerDAO.CountAllEnabledServers") @@ -660,6 +662,7 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com CountCachedRequests: int64(stat.CountCachedRequests), CountAttackRequests: int64(stat.CountAttackRequests), AttackBytes: int64(stat.AttackBytes), + CountIPs: int64(stat.CountIPs), }) } @@ -732,9 +735,6 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com topDomainStats = topDomainStatsCache.([]*stats.ServerDomainHourlyStat) } this.EndTag(ctx, "SharedServerDomainHourlyStatDAO.FindTopDomainStats") - if err != nil { - return nil, err - } for _, stat := range topDomainStats { result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeAdminDashboardResponse_DomainStat{ ServerId: int64(stat.ServerId), @@ -752,9 +752,6 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com pbCharts = pbChartsCache.([]*pb.MetricDataChart) } this.EndTag(ctx, "findMetricDataCharts") - if err != nil { - return nil, err - } result.MetricDataCharts = pbCharts return result, nil diff --git a/internal/rpc/services/service_server_bandwidth_stat.go b/internal/rpc/services/service_server_bandwidth_stat.go index 0e413544..53bd1ec1 100644 --- a/internal/rpc/services/service_server_bandwidth_stat.go +++ b/internal/rpc/services/service_server_bandwidth_stat.go @@ -8,6 +8,7 @@ import ( "errors" teaconst "github.com/TeaOSLab/EdgeAPI/internal/const" "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/db/models/stats" "github.com/TeaOSLab/EdgeAPI/internal/events" "github.com/TeaOSLab/EdgeAPI/internal/goman" "github.com/TeaOSLab/EdgeAPI/internal/remotelogs" @@ -115,6 +116,9 @@ func init() { // 分时统计 err = models.SharedUserPlanBandwidthStatDAO.UpdateUserPlanBandwidth(tx, stat.UserId, stat.UserPlanId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests, stat.CountWebsocketConnections) + if err != nil { + remotelogs.Error("SharedUserPlanBandwidthStatDAO", "UpdateUserPlanBandwidth: " + err.Error()) + } } } @@ -122,7 +126,15 @@ func init() { if stat.UserId > 0 { err = models.SharedUserBandwidthStatDAO.UpdateUserBandwidth(tx, stat.UserId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests) if err != nil { - remotelogs.Error("SharedUserBandwidthStatDAO", "dump bandwidth stats failed: "+err.Error()) + remotelogs.Error("SharedUserBandwidthStatDAO", "UpdateUserBandwidth: "+err.Error()) + } + } + + // 更新整体的独立IP统计 + if stat.CountIPs > 0 { + err = stats.SharedTrafficDailyStatDAO.IncreaseIPs(tx, stat.Day, stat.CountIPs) + if err != nil { + remotelogs.Error("SharedTrafficDailyStatDAO", "IncreaseIPs: "+err.Error()) } } } diff --git a/internal/setup/sql.json b/internal/setup/sql.json index ad28e036..187ad537 100644 --- a/internal/setup/sql.json +++ b/internal/setup/sql.json @@ -243805,7 +243805,7 @@ "name": "edgeTrafficDailyStats", "engine": "InnoDB", "charset": "utf8mb4_general_ci", - "definition": "CREATE TABLE `edgeTrafficDailyStats` (\n `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `day` varchar(8) DEFAULT NULL COMMENT 'YYYYMMDD',\n `cachedBytes` bigint(20) unsigned DEFAULT '0' COMMENT '缓存流量',\n `bytes` bigint(20) unsigned DEFAULT NULL COMMENT '流量字节',\n `countRequests` bigint(20) unsigned DEFAULT '0' COMMENT '请求数',\n `countCachedRequests` bigint(20) unsigned DEFAULT '0' COMMENT '缓存请求数',\n `countAttackRequests` bigint(20) unsigned DEFAULT '0' COMMENT '攻击量',\n `attackBytes` bigint(20) unsigned DEFAULT '0' COMMENT '攻击流量',\n PRIMARY KEY (`id`),\n UNIQUE KEY `day` (`day`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='总的流量统计(按天)'", + "definition": "CREATE TABLE `edgeTrafficDailyStats` (\n `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `day` varchar(8) DEFAULT NULL COMMENT 'YYYYMMDD',\n `cachedBytes` bigint(20) unsigned DEFAULT '0' COMMENT '缓存流量',\n `bytes` bigint(20) unsigned DEFAULT '0' COMMENT '流量字节',\n `countRequests` bigint(20) unsigned DEFAULT '0' COMMENT '请求数',\n `countCachedRequests` bigint(20) unsigned DEFAULT '0' COMMENT '缓存请求数',\n `countAttackRequests` bigint(20) unsigned DEFAULT '0' COMMENT '攻击量',\n `attackBytes` bigint(20) unsigned DEFAULT '0' COMMENT '攻击流量',\n `countIPs` bigint(20) unsigned DEFAULT '0' COMMENT '独立IP数',\n PRIMARY KEY (`id`),\n UNIQUE KEY `day` (`day`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='总的流量统计(按天)'", "fields": [ { "name": "id", @@ -243821,7 +243821,7 @@ }, { "name": "bytes", - "definition": "bigint(20) unsigned COMMENT '流量字节'" + "definition": "bigint(20) unsigned DEFAULT '0' COMMENT '流量字节'" }, { "name": "countRequests", @@ -243838,6 +243838,10 @@ { "name": "attackBytes", "definition": "bigint(20) unsigned DEFAULT '0' COMMENT '攻击流量'" + }, + { + "name": "countIPs", + "definition": "bigint(20) unsigned DEFAULT '0' COMMENT '独立IP数'" } ], "indexes": [